我有一个页面,它选择表单中的所有元素并将它们序列化,如下所示:
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
选择器进行预限定)。然后,它对每个元素执行以下操作:
(假设检查结果为假则退出)
- 检查父级是否具有
form
的nodeName.toLowerCase()
的祖先。 - 检查它是否没有以
ww
开头的name
属性(基本indexOf
操作)。 - 检查它是否没有
id
属性以IDF
结尾的祖先。 (昂贵的操作) - 检查它的祖先是否具有包含
tools
的class
属性。
最后两个操作很慢。
最好手动构造一个 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/