我有一个页面,它选择表单中的所有元素并将它们序列化为:
var filter = 'form :not([name^=ww],[id$=IDF] *,.tools *)';
var serialized = $(filter).serialize();
这是有效的,除非表格大约有600多个元素。然后用户得到javascript错误,说脚本运行缓慢,可能会使他们的浏览器无响应。然后它为他们提供了停止运行脚本的选项。
我试过单独运行过滤器,我尝试在选择器上使用.not,然后序列化它们,但我遇到了两个问题之一。要么运行得更快而没有错误,但也不会过滤元素,或者它会过滤元素并给我慢速脚本错误。
有什么想法吗?
答案 0 :(得分:5)
有600多个元素,这将会变慢。您需要为Sizzle(jQuery的选择器引擎)提供一些优化机会。
首先,考虑一下jQuery可以使用本机支持的querySelectorAll
方法(在现代浏览器中),如果您的选择器符合CSS3 spec(或至少达到目前支持的范围)浏览器)。
根据您的情况,这意味着只将一个简单选择器传递给:not
而不是3(1个简单,2个复杂)。
form :not([name^=ww])
这会非常快......虽然你不喜欢不支持querySelectorAll
的浏览器。
看看你的选择器,想想Sizzle与每个元素有多少关系。首先,它需要获取页面中的所有元素(您不是使用标记/ class / id预先限定 :not
选择器)。然后,在每个元素上执行以下操作:
(假设如果检查结果为假则退出)
nodeName.toLowerCase()
form
。name
开头的ww
属性(基本indexOf
操作)。id
属性以IDF
结尾的祖先。 (昂贵的操作)class
tools
属性的祖先。最后两个操作很慢。
最好手动构建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
);
});
注意:该功能未经测试。希望你明白了......
答案 1 :(得分:1)
您是否可以将整个表单序列化并在后端进行过滤?另外,为什么 - 为什么表格会增长到600多个领域呢?
答案 2 :(得分:0)
使用:input
选择器仅选择适用的元素..