如何在模板创建的元素上触发 JQuery .draggable()? [英] how to trigger JQuery .draggable() on elements created by templates?
问题描述
我在 Html 文件中有一个标准模板,例如:
{{#each all_cards}}{{>card_item}}{{/每个}}模板><模板名称="card_item"><div class="card" style="left:{{position.x}}px; top:{{position.y}}px">{{标题}}
模板>
我想让卡片(css 选择器 .card)可以通过 JQuery 拖动.现在,由于 Meteor 使用模板自动更新 DOM,我何时以及如何知道在什么地方调用 .draggable() ?
到目前为止,这是我的解决方案,它通过摆动动画(使用 CSS3)使其他客户端上的待处理运动可见:
Template.card_item.events = {'mouseover .card':功能(e){var $target = $(e.target);var $cardContainer = $target.hasClass('card') ?$target : $target.parents('.card');$cardContainer.draggable({containment: "parent", distance: 3});},'dragstart .card': 函数 (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':功能(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({添加:功能(事件){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,例如v0.5.0.请参阅下面我的评论.
看起来我们正在做类似的事情!我有 一个简单的 Magic: The Gathering 应用程序概念的工作证明.这是我目前实现拖动的方式:
在您的一个 html 文件的 部分中,包含 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
和 dragstop代码>事件
:
var prevDraggedTime = 0Template.card_item.events['drag .card'] = function (e) {//从 e 中获取 cardIdvar now = new Date().getTime();变量位置;如果(现在 - prevDraggedTime > 250){位置 = $(e.target).position();Cards.update(cardId, {$set: {x: position.top, y: position.left}});prevDraggedTime = 现在;}}Template.card_item.events['dragstop .card'] = function (e) {//从 e 中获取 cardIdvar position = $(e.target).position();Cards.update(cardId, {$set: {x: position.top, y: position.left}});}
I have a standard template in an Html file like:
<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>
I want to have the cards (css selector .card) become draggable with JQuery. Now since Meteor automagically updates the DOM using the template, when and how do I know where to call .draggable() on what??
EDIT: This is so far my solution which makes pending movements on other client visible with a wobble animation (using 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});
}
}
});
EDIT: This approach doesn't seem to work in the latest versions of Meteor, e.g. v0.5.0. See my comment below.
Looks like we're working on similar things! I've got a working proof of concept for a simple Magic: The Gathering app. Here's how I have dragging implemented at the moment:
In a <head>
section in one of your html files, include the jQuery UI script:
<script src="jquery-ui-1.8.20.custom.min.js"></script>
Then, in a js file, make sure elements become draggable on mouseover (note: this is sub-optimal on touchscreens since it requires two touches to drag... I'm looking for a better touchscreen solution):
Template.card_item.events['mouseover .card, touchstart .card'] = function (e) {
var $target = $(e.target);
if (!$target.data('isDraggable')) {
$target.data('isDraggable', true).draggable();
}
};
And finally, handle the 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}});
}
这篇关于如何在模板创建的元素上触发 JQuery .draggable()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!