没有 jQuery UI 的 jQuery 可排序

Posted

技术标签:

【中文标题】没有 jQuery UI 的 jQuery 可排序【英文标题】:jQuery Sortable without jQuery UI 【发布时间】:2011-06-07 04:42:18 【问题描述】:

我需要“可排序拖放”功能,并且我正在使用 jQuery。我不能真正使用 jQuery UI,因为对于这个项目来说这将是一个开销(我需要添加许多 KB 的 JS 和 CSS 才能使用一小部分功能)。

有没有可以推荐的插件,或者我可以遵循的简单实现路径?

解决方案必须尽可能轻量级,最好基于 jQuery/Sizzle 或纯 javascript

【问题讨论】:

rubaxa.github.io/Sortable 2014 我认为会是更好的解决方案 【参考方案1】:

为后代:http://dragsort.codeplex.com/

一个演示:http://cleesh.org/example(在开发网站上找不到)。

缩小到 9KB。

【讨论】:

更正:9KB 拖动排序 + 82KB jQuery(依赖)= 91KB。加起来远远超过 9KB。请参阅 rubaxa.github.io/Sortable(12.7 KB,无 jQuery)。 @StefanSteiger 这个问题是关于 jQuery,而不是 UI。即使您正在尝试宣传您的网站,您也无法理解此评论。 演示链接 = 404【参考方案2】:

您可以在 jqueryui.com 上构建自己的 JQuery 下载,而无需所有 css/主题信息。您还可以去掉小部件和效果,只使用可拖放/可拖放。

总共大约 30KB。还是太大了?

【讨论】:

