javascript 在没有jQuery的情况下查找最近的元素
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18663941/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Finding closest element without jQuery
提问by hunterc
I am trying to find the closest element with a specific tag name without jquery. When I click on a <th>
I want to get access to the <tbody>
for that table. Suggestions? I read about offset but didn't really understand it too much. Should I just use:
我试图在没有 jquery 的情况下找到具有特定标签名称的最近元素。当我单击 a 时,<th>
我想访问<tbody>
该表的 。建议?我阅读了偏移量,但并没有真正理解它。我应该只使用:
Assume th is already set to clicked th element
假设 th 已经设置为 clicked th 元素
th.offsetParent.getElementsByTagName('tbody')[0]
采纳答案by Ales
Little (very) late to the party, but nonetheless. This should do the trick:
聚会有点(非常)迟到,但仍然如此。这应该做的伎俩:
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;
}
回答by oriadam
Very simple:
很简单的:
el.closest('tbody')
Supported on all browsers except IE.
UPDATE: Edge now support it as well.
支持除 IE 之外的所有浏览器。
更新:Edge 现在也支持它。
No need for jQuery.
More over, replacing jQuery's $(this).closest('tbody')
with $(this.closest('tbody'))
will increase performance, significantly when the element is not found.
不需要 jQuery。更过,更换jQuery的$(this).closest('tbody')
使用$(this.closest('tbody'))
将提高性能,显著时未找到该元素。
Polyfill for IE:
IE 的 Polyfill:
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;
}
};
Note that there's no return
when the element was not found, effectively returning undefined
when the closest element was not found.
请注意,return
当未找到元素时没有,undefined
当未找到最近的元素时有效地返回。
For more details see: https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
有关更多详细信息,请参阅:https: //developer.mozilla.org/en-US/docs/Web/API/Element/closest
回答by Joon
Here's how you get the closest element by tag name without jQuery:
以下是在不使用 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');
回答by david1995
There exists a standardised function to do this: Element.closest. Most browsers except IE11 support it (details by caniuse.com). The MDN docsalso include a polyfill in case you have to target older browsers.
有一个标准化的函数可以做到这一点:Element.closest。除 IE11 外的大多数浏览器都支持它(caniuse.com 提供的详细信息)。该MDN文档还包括如果你有目标旧版浏览器的一个填充工具。
To find the closest tbody
parent given a th
you could do:
要找到最接近的tbody
父级,th
您可以执行以下操作:
th.closest('tbody');
In case you want to write the function yourself - here is what I came up with:
如果你想自己编写函数 - 这是我想出的:
function findClosestParent (startElement, fn) {
var parent = startElement.parentElement;
if (!parent) return undefined;
return fn(parent) ? parent : findClosestParent(parent, fn);
}
To find the closest parent by tag name you could use it like this:
要按标签名称查找最近的父级,您可以像这样使用它:
findClosestParent(x, element => return element.tagName === "SECTION");
回答by Matthew James Davis
function closest(el, sel) {
if (el != null)
return el.matches(sel) ? el
: (el.querySelector(sel)
|| closest(el.parentNode, sel));
}
This solution uses some of the more recent features of the HTML 5 spec, and using this on older/incompatible browsers (read: Internet Explorer) will require a polyfill.
此解决方案使用 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);
回答by zb'
To extend @SalmanPK answer
扩展@SalmanPK 答案
it will allow to use node as selector, useful when you working with events like mouseover.
它将允许使用节点作为选择器,这在您处理鼠标悬停等事件时非常有用。
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;
}
回答by Salman von Abbas
Here's the simple function I am using:-
这是我正在使用的简单功能:-
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;
}
回答by Willem van der Veen
Summary:
概括:
For finding a particular ancestor we can use:
为了找到特定的祖先,我们可以使用:
Element.closest();
Element.closest();
This function takes a CSS selector string as an argument. it then returns the closest ancestor of the current element (or the element itself) which matches the CSS selector which was passed in the arguments. If there is no ancestor it will return null
.
此函数将 CSS 选择器字符串作为参数。然后它返回与传入参数的 CSS 选择器匹配的当前元素(或元素本身)的最近祖先。如果没有祖先,它将返回null
。
Example:
例子:
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>
回答by MajidTaheri
Find nearest Elements childNodes.
查找最近的元素 childNodes。
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;
}
}
回答by Chris Ferdinandi
Get closest DOM element up the tree that contains a class, ID, data attribute, or tag. Includes the element itself. Supported back to IE6.
在包含类、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');