在没有 jQuery 的情况下查找最近的元素
Finding closest element without jQuery
我正在尝试在没有jquery的情况下找到具有特定标签名称的最接近的元素。当我单击某个<th>
时,我想访问该表的<tbody>
。建议?我读过偏移量,但并没有真正理解它。我应该只使用:
假设 th 已设置为单击的第 th 元素
th.offsetParent.getElementsByTagName('tbody')[0]
很简单:
el.closest('tbody')
在除 IE 之外的所有浏览器上都受支持。
更新:Edge现在也支持它。
不需要 jQuery。更重要的是,用$(this.closest('tbody'))
替换jQuery的$(this).closest('tbody')
将提高性能,当找不到元素时会显着提高性能。
适用于 IE 的填充代码:
if (!Element.prototype.matches) Element.prototype.matches = Element.prototype.msMatchesSelector;
if (!Element.prototype.closest) Element.prototype.closest = function (selector) {
var el = this;
while (el) {
if (el.matches(selector)) {
return el;
}
el = el.parentElement;
}
};
请注意,找不到元素时没有return
,当找不到最近的元素时,实际上会返回undefined
。
有关更多详细信息,请参阅:https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
参加派对的时间很少(非常)晚,但尽管如此。这应该可以解决问题:
function closest(el, selector) {
var matchesFn;
// find vendor prefix
['matches','webkitMatchesSelector','mozMatchesSelector','msMatchesSelector','oMatchesSelector'].some(function(fn) {
if (typeof document.body[fn] == 'function') {
matchesFn = fn;
return true;
}
return false;
})
var parent;
// traverse parents
while (el) {
parent = el.parentElement;
if (parent && parent[matchesFn](selector)) {
return parent;
}
el = parent;
}
return null;
}
以下是在没有 jQuery 的情况下通过标签名称获取最接近元素的方法:
function getClosest(el, tag) {
// this is necessary since nodeName is always in upper case
tag = tag.toUpperCase();
do {
if (el.nodeName === tag) {
// tag name is found! let's return it. :)
return el;
}
} while (el = el.parentNode);
// not found :(
return null;
}
getClosest(th, 'tbody');
有一个标准化的函数可以做到这一点:Element.closest。除IE11外,大多数浏览器都支持它(详细信息由 caniuse.com 提供)。MDN 文档还包括一个 polyfill,以防您必须针对较旧的浏览器。
要找到最接近tbody
给定th
的父级,您可以执行以下操作:
th.closest('tbody');
如果您想自己编写函数 - 这是我想到的:
function findClosestParent (startElement, fn) {
var parent = startElement.parentElement;
if (!parent) return undefined;
return fn(parent) ? parent : findClosestParent(parent, fn);
}
要按标签名称查找最接近的父项,您可以像这样使用它:
findClosestParent(x, element => return element.tagName === "SECTION");
function closest(el, sel) {
if (el != null)
return el.matches(sel) ? el
: (el.querySelector(sel)
|| closest(el.parentNode, sel));
}
此解决方案使用 HTML 5 规范的一些较新的功能,并且在较旧/不兼容的浏览器(阅读:Internet Explorer)上使用它将需要 polyfill。
Element.prototype.matches = (Element.prototype.matches || Element.prototype.mozMatchesSelector
|| Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector
|| Element.prototype.webkitMatchesSelector || Element.prototype.webkitMatchesSelector);
正在使用的简单函数:-
function closest(el, selector) {
var matches = el.webkitMatchesSelector ? 'webkitMatchesSelector' : (el.msMatchesSelector ? 'msMatchesSelector' : 'matches');
while (el.parentElement) {
if (el[matches](selector)) return el;
el = el.parentElement;
}
return null;
}
扩展@SalmanPK答案
它将允许使用节点作为选择器,这在处理鼠标悬停等事件时很有用。
function closest(el, selector) {
if (typeof selector === 'string') {
matches = el.webkitMatchesSelector ? 'webkitMatchesSelector' : (el.msMatchesSelector ? 'msMatchesSelector' : 'matches');
while (el.parentElement) {
if (el[matches](selector)) {
return el
};
el = el.parentElement;
}
} else {
while (el.parentElement) {
if (el === selector) {
return el
};
el = el.parentElement;
}
}
return null;
}
总结:
为了找到一个特定的祖先,我们可以使用:
Element.closest();
此函数将 CSS 选择器字符串作为参数。 然后,它返回当前元素(或元素本身)的最接近的祖先,该祖先与参数中传递的 CSS 选择器匹配。如果没有祖先,它将返回null
。
例:
const child = document.querySelector('.child');
// select the child
console.dir(child.closest('.parent').className);
// check if there is any ancestor called parent
<div class="parent">
<div></div>
<div>
<div></div>
<div class="child"></div>
</div>
</div>
获取包含类、ID、数据属性或标记的树上最接近的 DOM 元素。包括元素本身。支持回到 IE6。
var getClosest = function (elem, selector) {
var firstChar = selector.charAt(0);
// Get closest match
for ( ; elem && elem !== document; elem = elem.parentNode ) {
// If selector is a class
if ( firstChar === '.' ) {
if ( elem.classList.contains( selector.substr(1) ) ) {
return elem;
}
}
// If selector is an ID
if ( firstChar === '#' ) {
if ( elem.id === selector.substr(1) ) {
return elem;
}
}
// If selector is a data attribute
if ( firstChar === '[' ) {
if ( elem.hasAttribute( selector.substr(1, selector.length - 2) ) ) {
return elem;
}
}
// If selector is a tag
if ( elem.tagName.toLowerCase() === selector ) {
return elem;
}
}
return false;
};
var elem = document.querySelector('#some-element');
var closest = getClosest(elem, '.some-class');
var closestLink = getClosest(elem, 'a');
var closestExcludingElement = getClosest(elem.parentNode, '.some-class');
查找最近的元素子节点。
closest:function(el, selector,userMatchFn) {
var matchesFn;
// find vendor prefix
['matches','webkitMatchesSelector','mozMatchesSelector','msMatchesSelector','oMatchesSelector'].some(function(fn) {
if (typeof document.body[fn] == 'function') {
matchesFn = fn;
return true;
}
return false;
});
function findInChilds(el){
if(!el) return false;
if(el && el[matchesFn] && el[matchesFn](selector)
&& userMatchFn(el) ) return [el];
var resultAsArr=[];
if(el.childNodes && el.childNodes.length){
for(var i=0;i< el.childNodes.length;i++)
{
var child=el.childNodes[i];
var resultForChild=findInChilds(child);
if(resultForChild instanceof Array){
for(var j=0;j<resultForChild.length;j++)
{
resultAsArr.push(resultForChild[j]);
}
}
}
}
return resultAsArr.length?resultAsArr: false;
}
var parent;
if(!userMatchFn || arguments.length==2) userMatchFn=function(){return true;}
while (el) {
parent = el.parentElement;
result=findInChilds(parent);
if (result) return result;
el = parent;
}
return null;
}
在这里。
function findNearest(el, tag) {
while( el && el.tagName && el.tagName !== tag.toUpperCase()) {
el = el.nextSibling;
} return el;
}
只在树下找到兄弟姐妹。使用上一个兄弟姐妹走另一条路或者使用变量遍历双向并返回首先找到的变量。你得到了大致的想法,但是如果你想遍历父节点或子节点,如果一个兄弟姐妹不匹配,你也可以使用jQuery。在这一点上,这很容易值得。
派对有点晚了,但是当我路过并回答一个非常相似的问题时,我在这里放弃了我的解决方案 - 我们可以说这是 JQuery closest()
的方法,但显然是好的 JavaScript。
它不需要任何 pollyfills,它是较旧的浏览器,并且 IE (:-) 友好:https://stackoverflow.com/a/48726873/2816279
容易用jquery捕获的代码最接近:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(document).ready(function () {
$(".add").on("click", function () {
var v = $(this).closest(".division").find("input[name='roll']").val();
alert(v);
});
});
</script>
<?php
for ($i = 1; $i <= 5; $i++) {
echo'<div class = "division">'
. '<form method="POST" action="">'
. '<p><input type="number" name="roll" placeholder="Enter Roll"></p>'
. '<p><input type="button" class="add" name = "submit" value = "Click"></p>'
. '</form></div>';
}
?>
多谢。
- 在谷歌地图上查找最近的大头针
- 如何查找离单击位置最近的子项
- 使用JavaScript查找数组中最近的日期
- jQuery查找最近的按钮并触发点击
- 算法导航:如何查找最近的日期(javascript)
- 查找所选元素的最近链接
- 如何查找最近的元素
- 在没有 jQuery 的情况下查找最近的元素
- 使用多个选择器查找DOM中最近的元素
- 使用jQuery查找离滚动位置最近的HTML片段标识符
- javascript数组查找具有当前日期+日期的最近日期
- 使用javascript查找元素相对于最近相对定位的父元素的位置
- 在元素中查找最近的td
- jQuery查找最近的ul
- 在点击的标签上查找最近的图像
- 查找最近的最外层导航(多个嵌套导航元素)
- 查找最近的隐藏字段的值,位于用户点击上面的javascript
- Google Maps:事件监听器只查找最近添加的对象
- 查找最近的日期(javascript)
- 从已知位置查找最近的列出(数组?)城市