Moving a div to the top on click (virtual desktop)

旧巷老猫 提交于 2019-12-13 08:11:31

问题


I have an application that works like a virtual desktop (icons in a horizontal bar in the bottom). When you click on an icon, a window opens (dynamically created). If you click on another (or the same) icon another window opens 10px down and 10px to the right from the last one, and is moved on the top.

What I need to accomplish is that if you click on a window that is moved beneath another window, the clicked window gets moved to the top.

Below is what I got so far, but it isn't at all a good solution (eg. if you click on a window that's already on the top, the functions runs anyway and z-index on the window counts up). What would be a more elegant solution for this? Thanks in advance!

Windows.prototype.moveOnTop = function(){

var boxes = $('.window');

    boxes.click(function() {
        var thisWindow = $(this);
        Windows.prototype.getZindex(thisWindow);
    });
}

Windows.prototype.getZindex = function(thisWindow){

    var boxes = $('.window');
    var maxZindex = 0;

    boxes.each(function() {
        var zIndex = parseInt($(this).css('z-index'), 10);
        maxZindex = Math.max(maxZindex, zIndex);
    });

    thisWindow.css("z-index", maxZindex + 1);
}

回答1:


One way is not to give z-index to any of your .window divs and use DOM node positioning instead. i.e. you shift the clicked div to the topmost postion in the DOM, i.e. as the last child of body

i.e. something like:

Windows.prototype.moveOnTop = function(){

    $('.window').click(function() {
        var thisWindow = $(this);
        if(thisWindow.next().length > 0) thisWindow.appendTo('body');
    });

};

But you need to make sure that z-index is not specified for any of your .window divs.




回答2:


A more elegant solution would involve a structure (an array basically) holding references to all created windows. The structure would reflect the z-index of the windows, e.g. the bottom window would be in allWindows[0] and the top window would in allWindows[n-1] (where n is the number of windows).

As soon as a window (let's say it's at index [3]) receives focus (is clicked), you first update this structure:

  1. Move allWindows[n-1] (current top window) to a temporary holding location
  2. Move allWindows[3] to allWindows[n-1] (it's now the top window)
  3. Move each window between indices [3] and [n-1] (exclusive) one position down
  4. Place the window in the temporary holding location to allWindows[n-2] (one below the top)

Nothing visible has changed so far, just the structure has changed: it's now in the right order that the windows should be visible.

  1. Loop through allWindows[3]' toallWindows[n-1]` (inclusive) and set the z-index equal to the index in the structure

This way the z-index will never be more than n-1. Of course, you only do this if the window that is receiving focus (that is clicked) is not the top window already, so as not to waste.

I see that you are using jQuery. With a jQuery plugin pattern you can store this structure inside the plugin and you will be able to use it inside the click handlers.




回答3:


You could have some manager class look at the current windows, and swap indexes instead of counting up. This is a more elegant way of doing it.

Otherwise you might want to create an algorithm that holds the current indexes. So you'd bring one pane to the top, while lowering others.

It should be possible to find a layer on its z-index. So this shouldn't be so hard.




回答4:


Since you're calling Windows.prototype.moveOnTop every time a new window is added, the click handlers will stack for previously created windows. E.g. after creating n windows, the first window will have n handlers, the second will have n-1, et cetera.

Since getZindex looks fine to me, it may well be that this is the source of your problem. Or not, but it is something you'll want to fix anyway. And fixing it is easy:

$(document).on('click', '.window', function() {
    var thisWindow = $(this);
    Windows.prototype.getZindex(thisWindow);
});

This way, the window doesn't have to exist yet when you initialize your app. It's called event delegation, and it means the event will bubble up to the document, which will look if the clicked element matches the selector ('.window') and call the handler if it does.

As remarked before by Robert, your function names are a bit strange. You haven't shown us the rest of Windows, but it's clearly not tied to the DOM. Based on that guesswork, I think this might be more fitting:

  1. Remove Windows.prototype.moveOnTop.

  2. Rename getZindex to a more accurately descriptive name, e.g.:

    Windows.prototype.moveToTop = function(thisWindow){
        var boxes = $('.window');
        var maxZindex = 0;
    
        boxes.each(function() {
            var zIndex = parseInt($(this).css('z-index'), 10);
            maxZindex = Math.max(maxZindex, zIndex);
        });
    
        thisWindow.css("z-index", maxZindex + 1);
    }
    
  3. Wherever you initialize your app, add the following:

    var container = '#appContainer'; // <-- the container the app is rendered into
    
    $(container).on('click', '.window', function() {
        var thisWindow = $(this);
        Windows.prototype.moveToTop(thisWindow);
    });
    

Let us know if this solves your problem.



来源:https://stackoverflow.com/questions/8778298/moving-a-div-to-the-top-on-click-virtual-desktop

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!