这里真的有两个问题:
- 选择表格行中所有输入的最佳方法
- 确保所有输入都有值
对于第一个问题,有潜意识的一面。确保它是一个输入,然后在更改输入的当前行的上下文中选择它。
首先,jQuery 在后台使用 Sizzle (https://sizzlejs.com/) 引擎进行选择。需要注意的一件事是该引擎对选择器字符串的“从右到左”处理。
因此,最佳选择在某种程度上是特定于浏览器的,但最快的选择方法是在现代浏览器中使用 ID 后跟一个类。一些较旧的浏览器也不会按类别进行选择,但让我们留待您研究。
选择:做事的方式不好
鉴于此,让我们看一下您可能会使用的复杂选择器:
'div.mycontainer div.mytablecontainer>table#mytable.mytableclass tr td select, div.mycontainer div.mytablecontainer>table#mytable.mytableclass tr td input'
首先不要使用它。现在来探讨为什么不这样做:还记得我们讨论过“从右到左”选择器处理吗?为了讨论,让我们将选择器缩小到最后一部分:
"div.mycontainer div.mytablecontainer>table#mytable.mytableclass tr td input"
然后从右边开始:
- “查找 DOM 中的所有输入”,
- 使用这些输入的列表,“在
td 元素中查找所有输入
- 使用那些
td 元素,找到tr 中的所有元素
- 在
.mytableclass 元素中找到所有tr
- 在 ID 为
mytable 的元素中查找所有元素(请记住,此 ID 必须是唯一的)
- 现在继续,找到
table 元素的单个元素 id
- 这是类
mytablecontainer 的元素的直接子元素
- 这是一个DIV元素
div
- 这是类
mycontainer的元素的子元素
- 这是一个DIV元素
div
哇,那里的工作量很大。但我们还没有完成!我们必须为那里的 OTHER 选择器做同样的事情。
选择:更好的做事方式
现在让我们做得更好;首先,让我们利用现代浏览器类选择器向我们所有的“作用域”输入添加一个类——我们想要检查条目的东西。
<input class="myinput" />
它确实需要type="" 属性,但暂时忽略它。让我们使用它。
$('#mytable').find('.myinput');
这是做什么的:
- 选择ID为
'mytable'的元素,这是所有浏览器中最快的选择器;我们已经在 DOM 中删除了这 47 个其他表。
- 查找类为
class="myinput"的所有元素; 在该表中;在现代浏览器中,这也非常快
完成。哇!工作量要少得多。
关于.find() 而不是"#mytable input" 的旁注
还记得我们的从右到左吗?找到 DOM 中的所有输入,然后缩小到我们在该表中找到的那些输入,现在不要停止。
或者(更有可能)"#mytable .myinput"
所以我们选择一组元素的“规则”是:
-
尽可能使用 ID 将范围限制到某个容器
- 单独使用 ID,而不是更复杂的选择器的一部分
-
在有限范围内查找元素(如果可以,按类)
-
使用类,因为现代浏览器对此进行了出色的选择优化。
- 当您开始在选择器中添加空格“”或“>”时,
.find() 或.children() 会更好吗?在一个小的 DOM 中也许维护可能更容易,但在 4 年内哪个更容易理解?
第二个问题:不具体但仍然存在
您不能简单地将!$(this).val() 用于输入。
对于无效的复选框。单选按钮呢?那<input type="button" > 稍后有人添加到行中呢?哎呀。
所以只需向您希望验证的所有“输入”添加一个类并由它们选择:
<input type="text" class="validateMe" />
<select class="validateMe" >...
附注您可能想要嗅探输入的类型并基于此进行验证:How to get input type using jquery?
编辑:请记住,您的验证输入可能具有“真/假”值,因此这可能会失败:!$(this).val()(此处想到单选按钮,复选框)
一些代码和标记:
<table id="mytable">
<tr>
<td>
<select class="myinput">
<option></option>
<option>Select anything</option>
</select>
</td>
<td>
<input class="myinput" type="text" name="field1" />
</td>
<td>
<input class="myinput" type="text" name="field2" />
</td>
</tr>
<tr>
<td>
<select class="myinput">
<option></option>
<option>Select something</option>
</select>
</td>
<td>
<input class="myinput" type="text" name="field3" />
</td>
<td>
<input class="myinput" type="text" name="field4" />
</td>
</tr>
</table>
<div id="results">
</div>
可能不想要一个全局(命名空间“选择器”)
var selectors = '.myinput';
$('#mytable').on('change', selectors, function(event) {
var $this = $(event.currentTarget),
$row = $this.closest('tr'),
$elements = $row.find(selectors);
var $filledElements = $elements.filter(function(index) {
return $(this).val() || this.checked;
});
var hasEmpty = $filledElements.length !== $elements.length
var rowIndex = $row.index();
$('#results').append("Row:" + rowIndex + " has " + $filledElements.length + ' of ' + $elements.length + ' and shows ' + hasEmpty + '<br />');
if (hasEmpty)
console.log('some value is missing');
else {
console.log('valide');
// do something with values
}
});
还有一些可以玩的东西:https://jsfiddle.net/MarkSchultheiss/fqadx7c0/