Я пытаюсь найти ближайший элемент с определенным именем тега без jquery. Когда я нажимаю на, <th>
я хочу получить доступ к <tbody>
этой таблице. Предложения? Я читал о смещении, но толком не разбирался. Должен ли я просто использовать:
Предположим, что th уже настроен на нажатый элемент th
th.offsetParent.getElementsByTagName('tbody')[0]
javascript
охотник
источник
источник
parentNode
: developer.mozilla.org/en-US/docs/Web/API/Node.parentNodeel.closest('tbody')
для браузеров, отличных от IE. См. Более подробный ответ + полифил ниже.Ответы:
Немного (очень) поздно на вечеринку, но тем не менее. Это следует сделать трюк :
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; }
источник
el
проверял элемент, который выполняет jQuery.closest (), а также Element.closest ().for( var parent = el ; parent !== null && !parent[matchesFn](selector) ; parent = el.parentElement ){ el = parent; } return parent;
parent
в глобальной области видимости (!)el.parentNode
иначе это сломается при обходе SVG в IE.Очень просто:
el.closest('tbody')
Поддерживается во всех браузерах, кроме IE.
ОБНОВЛЕНИЕ : Edge теперь также поддерживает его.
Нет необходимости в jQuery. Более того , замена JQuery это
$(this).closest('tbody')
с$(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.
источник
Вот как можно получить ближайший элемент по имени тега без 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 также включают полифил на случай, если вам нужно настроить таргетинг на старые браузеры.
Чтобы найти ближайшего
tbody
родителя с учетом a,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) потребуется полифил.
источник
Чтобы продлить ответ @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>
источник
Получите ближайший элемент 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');
источник
firstChar
вместо всехIF
условий?for
петлю?Найдите ближайшие элементы 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. На этом этапе это того стоит.
источник
Немного поздно на вечеринку, но когда я проходил мимо и просто ответил на очень похожий вопрос, я бросаю здесь свое решение - мы можем сказать, что это
closest()
подход JQuery , но на простом старом добром JavaScript.Он не нуждается в каких-либо поллифилах, и это старые браузеры и дружественные 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>'; } ?>
Большое спасибо.
источник