12
votes

JQuery premier parent contenant tous les enfants

Comment puis-je avoir sur la sélection du premier parent d'un ensemble d'éléments contenant tous ces éléments?

Par exemple: P>

[$('ul')]


5 commentaires

Vous recherchez l'ancêtre commun le plus bas de tous les éléments?


Le parent peut-il contenir d'autres classes ou recherchez-vous le parent qui ne contient que les mêmes classes? $ (". article-info"). Les parents ("UL: premier") vous donneront tous (UL) qui ont ces enfants et filtrer automatiquement des doublons, vous obtenez donc une seule ul dans ce cas.


Oui, je cherche une version généralisée du plus petit-ancêtre commun


Par curiosité - Pourquoi avez-vous besoin de faire cela? Je ne peux pas vraiment penser à des applications utiles.


Eh bien, à long et à court d'entre eux, insertion dynamique d'un spectacle / cache tout bouton, mais regroupée par section, et je ne voulais pas avoir à changer mon javascript si j'ai décidé d'utiliser différentes balises pour mes listes d'articles.


11 Réponses :


0
votes

cherchez-vous-vous l'un de ces?

$("element").parents() // return all parents until reaches 'html'

$("element").parent() // return the first parent

$("element").closest("parent") // return the closest selected parent


3 commentaires

Ce serait le plus proche ("ul") ou des parents ("ul") car il n'y a pas d'élément "parent". C'est-à-dire que si l'OP ne cherche réellement l'élément commun le plus proche et c'est une autre boîte de vers.


Je pense qu'il demande l'ancêtre commun le plus proche, auquel cas cela ne fonctionnera pas.


