作为一个小练习,我决定重新创建Windows 8 Explorer文件列表面板,并且一切顺利,直到我想添加鼠标选择。基本上,该功能是通过沿窗口拖动鼠标并绘制一个正方形来选择多个文件的功能,该正方形应选择位于其下方的所有“文件”。

我唯一的问题是我似乎找不到找到将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;
        }
    });
});

最佳答案

如果我对您的理解正确,则需要确定选择框中包含哪些元素。这是似乎可以完成工作的代码(应该放在您的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处理程序中。

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

10-05 21:02
查看更多