【问题标题】:Plugin for jQuery Text-editor style selection?用于 jQuery 文本编辑器样式选择的插件?
【发布时间】:2011-01-21 14:44:58
【问题描述】:

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

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

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

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

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

【问题讨论】:

    标签: jquery jquery-ui select text-editor jquery-ui-selectable


    【解决方案1】:

    也许这可以通过某种方式进行优化,但我只在 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});
    });
    

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


    更新 - Example 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});
    });
    

    同样,也许这段代码可以通过某种方式优化性能。

    【讨论】:

    • 感谢您花时间写这篇文章!我会试一试。但是,我已经尝试自己编写类似这样的内容,并且我的应用程序需要非常高效,正如我在问题的“P/S”部分中添加的那样。无论哪种方式,我都会在这里发布有关进展情况的新闻。
    【解决方案2】:

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

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

    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()
    

    Give it a try,代码是also availabe

    【讨论】:

    • 我知道这已经很长时间了,但我终于有机会玩弄你的代码了。我已经将它修改为更接近我预期的应用程序,并且效果很好,除了它在 IE8 上的性能很糟糕。也许您可以帮助解释为什么它在 IE 上的表现如此糟糕?代码在suanpublic.xtreemhost.com/so/selectable点击“添加更多项目”5-6次,快速跨多行选择。然后注意IE和其他浏览器的区别。
    • 我在 IE 中发现了很大的性能瓶颈——看起来 .live() 在页面加载后添加的元素上非常慢。我现在正在使用简单的 .bind() ,这使它变得更好,尽管它仍然明显比 FF 慢。除此之外,您的代码帮助很大,我从中学到了很多。谢谢!
    【解决方案3】:

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

    首先,为“stop:”接口事件(可能像序列化http://jqueryui.com/demos/selectable/#serialize

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-06
      相关资源
      最近更新 更多