【问题标题】:Are jQuery selectors snapshots or are they updated in real timejQuery 选择器是快照还是实时更新
【发布时间】:2013-09-06 22:59:44
【问题描述】:

我有一个从 jQuery 选择器派生的变量 y:

function g() {
    jQuery('.MyProperty').each(function(){
        var x = jQuery(this);
        f(x);
    });
}

function f(x) {
    var y = x.siblings('SomeProperty').children('SomeClass');
    var myValue = random();
    y.MyValue = myValue;
    jQuery.ajax(
        /* ... */
        success: function {
            if (myValue != y.MyValue) {
                /// Do something!
            } else {
                /// Do something else!
            }
        }
    );
}

现在,让我们假设 g() 是一个事件处理程序,它在用户单击按钮时运行。这意味着它可以连续发射。由于 f() 触发异步 AJAX 调用,浏览器在成功之前不会阻塞,并且在所有 f() 调用完成后它们都可能以某种随机顺序到达(请记住,它们不会阻塞 AJAX 调用并且将刚刚完成),例如:

我面临的问题是,每个 AJAX 回调中的 y 似乎是实际 DOM 对象的快照,因为尽管对 g() 的调用(和 f( ) by extension) 发生在回调函数运行之前。

我想知道是否有任何方法可以刷新 jQuery 选择器,以便正确更新 y 的状态。

编辑:为了澄清我的担忧,这是一个示例事件队列:

g() /// Sets y.MyValue to 1.5555
g() /// Sets y.MyValue to 634.34
g() /// Sets y.MyValue to 555555
AJAX call back // Reads y.MyValue as 1.5555 when it should be 555555
AJAX call back // Reads y.MyValue as 555555 which is correct
g() /// Sets y.MyValue to 4232
AJAX call back // Reads y.MyValue as 4232 which is correct
AJAX call back // Reads y.MyValue as 634.34 when it should be 634.34

这可能会在服务器响应时间出现波动时发生。

【问题讨论】:

  • 正如 Pointy 所说,它们是快照。但是您问题中的代码似乎与此无关。
  • y 是一个局部变量,包含您在同一范围内创建的对象。它不是对 DOM 的引用,尽管它在内部包含对 DOM 的引用。所以/// Do something! 永远不会执行也就不足为奇了。了解您试图实现的实际最终目标是什么会很有用。您只是想限制 AJAX 请求吗?
  • 基本上,我想与适当的 DOM 对象重新同步。我见过 threads 谈论刷新 jQuery 选择器,但这仅适用于非常简单的选择器,而不适用于在这个特定示例中像 y 这样的多层深的选择器。
  • 这可能会帮助您理解一点:jsfiddle.net/x8VFM/1。您会注意到变量 y 始终是当前值。您可能还有其他问题。

标签: javascript jquery ajax


【解决方案1】:

jQuery 对象不是 DOM 的快照。 它们只是包装器,它们是包含对 DOM 元素(与您的选择器匹配)的引用的对象。 事实上,每次使用 jQuery 函数时,都会创建一个新的 jQuery 对象实例。所以你的 g() 函数每次都会将一个新实例传递给 f() 。然后 f 在这个新创建的 jQuery 对象实例上创建一个 MyValue 属性。然后为每个 ajax 调用创建一个新的成功处理程序。 y.MyValue 和 myValue 将始终相等,因为您每次都创建所有内容的新实例并告诉此值相等。

【讨论】:

  • 好的,请你们整理一下快照与非快照的争论。
  • jQuery 对象是包装器,它们包含对元素的索引(如数组)引用。如果没有找到您传递给 jQuery 函数的选择器的匹配项,或者如果您根本没有向 jQuery 函数传递任何参数,则仍然返回一个 jQuery 对象,只有一组空元素。亲自尝试:console.log(jQuery('a')) 将返回一个对象,其中包含对页面中所有链接的引用,索引从 0 到链接数 - 1。当然,jQuery 对象提供与集合中的元素交互的方法,否则它也可以是一个数组。
  • 当你这样做时:jQuery('.MyProperty') 在你的 g() 函数中,你会在每次调用 g() 时创建一个新的 jQuery 对象实例。所有这些 jQuery 对象实例在它们各自的集合中都有相同的元素,但它们是 jQuery 对象的不同实例。
  • 同样的事情发生在这里:var x = jQuery(this); 和这里:var y = x.siblings('SomeProperty').children('SomeClass');。每次调用您的函数时,它们都会创建 jQuery 对象的新实例。因此,当您这样做时:y.MyValue = myValue 您在新创建的对象上创建了一个属性。 jQuery 对象不是 DOM。
【解决方案2】:

如 cmets 中所述,它们是特定时间点的快照。除非我遗漏了什么,否则为什么不从成功回调中更新y(使用您需要的任何选择器)?

【讨论】:

    猜你喜欢
    • 2011-05-14
    • 2012-02-29
    • 1970-01-01
    • 2015-03-01
    • 1970-01-01
    • 2021-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多