Поиск ближайшего элемента без jQuery
Я пытаюсь найти ближайший элемент с определенным именем тега без jQuery. Когда я нажимаю на <th> Я хочу получить доступ к <tbody> для этой таблицы. Предложения? Я читал о смещении, но на самом деле не понимал его слишком много. Я должен просто использовать:
предположим, что th уже установлен в щелчок th элемент
th.offsetParent.getElementsByTagName('tbody')[0]
13 ответов:
маленький (очень) опоздал на вечеринку, но тем не менее. Это должно сделать фишка:
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.closest('tbody')поддерживается во всех браузерах, кроме IE.
обновление: край теперь поддерживает его также.нет необходимости в jQuery. Более того, заменив jQuery
$(this).closest('tbody')С$(this.closest('tbody'))увеличит производительность, значительно, когда элемент не найден.Polyfill для 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');
function closest(el, sel) { if (el != null) return el.matches(sel) ? el : (el.querySelector(sel) || closest(el.parentNode, sel)); }это решение использует некоторые из более поздних функций спецификации HTML 5, и использование этого в старых/несовместимых браузерах (читай: Internet Explorer) потребует полифилл.
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; }
Я написал себе небольшую функцию, чтобы сделать это сегодня. Может быть, это помогает:
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");
чтобы расширить @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; }
получить ближайший элемент 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');
здесь.
function findNearest(el, tag) { while( el && el.tagName && el.tagName !== tag.toUpperCase()) { el = el.nextSibling; } return el; }находит только братьев и сестер ниже по дереву. Используйте previousSibling чтобы пойти в другую сторону Или используйте переменные для обхода обоих путей и возврата того, что найдено первым. Вы получаете общую идею, но если вы хотите пройти через parentNodes или детей, если брат не соответствует вам, вы можете также использовать jQuery. В этот момент это легко стоит того.
найти ближайшие элементы 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;}
немного поздно на вечеринку, но когда я проходил мимо и просто ответил на очень похожий вопрос, я бросаю здесь свое решение - мы можем сказать, что это JQuery
closest()подход, но в простом хорошем JavaScript.Он не нуждается в каких-либо pollyfills и это старые браузеры, и IE (: -)) дружественный: https://stackoverflow.com/a/48726873/2816279
резюме:
для поиска конкретного предка мы можем использовать:
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>
Я думаю, что самый простой код, чтобы поймать с 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>'; } ?>спасибо.
Comments