在 JQuery 中让祖父母的第一个孩子最优雅、最可靠、最有效的方法是什么?
What is the most elegant, reliable and efficient way to get the grandparent's first child in JQuery?
我有一段像 HTML
<form action="/AssetBundle/DownloadFile" data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace" data-ajax-update="#masterLinkHolder" id="form0" method="post"></form>
<table>
<tr>
<td>someimage.png</td>
<td><img src="imageicon.png"></td>
<td><button type="button">Click to Download</button></td>
</tr>
<tr>
<td>somedocument.docx</td>
<td><img src="docicon.png"></td>
<td><button type="button">Click to Download</button></td>
</tr>
</table>
<input type="hidden" id="file2Download" />
</form>
当单击button
时,我想将id
file2Download
输入的value
设置为文件名(例如 someimage.png
、 somedocument.docx
( 与按钮相同的tr
,然后提交表单。所以我需要帮助填写
<script type="text/javascript">
$('button').click(function () {
$('#file2Download').val(
// ... ?
);
$('#id0').submit();
});
</script>
以正确的方式。我知道我正在看一棵树,就像
tr
/ | '
td td td
| '
img button
并试图从button
到祖父母tr
,然后到该tr
的第一个孩子.
tl;dr
接受的答案是第二慢的建议。
vanilla javascript和jQuery之间的差异是巨大的。
有很多方法可以剥猫皮,或者找到祖父母的第一个孩子。
尽可能使用vanilla javascript。
结果
以下是到目前为止建议的所有方法的 jsPerf 结果。请记住,操作/秒的数字越高越好,我将它们从最快到最慢排序
Element.parentNode.parentNode.firstElementChild.textContent;
@canon(演示(
字符 = 60
操作/秒 = 3,239,703Element.parentNode.parentNode.children[0].textContent;
@canon(演示(
字符 = 54
操作/秒 = 1,647,235Element.parentNode.parentNode.cells[0].textContent;
@canon(演示(
字符 = 51
操作/秒 = 1,558,070Element.parentNode.parentNode.querySelector('td:first-child').textContent;
@Tiny巨人
(演示(
字符 = 74
操作/秒 = 1,189,826document.getElementById(Element.dataset.select).textContent;
@guest271314(演示(
字符 = 60
操作/秒 = 800,876$('#' + $(Element).data('select')).text();
@guest271314(演示(
字符 = 42
操作/秒 = 47,144$('td:first-child',Element.parentNode.parentNode).text();
@Tiny巨人
(演示(
字符 = 57
操作/秒 = 18,305$(Element).parent().siblings(":eq(0)").text();
@guest271314(演示(
字符 = 46
操作/秒 = 17,633$(Element).closest('tr').find('td:first').text();
@j08691(演示(
字符 = 49
操作/秒 = 4,511$(Element).parentsUntil('table').find('td:first').text();
@AlvaroMontoro(演示(
字符 = 54
操作/秒 = 3,954
方法都使用香草javascript,最后五种使用jQuery。即使是最快的jQuery解决方案,操作/秒也会有非常显着的下降。最慢的原版方法与最快的 jQuery 方法之间的差异使 jQuery 方法的速度是原版方法的 1/17。
如您所见,接受的答案是第二慢的。在这种情况下,我会警告不要使用最接近的。你越具体,它就会跑得越快,最接近的只是把它变成了一个猜谜游戏。
这只是表明,虽然输入可能需要更多时间,但使用vanilla javascript总是会更快。更好的是,默认情况下包含香草javascript!
$('#file2Download').val(
$(this).closest('tr').find('td:first').text()
);
.closest()
会将 DOM 从按钮带到最近的表格行 ( <tr>
(,然后.find('td:first').text()
将向下搜索 DOM 并获取第一个表格单元格的文本内容。
顺便说一句,我假设您在示例中的意思不是$('#id0')
,因为您的表单 ID 是 form0
,将通过 $('#form0')
选择。
获得必要的祖父母的第一个孩子的最优雅和最有效的方法是使用普通的旧JavaScript。在这种特殊情况下,您已经确切地知道从哪里获得所需的值。只需通过自己显式导航 DOM 来获取它:
$("button").click(function(e) {
var el = this // button
.parentNode // parent
.parentNode // grandparent
.firstElementChild; // grandparent's first child
console.log(el.textContent);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>someimage.png</td>
<td><button type="button">Click to Download</button></td>
</tr>
<tr>
<td>somedocument.docx</td>
<td><button type="button">Click to Download</button></td>
</tr>
</table>
这和你得到的速度差不多。可比较的jQuery代码实际上要慢得多,即:≤ 速度的4.2%。你从jQuery解决方案中获得的只是几个字符。这个故事的寓意是,不要害怕在你的jQuery环境中使用vanilla javascript。在有意义的地方使用其中一个或两个。
现在,如果您不确定目标元素在参考元素祖先中的位置,请查看closest()
:
对于集合中的每个元素,通过测试元素本身并在 DOM 树中遍历其祖先来获取与选择器匹配的第一个元素。
var text = $(this).closest("tr").find("td:first-child").text();
$("button").click(function(e) {
var text = $(this).closest("tr").find("td:first-child").text();
console.log(text);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<tr>
<td>someimage.png</td>
<td><button type="button">Click to Download</button></td>
</tr>
<tr>
<td>somedocument.docx</td>
<td><button type="button">Click to Download</button></td>
</tr>
</table>
让我们阐明在考虑最可靠和最有效的方法时可能出现的问题。我将在这里简要介绍最接近的((和parent((函数,以便任何读者都清楚使用哪个,何时以及为什么使用。
closest(( 通过测试给定的 jQuery 对象并遍历 DOM 树以查找其祖先来获取与选择器匹配的第一个元素,一个我们传递给函数的 jQuery 对象。
parent(( 在 DOM 树中向上移动单个元素,并选择作为给定 jQuery 对象的父级的直接元素。
它们的差异是显着的,尽管它们似乎都与它们遍历 DOM 树的方式相似。
差异:
closest(( - 从当前元素开始。沿 DOM 树向上移动,直到找到所提供选择器的匹配项。返回的 jQuery 对象包含原始集中每个元素的零个或一个元素,按文档顺序排列
parent(( - 以父元素开头。沿着 DOM 树向上移动到文档的根元素,将每个祖先元素添加到临时集合中;然后,它会根据选择器(如果提供了选择器(筛选该集合。返回的 jQuery 对象包含原始集中每个元素的零个或多个元素,按相反的文档顺序排列。
因此,父级将在计算上提供更快的搜索,因为它的性质是向上进入父树结构。请记住,情况确实如此,因为我们正在寻找祖父母。
有关实现的更多详细信息,请参阅 jQuery 文档。
$('#file2Download').val(
$(this).parent().siblings(":eq(0)").text()
);
$('button').click(function () {
$('#file2Download').val(
$(this).parent().siblings(":eq(0)").text()
);
console.log($("#file2Download").val())
//$('#id0').submit();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<form action="" data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace" data-ajax-update="#masterLinkHolder" id="form0" method="post"></form>
<table>
<tr>
<td>someimage.png</td>
<td><img src="imageicon.png"></td>
<td><button type="button">Click to Download</button></td>
</tr>
<tr>
<td>somedocument.docx</td>
<td><img src="docicon.png"></td>
<td><button type="button">Click to Download</button></td>
</tr>
</table>
<input type="hidden" id="file2Download" />
</form>
注意,请参阅 https://stackoverflow.com/a/30336313/
另一种方法是在button
元素中添加一个data-*
属性,第一个td
id
;然后可以直接根据点击的按钮选择第一个td
data-id="first-td"
.html
<form action="/AssetBundle/DownloadFile" data-ajax="true" data-ajax-method="POST" data-ajax-mode="replace" data-ajax-update="#masterLinkHolder" id="form0" method="post"></form>
<table>
<tr>
<td id="select1">someimage.png</td>
<td><img src="imageicon.png"></td>
<td><button type="button" data-select="select1">Click to Download</button></td>
</tr>
<tr>
<td id="select2">somedocument.docx</td>
<td><img src="docicon.png"></td>
<td><button type="button" data-select="select2">Click to Download</button></td>
</tr>
</table>
<input type="hidden" id="file2Download" />
</form>
.js
$("#file2Download").val(document.getElementById(this.dataset.select).textContent)
- 在jQuery中创建向下滑动子菜单的最有效方法
- 使用Underscore.js修改json数组中所选元素的更有效方法
- 选择具有值数组的所有元素的最有效方法
- 将JSON存储和恢复到此Ionic应用程序的最有效方法
- 将javascript数组中的项移动到特定位置的有效方法
- 将JS对象数组转换为嵌套形式的最有效方法
- 隐藏具有特定类$.each、for等的元素的有效方法
- 什么's是调用具有可变参数的函数的有效方法
- 选择具有特定数据的所有 html 标记的最有效方法是什么 - [适当性],无论值如何
- 使用 jQuery 调用 PHP 端点的最有效方法
- 这是解析 Int 的有效方法吗?
- 在JavaScript中搜索数组映射的最有效方法
- 获取字符串中最后一个换行符的最有效方法是什么
- 什么's是在两个(或多个)阵列中找到匹配的细胞序列的最有效方法
- 什么's是在IE8+中添加元素的最有效方法
- 从任何jquery选择器字符串创建元素的最有效方法
- 在日期范围内查找丢失日期的最有效方法是什么
- 对区间[1,10^12]中的整数进行编码/解码的快速有效方法是什么
- 在条件(if)结构的条件语句中是否有定义变量的有效方法
- 在ASP.NET中使用JQuery UI自动完成的有效方法