在 JQuery 中获得祖父母的第一个 child 最优雅、可靠和高效的方法是什么?
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
的第一个 child。
$('#file2Download').val(
$(this).closest('tr').find('td:first').text()
);
.closest()
将带您从按钮向上 DOM 到最近的 table 行 (<tr>
),然后 .find('td:first').text()
将向下搜索DOM 并获取第一个 table 单元格的文本内容。
顺便说一句,我假设您在您的示例中不是指 $('#id0')
,因为您的表单 ID 是 form0
,它将通过 $('#form0')
.
选择
获得必需的 祖父母的第一个 child 的最优雅和最有效的方法是使用普通的旧 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 代码实际上是 much, much slower,即:≤ 4.2% 的速度。 可能 从 jQuery 解决方案中获得的只是几个字符。这个故事的寓意是,不要害怕在您的jQuery 环境 中使用香草javascript。在有意义的地方使用其中一个或两个。
现在,如果您不确定目标元素在参考元素祖先中的位置,请查看 closest()
:
For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
var text = $(this).<b>closest("tr")</b>.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>
$('#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>
注意,参见
另一种方法是将 data-*
属性添加到 button
元素,将 id
添加到第一个 td
;然后可以 select 首先 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)
让我们阐明在考虑最可靠和最有效的方法时可能出现的问题。我将在这里简要介绍 closest() 和 parent() 函数,以便任何 reader 清楚使用哪个、何时以及为什么使用。
closest() 获取匹配选择器的第一个元素,一个 jQuery object 我们通过测试给定的 jQuery object 和遍历 DOM 树寻找它的祖先。
parent() 在 DOM 树中向上移动单个元素,并选择 parent 到给定 jQuery object 的直接元素。
它们的区别很明显,尽管事实上它们的功能似乎与它们遍历 DOM 树的方式相似。
差异:
closest() - 从当前元素开始。向上移动 DOM 树,直到找到提供的选择器的匹配项。返回的 jQuery object 包含原始集合中每个元素的零个或一个元素,按文档顺序
parent() - 以 parent 元素开头。沿着 DOM 树向上移动到文档的根元素,将每个祖先元素添加到一个临时集合中;然后它会根据选择器过滤该集合(如果提供的话)。返回的 jQuery object 包含原始集合中每个元素的零个或多个元素,文档顺序相反。
因此,parent 由于其在 parent 树结构中上升一个级别的性质,因此在计算上会提供更快的搜索。请记住,情况确实如此,因为我们正在寻找 grandparent.
有关实施的更多详细信息,请参阅jQuery documentation。
tl;博士
接受的答案是第二慢的建议。
原版 javascript 和 jQuery 之间的区别是巨大的。
猫皮有很多种,还是先找爷爷奶奶吧child.
尽可能使用原版 javascript。
结果
以下是迄今为止建议的所有方法中的 jsPerf results。请记住,ops/sec 的数字越大越好,我已将它们从最快到最慢排序
Element.parentNode.parentNode.firstElementChild.textContent;
@佳能
(Demo)
字符 = 60
ops/sec = 3,239,703
Element.parentNode.parentNode.children[0].textContent;
@佳能
(Demo)
字符 = 54
ops/sec = 1,647,235
Element.parentNode.parentNode.cells[0].textContent;
@佳能
(Demo)
字符 = 51
ops/sec = 1,558,070
Element.parentNode.parentNode.querySelector('td:first-child').textContent;
@小巨人
(Demo)
字符 = 74
ops/sec = 1,189,826
document.getElementById(Element.dataset.select).textContent;
@guest271314
(Demo)
字符 = 60
ops/sec = 800,876
$('#' + $(Element).data('select')).text();
@guest271314
(Demo)
字符 = 42
ops/sec = 47,144
$('td:first-child',Element.parentNode.parentNode).text();
@小巨人
(Demo)
字符 = 57
ops/sec = 18,305
$(Element).parent().siblings(":eq(0)").text();
@guest271314
(Demo)
字符 = 46
ops/sec = 17,633
$(Element).closest('tr').find('td:first').text();
@j08691
(Demo)
字符 = 49
ops/sec = 4,511
$(Element).parentsUntil('table').find('td:first').text();
@AlvaroMontoro
(Demo)
字符 = 54
ops/sec = 3,954
前五种方法都使用 vanilla javascript,而后五种方法使用 jQuery。即使是最快的 jQuery 解决方案,ops/sec 也有非常显着的下降。最慢的香草方法与最快的 jQuery 方法之间的差异使 jQuery 方法的速度是香草方法的 1/17。
如您所见,接受的答案是第二慢的。我会警告不要在这种情况下使用 closest 。你越具体,它就会越快运行,最接近的只是把它变成一个猜谜游戏。
这只是为了说明,虽然打字可能需要更多时间,但使用原版 javascript 总是更快。更妙的是,默认包含原版 javascript!
我有一张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
的第一个 child。
$('#file2Download').val(
$(this).closest('tr').find('td:first').text()
);
.closest()
将带您从按钮向上 DOM 到最近的 table 行 (<tr>
),然后 .find('td:first').text()
将向下搜索DOM 并获取第一个 table 单元格的文本内容。
顺便说一句,我假设您在您的示例中不是指 $('#id0')
,因为您的表单 ID 是 form0
,它将通过 $('#form0')
.
获得必需的 祖父母的第一个 child 的最优雅和最有效的方法是使用普通的旧 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 代码实际上是 much, much slower,即:≤ 4.2% 的速度。 可能 从 jQuery 解决方案中获得的只是几个字符。这个故事的寓意是,不要害怕在您的jQuery 环境 中使用香草javascript。在有意义的地方使用其中一个或两个。
现在,如果您不确定目标元素在参考元素祖先中的位置,请查看 closest()
:
For each element in the set, get the first element that matches the selector by testing the element itself and traversing up through its ancestors in the DOM tree.
var text = $(this).<b>closest("tr")</b>.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>
$('#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>
注意,参见
另一种方法是将 data-*
属性添加到 button
元素,将 id
添加到第一个 td
;然后可以 select 首先 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)
让我们阐明在考虑最可靠和最有效的方法时可能出现的问题。我将在这里简要介绍 closest() 和 parent() 函数,以便任何 reader 清楚使用哪个、何时以及为什么使用。
closest() 获取匹配选择器的第一个元素,一个 jQuery object 我们通过测试给定的 jQuery object 和遍历 DOM 树寻找它的祖先。
parent() 在 DOM 树中向上移动单个元素,并选择 parent 到给定 jQuery object 的直接元素。
它们的区别很明显,尽管事实上它们的功能似乎与它们遍历 DOM 树的方式相似。
差异:
closest() - 从当前元素开始。向上移动 DOM 树,直到找到提供的选择器的匹配项。返回的 jQuery object 包含原始集合中每个元素的零个或一个元素,按文档顺序
parent() - 以 parent 元素开头。沿着 DOM 树向上移动到文档的根元素,将每个祖先元素添加到一个临时集合中;然后它会根据选择器过滤该集合(如果提供的话)。返回的 jQuery object 包含原始集合中每个元素的零个或多个元素,文档顺序相反。
因此,parent 由于其在 parent 树结构中上升一个级别的性质,因此在计算上会提供更快的搜索。请记住,情况确实如此,因为我们正在寻找 grandparent.
有关实施的更多详细信息,请参阅jQuery documentation。
tl;博士
接受的答案是第二慢的建议。
原版 javascript 和 jQuery 之间的区别是巨大的。
猫皮有很多种,还是先找爷爷奶奶吧child.
尽可能使用原版 javascript。
结果
以下是迄今为止建议的所有方法中的 jsPerf results。请记住,ops/sec 的数字越大越好,我已将它们从最快到最慢排序
Element.parentNode.parentNode.firstElementChild.textContent;
@佳能
(Demo)
字符 = 60
ops/sec = 3,239,703Element.parentNode.parentNode.children[0].textContent;
@佳能
(Demo)
字符 = 54
ops/sec = 1,647,235Element.parentNode.parentNode.cells[0].textContent;
@佳能
(Demo)
字符 = 51
ops/sec = 1,558,070Element.parentNode.parentNode.querySelector('td:first-child').textContent;
@小巨人
(Demo)
字符 = 74
ops/sec = 1,189,826document.getElementById(Element.dataset.select).textContent;
@guest271314
(Demo)
字符 = 60
ops/sec = 800,876$('#' + $(Element).data('select')).text();
@guest271314
(Demo)
字符 = 42
ops/sec = 47,144$('td:first-child',Element.parentNode.parentNode).text();
@小巨人
(Demo)
字符 = 57
ops/sec = 18,305$(Element).parent().siblings(":eq(0)").text();
@guest271314
(Demo)
字符 = 46
ops/sec = 17,633$(Element).closest('tr').find('td:first').text();
@j08691
(Demo)
字符 = 49
ops/sec = 4,511$(Element).parentsUntil('table').find('td:first').text();
@AlvaroMontoro
(Demo)
字符 = 54
ops/sec = 3,954
前五种方法都使用 vanilla javascript,而后五种方法使用 jQuery。即使是最快的 jQuery 解决方案,ops/sec 也有非常显着的下降。最慢的香草方法与最快的 jQuery 方法之间的差异使 jQuery 方法的速度是香草方法的 1/17。
如您所见,接受的答案是第二慢的。我会警告不要在这种情况下使用 closest 。你越具体,它就会越快运行,最接近的只是把它变成一个猜谜游戏。
这只是为了说明,虽然打字可能需要更多时间,但使用原版 javascript 总是更快。更妙的是,默认包含原版 javascript!