我正在使用带有jQuery 1.5的jQuery Validate插件1.8.0。适用于中小型表格。对于较大的表单,性能会显着下降(即使在IE8和FF4中),有时会导致“脚本运行速度太慢”消息。即使您指定了自定义规则,该插件似乎也会扫描表单中的整个DOM,以查找要验证的属性和类。任何人都知道如何完全关闭它?还有一个忽略选项,但它仍会扫描DOM,使用ignore attr跳过那些。
以下是ASP.NET呈现的内容,但大约有120行数据。不幸的是,分析结果不是一种选择。
<table id="GridView1">
<tbody>
<tr>
<th scope="col">Header 1</th>
<th scope="col">Header 2</th>
<th scope="col">Header 3</th>
<th scope="col">Header 4</th>
<th scope="col">Header 5</th>
<th scope="col">Header 6</th>
<th style="width: 60px; white-space: nowrap" scope="col">Header 7</th>
<th style="width: 60px; white-space: nowrap" scope="col">Header 8</th>
</tr>
<tr class="gridRow" jquery1507811088779756411="3">
<td style="width: 50px" align="middle">
<span id="GridView1_ctl03_Label1">XXX</span>
</td>
<td>
<span id="GridView1_ctl03_Label2">YYY</span>
</td>
<td style="width: 50px" align="middle">
<span id="GridView1_ctl03_Label3">ZZZ</span>
</td>
<td align="middle">
<select style="width: 70px" id="GridView1_ctl03_Dropdown4" name="GridView1$ctl03$Dropdown4">
<option selected value="Y">Y</option>
<option value="N">N</option>
</select>
</td>
<td style="width: 50px" align="middle">
<input id="GridView1_ctl03_hidId1" value="100" type="hidden" name="GridView1$ctl03$hidId1" />
<input id="GridView1_ctl03_hidId2" value="100" type="hidden" name="GridView1$ctl03$hidId2" />
<input id="GridView1_ctl03_hidId3" value="100" type="hidden" name="GridView1$ctl03$hidId3" />
<input id="GridView1_ctl03_hidId4" value="100" type="hidden" name="GridView1$ctl03$hidId4" />
<select style="width: 40px" id="GridView1_ctl03_Dropdown5" name="GridView1$ctl03$Dropdown5">
<option selected value="A">A</option>
<option value="B">B</option>
</select>
</td>
<td style="width: 50px" align="middle">
<span id="GridView1_ctl03_Label6">101</span>
</td>
<td align="middle">
<input style="width: 60px" id="GridView1_ctl03_Textbox8" class="date required"
title="Please enter a valid start date." type="text" name="GridView1$ctl03$Textbox8"
jquery1507811088779756411="122" />
</td>
<td align="middle">
<input style="width: 60px" id="GridView1_ctl03_Textbox9" class="date"
title="Please enter a valid end date." type="text" name="GridView1$ctl03$Textbox9"
jquery1507811088779756411="123" />
</td>
</tr>
</tbody>
</table>
答案 0 :(得分:11)
我也一直在努力解决这个问题。通过自定义一些验证,我已经能够在IE8中减少80个验证元素的验证时间,从4100ms到192ms。我将在此发布我的发现,希望其他人可以受益,并且希望jquery-validate中的某位专家会发现我的代码存在问题。
以下是我发现有用的一些内容:
定义自己的方法来验证表单。 jQuery中内置的内容非常缓慢,并且您可能不需要它提供的所有灵活性。这是我的 - 使用它产生了巨大的差异(它被称为子集,因为我的表单被分成了标签,我在每个标签div上随着用户前进单独调用它。)
jQuery.validator.prototype.subset = function (container, validateHiddenElements) {
var ok = true;
var validator = this;
// Performance hack - cache the value of errors(), and temporarily patch the function to return the cache
// (it is restored at the end of this function).
var errors = this.errors();
var errorsFunc = this.errors;
this.errors = function () { return errors; };
$(container.selector + " [data-val=true]").each(function () {
!this.name && validator.settings.debug && window.console && console.error("%o has no name assigned", this);
var tagName = this.tagName.toLowerCase();
if (tagName == "input" || tagName == "select" || tagName == "textarea") {
var $this = $(this);
if (!$this.hasClass('doNotValidate') &&
(validateHiddenElements || $this.is(':visible'))) {
if (!validator.element($this)) ok = false;
}
}
});
this.errors = errorsFunc;
return ok;
};
在validator.settings上定义自己的showErrors方法。即使没有要显示的错误,内置的也会为每个可验证的输入创建错误消息跨度。如果你有很多这样的话,这会变得很慢,所以你可以添加一些逻辑来避免这种情况。这是我的:
function showErrorsOverride() {
var anyElementsNeedUpdate = false;
for (var i = 0; i < this.errorList.length; i++) {
if (!$(this.errorList[i].element).hasClass(this.settings.errorClass)) {
anyElementsNeedUpdate = true;
}
}
for (var i = 0; i < this.successList.length; i++) {
if ($(this.successList[i]).hasClass(this.settings.errorClass)) {
anyElementsNeedUpdate = true;
}
}
if (anyElementsNeedUpdate)
{
// show the usual errors (defaultShowErrors is part of the jQuery validator)
this.defaultShowErrors();
}
}
答案 1 :(得分:9)
派对有点晚了,但是对于任何感兴趣的人 - 类似于Joe的回答,我发现从defaultShowErrors()函数禁用成功设置会有所帮助。它似乎只是隐藏有效字段的错误标签,如果您没有任何错误标签,那么这是不必要的开销。在IE8中加速我的表格,从大约1.8秒到大约260毫秒的55个字段。
$(document).ready(function()
{
$("form").each(function ()
{
$(this).data("validator").settings.success = false;
})
});
答案 2 :(得分:0)
我们需要更多代码来帮助您。但遍历DOM对象是一项繁重的操作。 也许对于那些大型表格你想要使用另一种方法。如果你使用了很多组合和文本字段,你可以附加一个事件处理程序(丢失焦点),这样你就可以将值保存在一个javascript对象中,然后使用这个对象来获取数据。
答案 3 :(得分:0)
我们遇到了大型的类似问题,但发现了以下解决方案。现在我们的大型表格(> 600输入)在~10ms内验证。
我在这里发布了答案: https://stackoverflow.com/a/23132844/1821717