[英]Finding closest element without jQuery
我試圖在沒有 jquery 的情況下找到具有特定標簽名稱的最近元素。 當我單擊<th>
我想訪問該表的<tbody>
。 建議? 我讀過偏移量,但並沒有真正理解它。 我應該只使用:
假設 th 已經設置為 clicked th 元素
th.offsetParent.getElementsByTagName('tbody')[0]
很簡單的:
el.closest('tbody')
支持除 IE 之外的所有瀏覽器。
更新:Edge 現在也支持它。
不需要 jQuery。 更重要的是,將 jQuery 的$(this).closest('tbody')
替換$(this.closest('tbody'))
將提高性能,尤其是在找不到元素時。
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;
}
};
請注意,未找到元素時不會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);
擴展@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;
}
這是我正在使用的簡單功能:-
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;
}
為了找到特定的祖先,我們可以使用:
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');
查找最近的元素 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;
}
這里。
function findNearest(el, tag) {
while( el && el.tagName && el.tagName !== tag.toUpperCase()) {
el = el.nextSibling;
} return el;
}
只能在樹的下方找到兄弟姐妹。 使用previousSibling走另一條路 或者使用變量來遍歷雙向並返回先找到的那個。 你得到了一般的想法,但是如果你想遍歷 parentNodes 或如果兄弟節點不匹配,你也可以使用 jQuery。 在這一點上,這很容易值得。
聚會有點晚了,但是當我路過並回答一個非常相似的問題時,我把我的解決方案放在這里 - 我們可以說這是 JQuery closest()
方法,但在普通的 ol' 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>';
}
?>
非常感謝。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.