创建Windows 8 Explorer模拟 - 鼠标选择问题

时间:2014-07-14 15:26:22

标签: javascript jquery selection mousemove

作为一个小练习我决定重新创建Windows 8资源管理器文件列表面板,一切顺利,直到我想添加鼠标选择。它基本上是一个功能,允许您通过在窗口上拖动鼠标来选择多个文件,绘制一个正方形,它应该选择属于它的所有“文件”。

我遇到的唯一问题是我似乎找不到将selected类添加到选择下的元素的方法

以下是相关代码:working fiddle中提供的完整代码)

<ul class="files">
    <li>
        <span class="icon folder"></span>
        <span class="name">Folder</span>
    </li>
</ul>

.selection {
    position: absolute;
    border: 1px solid #39F;
    background-color: rgba(51,153,255,.4);
    display: none;
}

$(function(){
    var $body = $(document.body);
    var selecting = false,
        $selectionDiv = $(document.createElement('div')).addClass('selection').appendTo($body),
        startX, startY;
    $body.on({
        mousedown: function(e){
            if (e.target === document.body){
                e.stopPropagation();

                startX = e.clientX;
                startY = e.clientY;
                selecting = true;

                $selectionDiv.show().css({top:startY+'px',left:startX+'px',width:'0px',height:'0px'});
            }
        },
        mousemove: function(e){
            if (selecting){
                var currentX = e.clientX,
                    currentY = e.clientY;

                var subX = currentX - startX,
                    subY = currentY - startY;

                if (subX < 0){
                    subX *= -1;
                    $selectionDiv.css('left',startX+(currentX-startX));
                }
                else $selectionDiv.css('left',startX+'px');

                if (subY < 0){
                    subY *= -1;
                    $selectionDiv.css('top',startY+(currentY-startY));
                }
                else $selectionDiv.css('top',startY+'px');

                $selectionDiv.css({
                    width: subX,
                    height: subY,
                });
            }
        }
    }).on('mouseup blur mouseleave',function(){
        if (selecting){
            $selectionDiv.hide();
            selecting = false;
        }
    });
});

1 个答案:

答案 0 :(得分:4)

如果我理解正确,您需要确定选择框中包含哪些元素。这里的代码似乎可以完成这项工作(它应该进入你的mousemove事件处理程序):

var topLeftX = Math.min(startX, currentX),
    topLeftY = Math.min(startY, currentY),
    bottomRightX = Math.max(startX, currentX),
    bottomRightY = Math.max(startY, currentY);

$('.files li').each(function() {
    var offset = $(this).offset(),
        width = $(this).outerWidth(),
        height = $(this).outerHeight();

    if (offset.left < bottomRightX
            && offset.left + width > topLeftX
            && offset.top < bottomRightY
            && offset.top + height > topLeftY) {
        $(this).addClass('selected');
    }
    else {
        $(this).removeClass('selected');
    }
});

此代码遍历文件列表的所有元素,并为选择框和列表元素运行矩形重叠测试(我从this answer得到的算法)。 outerWidth()outerHeight()的使用可确保边界也得到考虑。

我还注意到,当你释放鼠标时,会调用重置选择的处理程序:

$(window).click(function(){
    $('.files li').removeClass('selected');
})

作为一种可能的解决方案,您可以将其移至mousedown处理程序。

这里的JSFIddle在Chrome 35中适用于我:http://jsfiddle.net/5Hzm4/2/