3

我想要实现的是使用 jQuery 来模仿您在典型文本编辑器中看到的文本选择功能的行为,除了选择文本之外,我想选择多行<div>s。然而,到目前为止,我为 jQuery 找到的唯一“选择”插件基于矩形套索模型运行。特别是,我正在使用 jQueryUI 可选插件。要了解我在说什么,请考虑以下 2 个图像:

默认的 jQueryUI“可选”插件行为

理想的插件行为(无套索) http://img709.imageshack.us/img709/5664/selectableidealthumb.png

你也可以去这里玩这个确切的例子。有人知道实现这一目标的插件吗?这将使我免于继续破解或破解此插件以获得我想要的东西......

P/S:在我的应用程序中,每行最多包含 150 个左右的 div,每个 div 中都会有几个 div。我尝试过手动滚动我自己的可选择项,但即使只处理一行也很慢。我目前正在使用这个插件,因为它的性能比我写的要好得多。

4

3 回答 3

2

也许这可以通过某种方式进行优化,但我只在 Chrome 中对其进行了测试,但我认为它也可以在其他浏览器中使用。不需要 jQuery UI,它是手工制作的 ;)

$(function() {
    var selectableLi = $('#selectable li');
    selectableLi.mousedown(function(){
        var startIndex, endIndex, mouseUpOnLi = false;

        // When dragging starts, remove classes active and hover
        selectableLi.removeClass('active hover');

        // Give the element where dragging starts a class
        $(this).addClass('active');

        // Save the start index
        startIndex = $(this).index();

        // Bind mouse up event 
        selectableLi.bind('mouseup', function(){

            // Mouse up is on a li-element
            mouseUpOnLi = true;
            $(this).addClass('active');

            // Remove the events for mouseup, mouseover and mouseout
            selectableLi.unbind('mouseup mouseover mouseout');

            // Store the end index
            endIndex = $(this).index();

            // Swap values if endIndex < startindex
            if(endIndex < startIndex){
                var tmp = startIndex;
                startIndex = endIndex;
                endIndex = tmp;                 
            }

            // Give the selected elements a colour
            for(i=startIndex; i<=endIndex; i++){
                $(selectableLi[i]).addClass('active');
            }

        }).bind('mouseover', function(){
            // Give elements a hover class when hovering
            $(this).addClass('hover');
        }).bind('mouseout', function(){
            // Remove the hover class when mouse moves out the li
            $(this).removeClass('hover');
        });

        $(document).bind('mouseup', function(e){
            // When mouse up is outside a li-element
            if(!mouseUpOnLi){
                selectableLi.removeClass('active');
            }
            $(this).unbind('mouseup');
        });
    }).attr("unselectable","on").css("MozUserSelect","none").bind("selectstart",function(){return false});
});

我在网上有一个例子。请注意,选择时项目没有背景颜色;我认为这将提供更好的性能。


更新 -示例 2

我更新了它,以便在选择时可以看到选择:

var selectableLi;

function colourSelected(a, b, Class){
    selectableLi.removeClass(Class);
    // Swap values if a > b
    if(a > b){
        var tmp = a;
        a = b;
        b = tmp;                    
    }

    // Give the selected elements a colour
    for(i=a; i<=b; i++){
        $(selectableLi[i]).addClass(Class);
    }       
}

$(function() {
    selectableLi = $('#selectable li');
    selectableLi.mousedown(function(){
        var startIndex, endIndex, mouseUpOnLi = false;

        // When dragging starts, remove classes active and hover
        selectableLi.removeClass('active hover');

        // Give the element where dragging starts a class
        $(this).addClass('active');

        // Save the start index
        startIndex = $(this).index();

        // Bind mouse up event 
        selectableLi.bind('mouseup', function(){

            // Mouse up is on a li-element
            mouseUpOnLi = true;
            $(this).addClass('active');

            // Remove the events for mouseup, mouseover and mouseout
            selectableLi.unbind('mouseup mouseover mouseout');

            colourSelected(startIndex, $(this).index(), 'active');

        }).bind('mouseover mouseout', function(){
            // Give elements a hover class when hovering
            colourSelected(startIndex, $(this).index(), 'hover');
        });

        $(document).bind('mouseup', function(e){
            // When mouse up is outside a li-element
            if(!mouseUpOnLi){
                selectableLi.removeClass('active hover');
            }
            $(this).unbind('mouseup');
            selectableLi.unbind('mouseover mouseout');
        });
    }).attr("unselectable","on").css("MozUserSelect","none").bind("selectstart",function(){return false});
});

同样,也许可以以某种方式优化此代码以提高性能。

于 2010-02-26T21:41:28.103 回答
0

也许您已经为此获得了自己的脚本,但我对我的脚本进行了优化和改进。它仅在需要时添加或删除类,这对性能很有帮助。

它还提供了一些可能有用的方法:

var sR = $('#selectable').selectableRange({
    /* Alternatively, you could overwrite default options
    classname: 'active',
    log: false,
    logElement: $('#log'),
    nodename: 'LI'*/
});

// Initialize the selectable so it works
sR.init();

// You can always change options like this:
$('#logOnOff').click(function(){
    // Toggle log
    sR.options.log = (sR.options.log) ? false : true;
});

// Also you can use this methods:
// sR.deselect()
// sR.destroy()
// sR.getSelectedItems()

试试看,代码也是可用的。

于 2010-02-27T14:45:52.687 回答
0

我会使用 jQuery 功能制作我自己的版本。

首先,接口事件“停止:”(也许像序列化http://jqueryui.com/demos/selectable/#serialize

然后看看我得到了哪个 ID,最低和最高的 ID 足以让我在剩余的对象中进行简单的“for...next”循环。

我知道它是一个修复/破解解决方案,但从我的角度来看,这似乎解决了问题,它对你有用还是你也需要代码?只是想先提供算法思想。:o)

于 2010-05-31T23:31:51.580 回答