J'essaie de trouver l'élément le plus proche avec un nom de balise spécifique sans jquery. Lorsque je clique sur un, <th>
je veux accéder au <tbody>
pour cette table. Suggestions? J'ai lu sur l'offset mais je ne l'ai pas trop compris. Dois-je simplement utiliser:
Supposons que l'élément soit déjà défini sur l'élément cliqué
th.offsetParent.getElementsByTagName('tbody')[0]
javascript
chasseur
la source
la source
parentNode
: developer.mozilla.org/en-US/docs/Web/API/Node.parentNodeel.closest('tbody')
pour les navigateurs non-ie. Voir la réponse plus élaborée + polyfill ci-dessous.Réponses:
Peu (très) tard à la fête, mais néanmoins. Cela devrait faire l' affaire :
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; }
la source
el
que jQuery.closest () et Element.closest () font.for( var parent = el ; parent !== null && !parent[matchesFn](selector) ; parent = el.parentElement ){ el = parent; } return parent;
parent
dans la portée globale (!)el.parentNode
ou cela se cassera lors de la traversée d'un SVG dans IE.Très simple:
el.closest('tbody')
Pris en charge sur tous les navigateurs sauf IE.
MISE À JOUR : Edge le prend désormais également en charge.
Pas besoin de jQuery. De plus, le remplacement de jQuery
$(this).closest('tbody')
par$(this.closest('tbody'))
augmentera les performances, de manière significative lorsque l'élément n'est pas trouvé.Polyfill pour 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; } };
Notez qu'il n'y a pas
return
lorsque l'élément n'a pas été trouvé, retournant effectivementundefined
lorsque l'élément le plus proche n'a pas été trouvé.Pour plus de détails, voir: https://developer.mozilla.org/en-US/docs/Web/API/Element/closest
la source
Voici comment obtenir l'élément le plus proche par nom de balise sans 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');
la source
Il existe une fonction standardisée pour ce faire: Element.closest . La plupart des navigateurs, à l'exception d'IE11, le prennent en charge ( détails par caniuse.com ). Les documents MDN incluent également un polyfill au cas où vous auriez à cibler des navigateurs plus anciens.
Pour trouver le
tbody
parent le plus proche,th
vous pouvez faire:th.closest('tbody');
Au cas où vous voudriez écrire la fonction vous-même - voici ce que j'ai proposé:
function findClosestParent (startElement, fn) { var parent = startElement.parentElement; if (!parent) return undefined; return fn(parent) ? parent : findClosestParent(parent, fn); }
Pour trouver le parent le plus proche par nom de balise, vous pouvez l'utiliser comme ceci:
findClosestParent(x, element => return element.tagName === "SECTION");
la source
function closest(el, sel) { if (el != null) return el.matches(sel) ? el : (el.querySelector(sel) || closest(el.parentNode, sel)); }
Cette solution utilise certaines des fonctionnalités les plus récentes de la spécification HTML 5, et son utilisation sur des navigateurs plus anciens / incompatibles (lire: Internet Explorer) nécessitera un polyfill.
la source
Pour étendre la réponse @SalmanPK
cela permettra d'utiliser node comme sélecteur, utile lorsque vous travaillez avec des événements comme le survol de la souris.
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; }
la source
Voici la fonction simple que j'utilise: -
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; }
la source
Sommaire:
Pour trouver un ancêtre particulier, nous pouvons utiliser:
Element.closest();
Cette fonction prend une chaîne de sélection CSS comme argument. il retourne alors l'ancêtre le plus proche de l'élément courant (ou de l'élément lui-même) qui correspond au sélecteur CSS qui a été passé dans les arguments. S'il n'y a pas d'ancêtre, il reviendra
null
.Exemple:
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>
la source
Obtenez l'élément DOM le plus proche dans l'arborescence qui contient une classe, un ID, un attribut de données ou une balise. Inclut l'élément lui-même. Prise en charge vers 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');
la source
firstChar
au lieu de toutes lesIF
conditions?for
boucle masquée ?Trouvez les childNodes Eléments les plus proches.
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;
}
la source
Ici.
function findNearest(el, tag) { while( el && el.tagName && el.tagName !== tag.toUpperCase()) { el = el.nextSibling; } return el; }
Ne trouve que les frères et sœurs plus bas dans l'arbre. Utilisez previousSibling pour aller dans l'autre sens Ou utilisez des variables pour parcourir les deux sens et renvoyer celui qui est trouvé en premier. Vous avez l'idée générale, mais si vous voulez traverser les nœuds parents ou les enfants si un frère ne correspond pas, vous pouvez également utiliser jQuery. À ce stade, cela en vaut la peine.
la source
Un peu tard à la fête, mais alors que je passais et que je répondais juste à une question très similaire, je laisse ici ma solution - nous pouvons dire que c'est l'
closest()
approche JQuery , mais en bon vieux JavaScript.Il n'a pas besoin de pollyfills et ses navigateurs plus anciens et compatibles avec IE (:-)): https://stackoverflow.com/a/48726873/2816279
la source
Je pense que le code le plus simple à attraper avec jquery le plus proche:
<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>'; } ?>
Merci beaucoup.
la source