Oui, je pensais $ ('. Article-info'). Parent () ou $ (". Article-info '). Le plus proche (' ul ') lorsque j'ai lu la question.



2
votes

Je suppose que le point est que le .Item-info est (potentiellement) étalé sur la page.

Si c'est vrai, Essayez ceci: < un href = "http://jsfiddle.net/ejwjf/1/" rel = "nOfollow noreferrer"> http://jsfiddle.net/ejwjf/1/ xxx


Voici une version de la fonction: http://jsfiddle.net/ejwjf/2/ xxx


9 commentaires

C'est une belle solution simple s'il utilise un seul sélecteur. Mais nécessite une duplication / une connaissance préalable du ou des sélecteurs.


@Jamie - S'il vous plaît expliquer ce que vous voulez dire. Vous devriez connaître le sélecteur à un moment donné. Aucune raison pour laquelle il ne pouvait pas être partagé dans une variable. Ou je ne comprends pas ce que tu veux dire?


@Jamie - Voici une version de la fonction: jsfiddle.net/ejwjf/2 Il suffit de passer dans le sélecteur. Bien que vous ayez raison sur plusieurs sélecteurs. Cela nécessiterait un peu plus d'attention. Devrait être très faisable, cependant.


En fait, fonctionne bien avec plusieurs sélecteurs, si vous voulez dire des sélecteurs séparés par des virgules. jsfiddle.net/ejwjf/4


Je voulais dire plus dans les lignes de si j'ai var cor = $ ("certains sélecteur"). Parents ("UL"); a ensuite voulu faire CONT.C.MONANCESTEUR () . Les choses enchaînements sont une partie très importante de JQuery. En tout cas, j'étais celui qui vous a euillée, je n'ai aucune idée qui vous a baissé depuis qu'ils n'étaient pas assez utiles pour laisser un commentaire.


@Jamie - merci pour le vote Up. Il y a eu de plus en plus de votes en bas sans explication ces derniers temps. Les utilisateurs semblent donc avoir un peu de classe basse malheureusement. : O (en ce qui concerne la chaîne, cela devrait pouvoir être transformé dans un plugin tout aussi facilement. Je n'étais pas sûr de ce que l'Op voulait finalement depuis qu'un sélecteur n'est pas une option disponible.


@Jamie - a ajouté une version plugin, juste pour la preuve de concept. ; o) jsfiddle.net/ejwjf/5


@Patrick Il est bon de savoir sur la propriété .Selector, je ne savais pas à ce sujet! Cependant, cela échoue toujours si vous n'utilisez pas de sélecteur simple. Exemple: $ ('. Élément-info'). Ajouter ('Span'). FindCommon (); échoue


J'aimerais avoir inclus votre fonction dans mes comparaisons (voir ma réponse) mais elle ne s'est pas prêtée à un plugin JQuery à usage général.



9
votes

Si vous recherchez réellement un ancêtre commun le plus bas ( Voir ce fonctionnement dans un violon ):

<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="jquery.commonancestor.js"></script>


$(function() {
  console.log($(".item-info").commonAncestor());
});
</script>
<body>
 <dl>
  <dt>Items:</dt>
  <dd>
   <ul>
    <li>Item 1<b><div class="item-info">...</div></b></li>
    <li>Item 2<u><div class="item-info">...</div></u></li>
    <li>Item 3<i><div class="item-info">...</div></i></li>
   </ul>
  </dd>
 </dl>
</body>


5 commentaires

Cela semble être le truc, mais je me demande ce qui est avec tout ce que la tranchage? Est-ce parce que .Parents () renvoie les éléments parent dans l'ordre inverse, se terminant par html ?


Le tranchant est nécessaire amener tous les nœuds à la même hauteur de l'arbre DOM. Si l'élément le plus proche de la racine ( html ) est de 3 nœuds, puis l'ancêtre commun le plus bas ne peut pas dépasser 3 nœuds de la racine. En outre, faire des vérifications sur l'égalité sur quoi que ce soit plus loin que cela n'est inutile, car un élément 3 nœuds éloignés de la racine ne peut pas être égal à un élément 4 nœuds. La tranche ramène la liste des nœuds parents à la distance minimale au nœud racine.


L'initial $ (this) n'est pas nécessaire depuis dans les fonctions jQuery, ceci est déjà un objet JQuery. De plus, depuis JQuery 1.4 (ou ThereBouts), un objet vide JQuery nécessite uniquement $ () pas `$ ([])


Consultez ma réponse si vous êtes intéressant dans certaines informations de comparaison et une affaire de bord qui rend votre fonction échoue.


IE8 iTère à travers des méthodes de tableau lors de l'utilisation de pour (var i dans les parents) . Donc, remplacez-le par pour (var i = 0; i Pour seulement itérer via des éléments de réseau.



0
votes

Je crois que c'est ce que vous recherchez:

jQuery

Les quatre premières lignes contiennent le code qui fait le réel saisir de l'ULS. Le reste est juste d'afficher le contenu de l'ULS correspondant. xxx

html xxx

Le code JQuery ci-dessus retournera l'ULS pour le premier et le deuxième coup (le troisième est un DUD). Vérifiez-le à http://jsfiddle.net/kstf/

Un autre exemple ( Sans l'alerte): http://jsfiddle.net/vqxgc/


5 commentaires

Ceci est essentiellement comme la réponse de Patrick, sauf plus longtemps, plus difficile à comprendre et avec plus de duplication de contenu - c'est-à-dire inutile si vous vouliez le réutiliser.


@Jamie Wong - Le code qui fait en réalité quelque chose est cinq lignes. Bien sûr, vous pouvez faire une prise d'élément de JQuery MOWERY en mettant $ (this) .children ("Li") dans une variable.


D'accord, mon problème avec la longueur est invalide, mais les autres problèmes sont debout.


Changé pour filtrer à la place. Encore plus efficace.


Je n'ai pas inclus votre fonction dans les cas de test car il ne se prête pas à être un plugin JQuery.



0
votes

Inspiré d'un mélange des autres réponses sur la quiétique, j'ai créé une version que j'ai trouvée adaptée à mes exigences. http://jsfiddle.net/qdrv5/ (Notez qu'il écrit le parent trouvé à la console)

jQuery.fn.firstParent=function (f){
    //Set the variables for use;
    s=$(this);
    var i,j;
    var p=[];
    var pv=true;

    //make sure there is something to itterate over
    if(s.length>0){

        //build a multidimentional array of parents
        s.each(function(){p.push($(this).parents());});

        //itterate through the parents of the first element starting at the closest
        for(i=0;i<p[0].length;i++){

            //itterate through all elements after the first
            for(j=1;j<s.length;j++){

                //look for the current parent of the first element in each array
                pv=($.inArray(p[0][i],p[j]) != -1);

                //if we are looking at the last element and it matchs, return that parent
                if(pv==true && j==s.length-1) return typeof(f)=='string'?$(p[0][i]).find(f):$(p[0][i]);
            }
        }
    }
    return false;
}


1 commentaires

Ricki, cette fonction échoue dans certains cas. Voir ce violon pour certains cas de test (cliquez sur les préréglages). Voir ma réponse pour plus de détails.



1
votes

Avez-vous oublié? ... c'est juste JavaScript ... XXX


1 commentaires

Je sais que c'est juste JavaScript. Cependant, le problème que je courais n'est pas aussi simple que cela. Je pourrais avoir un seul élément de liste, une boîte d'entrée, une étendue et un lien comme mon ensemble JQuery, et je voudrais obtenir le premier objet parent qui les contient tous, quel que soit leur lieu où ils se trouvent dans le document.



0
votes

Alors ... je sais que c'est un vieux fil, mais j'avais besoin de cette fonctionnalité exacte et j'avais besoin de travailler dans la belle chaîne qui est jQuery;) Alors voici ce que j'ai proposé:

jQuery.fn.firstParent=function (f){
    //Set the variables for use;
    s=$(this);
    var i,j;
    var p=[];
    var pv=true;

    //make sure there is something to itterate over
    if(s.length>0){

        //build a multidimentional array of parents
        s.each(function(){p.push($(this).parents());});

        //itterate through the parents of the first element starting at the closest
        for(i=0;i<p[0].length;i++){

            //itterate through all elements after the first
            for(j=1;j<s.length;j++){

                //look for the current parent of the first element in each array
                pv=($.inArray(p[0][i],p[j]) != -1);

                //if we are looking at the last element and it matchs, return that parent
                if(pv==true && j==s.length-1) return typeof(f)=='string'?$(p[0][i]).find(f):$(p[0][i]);
            }
        }
    }
    return false;
}


1 commentaires

Trey, cette fonction échoue dans certains cas. Voir ce violon pour certains cas de test (cliquez sur les préréglages). Voir ma réponse pour plus de détails.



1
votes

Voici ma version. Il fonctionne mieux de toutes les réponses de type JQuery-plugin sur la page. C'est le seul qui gère un objet jQuery vide $ () code> sans erreur. La réponse de Jamie Wong et de Jamie Wong sont les seules à gérer un objet JQuery mono-élément sans erreur.

i Construit a Jsfiddle met en valeur toutes les versions 'Sortie . Vous pouvez cliquer sur les boutons de préréglage pour voir facilement différents cas de test ou entrer votre propre sélecteur, puis cliquez sur Rechercher pour voir le résultat. P>

jQuery.fn.reverse = function() {
   return Array.prototype.reverse.call(this);
};

jQuery.fn.commonAncestor = function() {
   var i, l, current,
      compare = this.eq(0).parents().reverse(),
      pos = compare.length - 1;
   for (i = 1, l = this.length; i < l && pos > 0; i += 1) {
      current = this.eq(i).parents().reverse();
      pos = Math.min(pos, current.length - 1);
      while (compare[pos] !== current[pos]) {
         pos -= 1;
      }
   }
   return compare.eq(pos);
};


0 commentaires

0
votes

Je ferais quelque chose comme ceci: filtrer les parents de sélecteur, qui contiennent chaque élément de l'ensemble du sélecteur.

jQuery.fn.commonParent = function() {
  var parent = this.parents();
  this.each(function() {
    parent = parent.has(this);
  });
  return parent.first();
};


0 commentaires

1
votes

Celui-ci n'est pas significativement plus rapide que tous les autres (y compris Erike's) surtout pour de nombreux éléments:

p>

"Faux">
jQuery.fn.commonAncestor = function() {
  if (!this.length)
    return null;

  var parent = this[0].parentNode;
  for (var i = this.length - 1; i >= 1; --i) {
    var elt = this[i];
    if (elt.contains(parent))
      parent = elt.parentNode;
    else
      while (!parent.contains(elt))
        parent = parent.parentNode;
  }
  return parent;
};


0 commentaires

0
votes

8 ans plus tard et face au même problème que j'ai retrouvé ici. Aucune de ces réponses n'a été exactement ce que je cherchais, alors je me suis retrouvé avec cela. Ce n'est peut-être pas l'absolu le plus rapide, mais il est petit et simple: xxx

pour obtenir le plus proche: xxx


0 commentaires