【问题标题】:How to make all div draggable with in a parent container如何在父容器中使所有 div 可拖动
【发布时间】:2012-10-12 08:08:51
【问题描述】:

有一个div id parentDiv,在parentDiv divl 中有一些类block1 的div

喜欢

<div id="btn"><input name="click" type="button" value="Click" class='button" /></div>

<div id="parentDiv">
    <div class="block1" style=" width:100px; height:100px; background:orange;">I am Block1</div>
    <div class="block1" style=" width:100px; height:100px; background:orange;">I am Block1</div>
</div>

在 JQuery 中,类为 block1 的 div 是可拖动的。

$(function(){
    $('.block1').draggable({
        drag: function() {
           $('.block1').text('Drag Now!');
        },
        stop: function() {
           $('.block1').text('Stop Now!');
        }
    });
});

这些 div 作为方面工作,但问题是,如果通过单击 btn 输入将任何带有 block1 的新 div 附加到 parentDiv

$('#btn').on('click', 'input.button', function(){
    var $newDiv=$('<div class="block1" style=" width:100px; height:100px; background:green;">I am Block1</div>');
});

这是不可拖动的。

是的,它不起作用,因为它不在 DOM 中。

我们能够在#btn div 上为其子input.button 定义一个click 事件,如果我们在这个#btn div 中添加带有类按钮的新输入,所有这些都将作为方面工作。

所以我的问题是,有没有办法让父容器parentDiv 中的所有 div 都可以拖动,就像我们可以使用#btn div 一样?

【问题讨论】:

    标签: jquery-ui draggable jquery


    【解决方案1】:

    您可以使用jQuery on methodmouseover 事件来绑定未初始化的可拖动子项:

    $(".parentDiv").on("mouseover", ".block1", function() {
    
        // Use the UI pseudo-selector to check that
        // it is not already draggable
        if(!$(this).is(":ui-draggable"))
            $(this).draggable({
                /* Options */
            });
    });
    

    为方便起见,包装在一个扩展 jQuery 的函数中:

    $.fn.extend({
    
        /**
         * Children of the element with the given selector
         * will automatically be made draggable
         * @param {String} selector
         *  The selector of the child / descendant elements
         *  to automatically be made draggable
         * @param {Object} opts
         *  The options that would normally be passed to the
         *  draggable method
         * @returns
         *  The jQuery array for chaining
         */
        draggableChildren: function(selector, opts) {
    
            // On using event delegation to automatically
            // handle new child events
            $(this).on("mouseover", selector, function() {
    
               // Check that draggable not already initialized
               if(!$(this).is(":ui-draggable"))
    
                   // Initialize draggable
                   $(this).draggable(opts);
            });
    
            // Return this for chaining
            return this;
        }
    });
    

    您可以按如下方式使用它:

    $(".parentDiv").draggableChildren(".block1", {
        drag: function() {
            $(this).text('Drag Now!');
        },
        stop: function() {
            $(this).text('Stop Now!');
        }
    });
    

    Here is a fiddle showing it in action

    【讨论】:

    • 非常感谢!如果可以的话+100。我还制作了一个 .resizable 版本。这种技术使我能够将 260 个 div 的 .draggable 和 .resizable 创建时间从 2600 ms 减少到 20 ms,因为 .d 和 .r 现在仅在需要时才初始化。最好的是:每次页面加载只需执行一次。
    【解决方案2】:

    你需要使用jquery的“live”功能在future元素上添加事件和函数。

    此代码是从另一篇文章中借用的 (http://stackoverflow.com/questions/1805210/jquery-drag-and-drop-using-live-events)

    (function ($) {
       $.fn.liveDraggable = function (opts) {
          this.live("mouseover", function() {
             if (!$(this).data("init")) {
                $(this).data("init", true).draggable(opts);
             }
          });
          return $();
       };
    }(jQuery));
    

    现在不要这样称呼它:

    $(selector).draggable({opts});
    

    ...只需使用:

    $(selector).liveDraggable({opts})
    

    【讨论】:

    • 是的,它正在工作。但正如 jquery doc 所说,不推荐使用 live() 方法。我们如何使用它来使用 live。
    【解决方案3】:

    您需要将containment 属性设置为 parent 以限制区域。

    $("#yourItem" ).draggable({ containment: "parent" });
    

    要为新的动态项目启用可拖动,您可以做的是,将绑定可拖动功能的代码移动到一个方法,并在将新项目添加到 DOM 后调用该方法

     function BindDraggable()
     {
        $('.block1').draggable({
            drag: function() {
               $('.block1').text('Drag Now!');
            },
            stop: function() {
               $('.block1').text('Stop Now!');
            },
            containment: 'parent'
        });
     }
    

    现在在文档准备好并添加新内容后立即调用它

    $(function(){
      BindDraggable();
    
      $('#btn').on('click', 'input#button', function(){
        var $newDiv=$('<div class="block1" style=" width:100px; height:100px; background:green;">I am Block1</div>');
        //to do :attach the new item to the DOM
    
        BindDraggable();
    });
    

    });

    【讨论】:

    • 是的,目前我正在使用你描述的,但是有没有办法只调用这个 BindDraggable() 一次,并且它适用于新的一次。
    【解决方案4】:
    $('#maindiv div").draggable({container:"#maindiv",scroll:false}) 
    

    现在你可以为所欲为

    【讨论】:

    • 据我所知,可拖动对象中没有container 选项。你的意思是containment..?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 2015-01-26
    • 1970-01-01
    • 2013-01-25
    • 1970-01-01
    • 2016-06-19
    相关资源
    最近更新 更多