将jQuery事件应用于所有类元素?

14
我有以下代码,可以让在iOS上运行的用户移动带有类别.drag<div> 在网页上。当只有一个.drag时它可以正常工作,但是如果有两个实例,它就无法工作了。是否可能让代码找到所有的<div>,然后使它们可拖动?
var drag = $(".drag")[0];
    xPos = drag.offsetWidth / 2;
    yPos = drag.offsetHeight / 2;
    drag.addEventListener("touchmove", function() {
        event.preventDefault();
        $(this).css({
        'left' : event.targetTouches[0].pageX - xPos + 'px', 
        'top' : event.targetTouches[0].pageY - yPos + 'px'
    });
});
4个回答

17
当您使用$(selector)[0]时,您会获得与选择器匹配的第一个DOM元素。取而代之地,使用.each()将事件侦听器添加到所有匹配选择器的元素中:
$(".drag").each(function () {
    var drag = this;
    xPos = drag.offsetWidth / 2;
    yPos = drag.offsetHeight / 2;
    drag.addEventListener("touchmove", function() {
        event.preventDefault();
        $(this).css({
          'left' : event.targetTouches[0].pageX - xPos + 'px', 
          'top' : event.targetTouches[0].pageY - yPos + 'px'
        });
    });
});​

3
将jQuery和JavaScript混合使用不是一个好习惯。你应该使用 var drag = $(this) 代替 var drag = this - brienna

1

是的,这是可能的。但是您正在使用 jQuery 选择器(可以选择并返回多个元素),然后立即取消包装以返回第一个元素。您可以修改代码,始终使用 jQuery 函数并避免此问题。

// an array of all elements with class "drag"
// each element is wrapped
var drag = $(".drag");

// selects all matching elements, but then references
// the first raw DOM element in the array
var drag = $(".drag")[0]; 

另一种看待它的方式:

var matches = $(".drag");

// each() executes a function for each matched element
matches.each(function () {
    var drag = this; // raw dom element

    // or, wrap to get jQuery object
    // var drag = $(this);
});​

正如我所提到的,您还可以在代码中使用jQuery函数。 我看到的两个快速示例是x / y坐标计算和事件绑定。


当我这样做时,我收到以下错误:TypeError:'undefined'不是函数(评估'drag.addEventListener')。您可以在此处查看实时示例:http://codekraken.com/testing/drag/test.html(必须在 iOS 上运行才能正常工作)。另外,您能否详细说明使用jQuery函数而不是我目前拥有的内容? - Charlie
是的,他的代码有效。你的示例无法工作,因为var drag=$(".drag");会将多个元素分配给变量吗? - Charlie
他和我说的是同样的事情...我只是在解释选择器的工作原理。我添加了另一个例子来澄清。 - Tim M.
感谢澄清。哪种方式更好?我知道这是一个普遍的问题,但就可读性而言,我更喜欢João的答案。此外,如果你们都在说同样的事情,为什么你的例子不起作用而他的却可以呢? - Charlie
因为我没有像João那样给出完整的示例。我只是向您展示了您错误使用选择器仅匹配第一个元素背后的理论。至于最佳方法,有许多有效的使用jQuery的方法。我建议首先阅读each()方法:http://api.jquery.com/each/ - Tim M.

0

对于大多数有经验的开发人员来说,这可能是显而易见的,但对于像我这样遇到了jQuery无法应用于多个元素的一些初级开发人员来说,这可能会很有帮助。

今天我学到了一个知识点,就是你必须确保你的脚本是在

之外加载的。

我错误地将脚本加载在第一个元素内部,并想知道为什么jQuery函数没有应用于页面下方的其他


0

首先,您可以使用[0]声明只想要第一个元素。

其次,您应该使用jQuery的on()方法。以下是我看到您的函数:

var drag = $(".drag");

drag.on("touchmove", function(event) {
    xPos = $(this).offsetWidth / 2;
    yPos = $(this).offsetHeight / 2;

    event.preventDefault(); // preventDefault is IE-specific, is it?  

    $(this).css({
        'left' : event.targetTouches[0].pageX - xPos + 'px', 
        'top' : event.targetTouches[0].pageY - yPos + 'px'
        });
});

使用bind()方法有哪些好处? - Charlie
抱歉,我的错误 - 自从jQuery 1.7以来,首选方法是使用'on'而不是'bind'。addEventListener在这里甚至都不起作用(标记为正确的解决方案也不应该工作),因为addEventListener是针对JS元素的,而你正在尝试将其绑定到jQuery对象上。您可以在此处找到有关使用'on'的讨论:https://dev59.com/D2ox5IYBdhLWcg3wvW7X - mhaligowski

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接