【问题标题】:how to trigger JQuery .draggable() on elements created by templates?如何在模板创建的元素上触发 JQuery .draggable()?
【发布时间】:2012-05-14 06:16:32
【问题描述】:

我在 Html 文件中有一个标准模板,例如:

<template name="cards">
  {{#each all_cards}}
    {{> card_item}}
  {{/each}}
</template>
<template name="card_item">
  <div class="card" style="left:{{position.x}}px; top:{{position.y}}px">
    {{title}}
  </div>
</template>

我想让卡片(css 选择器.card)可以用 JQuery 拖动。 现在,由于 Meteor 使用模板自动更新 DOM,我何时以及如何知道在何处调用 .draggable() ??

编辑:到目前为止,这是我的解决方案,它通过摆动动画(使用 CSS3)使其他客户端上的待处理动作可见:

Template.card_item.events = {
'mouseover .card': function (e) {
    var $target = $(e.target);
    var $cardContainer = $target.hasClass('card') ? $target : $target.parents('.card');     
    $cardContainer.draggable({containment: "parent", distance: 3});
},
'dragstart .card': function (e) {
    Session.set("dragging_id", e.target.id);
    $(e.target).addClass("drag");
    pos = $(e.target).position();
    Events.insert({type: "dragstart", id:e.target.id, left: pos.left, top: pos.top});       
},
'dragstop .card': function (e) {
    pos = $(e.target).position();
    Events.insert({type: "dragstop", id:e.target.id, left: pos.left, top: pos.top});        
    Cards.update(e.target.id, {$set: {left:pos.left, top:pos.top}});
    Session.set("dragging_id", null);
}
}

Events.find().observe({
added: function(event) {
    if (event.type == "dragstart" && !Session.equals("dragging_id", event.id)) {
        $("#"+event.id).draggable({disabled: true});
        $("#"+event.id).addClass("wobble");             
    }
    if (event.type == "dragstop" && !Session.equals("dragging_id", event.id)) {
        $("#"+event.id).animate({left: event.left, top: event.top}, 250);           
        Events.remove({id:this.id});  
        $("#"+event.id).draggable({disabled: false});
    }
}
});

【问题讨论】:

  • 使用Meteor.defer,它不在文档中,但这个问题解释了它。我目前正在使用它来制作可排序的列表,并且效果很好。 stackoverflow.com/questions/10109788/…
  • 谢谢,我去看看! - 很酷,这很有效!
  • 干杯,不客气。另外,我刚刚了解到meteor.defer 只是setTimeout 的一个包装器,在控制台中输入Meteor.defer,不带任何参数来理解我的意思。
  • 我查了一下,很有趣....
  • 好的,看更新,Meteor.defer 不应该在这种情况下使用..

标签: meteor


【解决方案1】:

编辑:这种方法似乎不适用于最新版本的 Meteor,例如v0.5.0。请参阅下面的comment

看起来我们正在做类似的事情!我有a working proof of concept for a simple Magic: The Gathering app。以下是我目前实现拖动的方式:

在您的一个 html 文件的 &lt;head&gt; 部分中,包含 jQuery UI 脚本:

<script src="jquery-ui-1.8.20.custom.min.js"></script>

然后,在一个 js 文件中,确保元素在鼠标悬停时变得可拖动(注意:这在触摸屏上不是最理想的,因为它需要两次触摸才能拖动......我正在寻找更好的触摸屏解决方案):

Template.card_item.events['mouseover .card, touchstart .card'] = function (e) {
    var $target = $(e.target);
    if (!$target.data('isDraggable')) {
      $target.data('isDraggable', true).draggable();
    }
};

最后,处理drag and dragstop events

var prevDraggedTime = 0

Template.card_item.events['drag .card'] = function (e) {
    // get the cardId from e
    var now = new Date().getTime();
    var position;

    if (now - prevDraggedTime > 250) {
        position = $(e.target).position();
        Cards.update(cardId, {$set: {x: position.top, y: position.left}});
        prevDraggedTime = now;
    }
}

Template.card_item.events['dragstop .card'] = function (e) {
    // get the cardId from e
    var position = $(e.target).position();
    Cards.update(cardId, {$set: {x: position.top, y: position.left}});
}

【讨论】:

  • 我认为更新“拖动”不是一个好主意。即使是很小的阻力,也可能需要数百次更新。只需更新 dragend 并使用 css3 转换即可在其他客户端上顺利移动。
  • 是的,这只是为了演示这个概念。在我的实际代码中,我在dragstop 上更新位置,然后在drag 上每250 毫秒更新一次。
  • 酷,这更有意义。不过,我认为在您的回答中也值得多说。
  • 谢谢,在您的帮助下,我使用您的设置排除了延迟功能。
  • @Emmett 我很高兴,现在是 +1 答案:)
猜你喜欢
  • 1970-01-01
  • 2010-12-16
  • 1970-01-01
  • 2018-05-21
  • 1970-01-01
  • 2014-05-01
  • 1970-01-01
  • 2011-09-11
  • 1970-01-01
相关资源
最近更新 更多