不幸的是,它是。对于所需的功能,它太多了:-( 最后不得不使用 jquery.ui - 其他插件还不够成熟,所以像在定位(相对/绝对/固定)父级中排序或对重样式元素进行排序这样的事情太麻烦了。不幸的是,这个项目的时间表不允许深入研究所有问题并重写这些其他插件。 我查看了其中的一些,例如this other answer 中列出的那些,并得出了相同的结论。 Esp 用于可放置(我需要的不仅仅是可排序的)以及诸如如果未正确放置则恢复到位置等内容的组合。【参考方案3】:

这是另一个给后代的:http://johnny.github.com/jquery-sortable/。

它唯一的依赖是 jQuery,有一个很好的功能集,并且缩小到 8kb。

【讨论】:

再次:jQuery + 8KB = ~90 KB。那是 != 8KB。 @StefanSteiger 再次:您在此评论的线程错误。【参考方案4】:

自从有人问这个问题以来已经有很多时间了,所以如果您正在考虑 jquery UI 的替代方案,这是一个非常好的且易于实现的 http://rubaxa.github.io/Sortable/

【讨论】:

【参考方案5】:

如果您确定不使用可以维护和更新的自定义、缩小和压缩版本的 jQueryUI...

...也许以下博客文章中的插件之一适合您:

“17 个用于轻松高效地重新排序和过滤页面元素的 jQuery 插件” http://www.tripwiremagazine.com/2010/03/17-jquery-plugins-for-easy-and-efficient-reordering-and-filtering-page-elements.html

博文中的示例:“List Reorder” (

【讨论】:

嘿!我自己没有找到这个列表。我现在正在尝试重写“ListReorder”以支持任何块行元素的“排序”。很快就会更新。 对于简单的排序,但是,如果您没有定位父元素或对排序元素进行重样式,则此列表重新排序非常好。 很高兴知道进一步的脚本... jQuery Mobile 在添加 jQueryUI 时疯狂增长... 顺便说一句,这就是我编辑列表重新排序插件的地方,虽然还没有完成:jsfiddle.net/gryzzly/L6Upf【参考方案6】:

如果您查看jQuery UI source,jquery.ui.sortable.js 是一个单独的文件,我相信它仅取决于jquery.ui.core.jsjquery.ui.widget.jsjquery.ui.mouse.js,尽管我还没有对此进行测试。但是,这仍然是 36KB 的缩小版。

【讨论】:

【参考方案7】:

你可以试试我的 (http://jsfiddle.net/606bs750/16/)。 您可以拖动和排序无限数量的块。

块将约束到父级。

<div id="parent" class="parent">
    <button id="button1" class="button">Drag me 1</button>
    <button id="button2" class="button">Drag me 2</button>
    <button id="button3" class="button">Drag me 3</button>
    <button id="button4" class="button">Drag me 4</button>
</div>

JQuery(仅限):

$(function() 
    $('.button').mousedown(function(e) 
        if(e.which===1) 
            var button = $(this);
            var button_id = button.attr('id');
            var parent_height = button.parent().innerHeight();
            var top = parseInt(button.css('top'));
            var original_ypos = button.position().top; //original ypos
            var drag_min_ypos = 0-original_ypos;
            var drag_max_ypos = parent_height-original_ypos-button.outerHeight();
            var drag_start_ypos = e.clientY;
            var my_ypos = original_ypos;
            //Set current order for all
            $('.button').each(function(i)  $(this).attr('data-order',(i+1)); );
            var prev_button = button.prev('.button'); var next_button = button.next('.button');
            var prev_button_ypos = prev_button.length>0 ? prev_button.position().top : '';
            var next_button_ypos = next_button.length>0 ? next_button.position().top : '';
            $('#log1').text('mousedown '+button_id+' original_ypos: '+original_ypos);
            $('#log2').text('');
            $('#log3').text('');
            $(window).on('mousemove',function(e) 
                //Move and constrain
                button.addClass('drag');
                var direction = my_ypos>button.position().top ? 'up' : 'down';
                var new_top = top+(e.clientY-drag_start_ypos);
                my_ypos = button.position().top;
                button.css(top:new_top+'px');
                if(new_top<drag_min_ypos)  button.css(top:drag_min_ypos+'px'); 
                if(new_top>drag_max_ypos)  button.css(top:drag_max_ypos+'px'); 
                $('#log2').text('mousemove new_top: '+new_top+', my_ypos: '+my_ypos+', direction: '+direction);
                //$('#log3').text('');
                //Check position over others
                if(direction=='down'&&next_button_ypos!='') 
                    if(my_ypos>next_button_ypos)  //crossed next button
                        $('#log3').text('dragged after '+next_button_ypos+' ('+next_button.attr('id')+')');
                        next_button.css(top:(parseInt(next_button.css('top'))-next_button.outerHeight(true))+'px'); //up once
                        var tmp_order = next_button.attr('data-order');
                        next_button.attr('data-order',button.attr('data-order')); //switch order
                        button.attr('data-order',tmp_order);
                        prev_button = next_button; next_button = next_button.nextAll('.button:not(.drag)').first();
                        prev_button_ypos = prev_button.length>0 ? prev_button.position().top : '';
                        next_button_ypos = next_button.length>0 ? next_button.position().top : '';
                    
                 else if(direction=='up'&&prev_button_ypos!='') 
                    if(my_ypos<prev_button_ypos)  //crossed prev button
                        $('#log3').text('dragged before '+prev_button_ypos+', '+prev_button.attr('id'));
                        prev_button.css(top:(parseInt(prev_button.css('top'))+prev_button.outerHeight(true))+'px'); //down once
                        var tmp_order = prev_button.attr('data-order');
                        prev_button.attr('data-order',button.attr('data-order')); //switch order
                        button.attr('data-order',tmp_order);
                        next_button = prev_button; prev_button = prev_button.prevAll('.button:not(.drag)').first();
                        prev_button_ypos = prev_button.length>0 ? prev_button.position().top : '';
                        next_button_ypos = next_button.length>0 ? next_button.position().top : '';
                    
                
                $('#log4').text('prev_button_ypos: '+prev_button_ypos+' ('+prev_button.attr('id')+'), next_button_ypos: '+next_button_ypos+' ('+next_button.attr('id')+')');
            );
            $(window).on('mouseup',function(e) 
                 if(e.which===1) 
                    $('.button').removeClass('drag');
                    $(window).off('mouseup mousemove');
                    //Reorder and reposition all
                    $('.button').each(function() 
                        var this_order = parseInt($(this).attr('data-order'));
                        var prev_order = $(this).siblings('.button[data-order="'+(this_order-1)+'"]');
                        if(prev_order.length>0)  $(this).insertAfter(prev_order); 
                    );
                    $('.button').css('top','0'); $('.button').removeAttr('data-order'); //reset
                    $('#log1').text('mouseup');
                    $('#log2').text('');
                    $('#log3').text('');
                    $('#log4').text('');
                 
            );
        
    );
);

【讨论】:

嗨,Jason,我认为如果您在“mousedown”、“mousemove”和“mouseup”旁边添加“touchstart”、“touchmove”和“touchend”,那么它应该可以工作。触摸位置可能使用 e.clientX 和 e.clientY 以外的其他变量,因此如果这些变量不能立即工作,您可能需要在 *** 上搜索这些变量。测试是让它在触摸上工作的关键。您可能必须更改 $('.button').mousedown(funciton(e) 才能在处理程序 $('.button').on('mousedown touchstart', function(e) 上使用 jquery。您可能还需要jquery.ui 或 jquery.mobile 来支持我提到的那些触摸事件。【参考方案8】:

这里有一个http://plugins.jquery.com/project/NestedSortable 它不使用 UI,只有 5kb(尽管如果需要,你可以破解任何额外的功能来降低它)

希望对你有帮助

安德鲁

【讨论】:

那一个依赖于interface.eyecon.ro,它本身就超过100k :(【参考方案9】:

如果您不想要任何多余的装饰,那么我发现这个是最好的: http://jsfiddle.net/erikdana/Nkykq/3/高达 http://jsfiddle.net/erikdana/Nkykq/6/

非常轻巧,切中要害。

js

$('#box').bind(
    mousedown: function() 
        $(document).mousemove(function(e) 
            $('#box').css(
                top: e.pageY - 10,
                left: e.pageX - 20
            );
        );
    ,
    mouseup: function() 
        $(document).unbind(mousedown);
        var box = $('#box').css('top');
        if (box > '100') 
            $('#box').css(width: '100px');
        ;
    
);

css

div width:50px;height:50px;background:blue;position:absolute; cursor:move;
div:focus  cursor:move;

【讨论】:

这是一个用于可拖动功能的简洁脚本,但问题是关于可排序,这不仅仅是移动项目。【参考方案10】:

我建议您选择“LMDD 拖放” gzip 压缩后不到 4kb,实现起来非常简单。 https://supraniti.github.io/Lean-Mean-Drag-and-Drop/ 简单例子:

div id="basic-example"> (scope)
    <div class="grid"> (container)
        <div class="item"></div> (draggable)
    </div>
</div>
<script>
    lmdd.set(document.getElementById('basic-example'), 
        containerClass: 'grid',
        draggableItemClass: 'item'
);
</script>

【讨论】:

也可以排序吗? 是的。您可以对赞美诗元素进行排序和重新排序

以上是关于没有 jQuery UI 的 jQuery 可排序的主要内容,如果未能解决你的问题,请参考以下文章

jQuery UI 可排序和可选

Jquery可排序“更改”事件元素位置

jQuery UI 可排序:确定项目的顺序

jquery ui可排序占位符无法更改背景颜色

React 导入 Jquery-Ui 可排序

jQuery.repeater 不适用于可排序的 jQuery Ui