javascript - 从 jQuery 选择器中过滤元素

标签 javascript jquery

我有一个页面,它选择表单中的所有元素并将它们序列化,如下所示:

var filter = 'form :not([name^=ww],[id$=IDF] *,.tools *)';
var serialized = $(filter).serialize();

除非表单包含 600 多个元素,否则这种方法有效。然后,用户收到 javascript 错误,指出脚本运行缓慢,可能导致浏览器无响应。然后,他们可以选择停止运行脚本。

我尝试单独运行过滤器,我尝试在选择器上使用 .not,然后序列化它们,但我遇到了两个问题之一。要么它运行得更快而没有错误,但也不过滤元素,或者它确实过滤了元素并给了我缓慢的脚本错误。

有什么想法吗?

最佳答案

对于 600 多个元素,这将非常慢。您需要为 Sizzle(jQuery 的选择器引擎)提供一些优化机会。

首先,考虑这样一个事实:如果您的选择器符合 CSS3 spec ,则 jQuery 可以使用 native 支持的 ​​querySelectorAll 方法(在现代浏览器中)。 (或者至少在浏览器当前支持的范围内)。

对于您的情况,这意味着仅将一个简单选择器传递给:not,而不是3个(1个简单,2个复杂)。

form :not([name^=ww])

这会相当快...尽管您对不支持 querySelectorAll 的浏览器不太友好。

看看你的选择器,想想 Sizzle 与每个元素有多少关系。首先,它需要获取页面中的所有元素(您没有使用标签/类/id 对 :not 选择器进行预限定)。然后,它对每个元素执行以下操作:

(假设检查结果为假则退出)

  1. 检查父级是否具有 formnodeName.toLowerCase() 的祖先。
  2. 检查它是否没有以 ww 开头的 name 属性(基本 indexOf 操作)。
  3. 检查它是否没有 id 属性以 IDF 结尾的祖先。 (昂贵的操作)
  4. 检查它的祖先是否具有包含 toolsclass 属性。

最后两个操作很慢。

最好手动构造一个 filter 函数,如下所示:

var jq = $([1]);
$('form :input').filter(function(){

    // Re-order conditions so that
    // most likely to fail is at the top!

    jq[0] = this; // faster than constructing a new jQ obj

    return (

        !jq.closest('[id$=IDF]')[0]
            // this can be improved. Maybe pre-qualify
            // attribute selector with a tag name

        && !jq.closest('.tools')[0]

        && this.name.indexOf('ww') !== 0

    );

});

注意:该功能未经测试。希望您能明白...

关于javascript - 从 jQuery 选择器中过滤元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3256852/

相关文章:

javascript - Nodejs Hapi - 如何启用跨域访问控制

javascript - JQuery Mobile OSM div 自动设置为 0% 高度,即使我的 CSS 已将其设置为 100%

javascript - 动态 jQuery 语句第二部分

javascript - 辅助 onClick 事件不起作用

javascript - 谷歌地图不会显示在浏览器上

javascript - 更改按钮中的 onclick 事件颜色

javascript - Access-Control-Allow-Origin 不允许 Origin null

javascript - Node.js - 异步方法调用问题

javascript - 组 JS 事件

javascript - 检查可拖动对象是否在正确的可放置容器中