J'espère utiliser les sélecteurs CSS pour sélectionner le dernier fichier dans le dernier répertoire non caché, qui est 6
, avec le code Javascript suivant:
<div id='root'> <div class='dir'> <div class='dir'> <div class='file'>1</div> <div class='file'>2</div> <div class='file'>3</div> </div> </div> <div class='dir'> <div class='dir'> <div class='file'>4</div> <div class='file'>5</div> <div class='file'>6</div> </div> </div> <div class='dir'> <div class='dir'> <div class='dir hidden'> <div class='dir'> <div class='file'>7</div> <div class='file'>8</div> <div class='file'>9</div> </div> </div> </div> </div> </div>
Mais le résultat est 3
. Je me demande s'il existe un moyen d'obtenir 6
avec uniquement des sélecteurs CSS par opposition au code Javascript récursif.
HTML:
const root = document.querySelector('#root'); const last = root.querySelector('.dir:not(.hidden):last-child .file:last-child'); console.log(last.innerHTML);
https://jsbin.com/moyagivopi/1/edit?html,js , console
https: // jsbin .com / huteqabiga / 1 / edit? html, js, console
3 Réponses :
Vous pouvez diviser votre sélection en 2 étapes, vous obtenez d'abord les éléments sans .hidden
puis vous sélectionnez le dernier dans le dernier . Je ne pense pas que vous aurez une chance avec du CSS pur
<div id='root'> <div class='dir'> <div class='dir'> <div class='file'>1</div> <div class='file'>2</div> <div class='file'>3</div> </div> </div> <div class='dir'> <div class='dir'> <div class='file'>4</div> <div class='file'>5</div> <div class='file'>6</div> </div> </div> <div class='dir'> <div class='dir '> <div class='file'>10</div> <div class='dir hidden'> <div class='file'>7</div> <div class='file'>8</div> <div class='file'>9</div> </div> </div> </div> </div>
//got from this answer https://stackoverflow.com/a/16863971/8620333 function hasSomeParentTheClass(element, classname) { if (element.classList.contains(classname)) return true; return element.parentElement && hasSomeParentTheClass(element.parentElement, classname); } var elements = document.querySelectorAll('.file'); var i = elements.length - 1; for (; i >= 0; i--) { if (!hasSomeParentTheClass(elements[i], 'hidden')) { break; } } console.log(elements[i].innerHTML);
Autre exemple:
<div id='root'> <div class='dir'> <div class='dir'> <div class='file'>1</div> <div class='file'>2</div> <div class='file'>3</div> </div> </div> <div class='dir'> <div class='dir'> <div class='file'>4</div> <div class='file'>5</div> <div class='file'>6</div> </div> </div> <div class='dir'> <div class='dir hidden'> <div class='file'>7</div> <div class='file'>8</div> <div class='file'>9</div> </div> </div> </div>
var last = document.querySelectorAll('#root > .dir:not(.hidden) > .dir:not(.hidden)'); var element = last[last.length - 1].querySelector('.file:last-child'); console.log(element.innerHTML);
Une autre idée serait de sélectionner tout le dernier .file
puis d'exécuter un test à partir du dernier pour voir s'il y a un ancêtre avec .hidden
classer. Contrairement à la solution précédente, cela fonctionnera avec n'importe quel niveau d'imbrication.
<div id='root'> <div class='dir'> <div class='dir'> <div class='file'>1</div> <div class='file'>2</div> <div class='file'>3</div> </div> </div> <div class='dir'> <div class='dir'> <div class='file'>4</div> <div class='file'>5</div> <div class='file'>6</div> </div> </div> <div class='dir hidden'> <div class='dir'> <div class='file'>7</div> <div class='file'>8</div> <div class='file'>9</div> </div> </div> </div>
var last = document.querySelectorAll('#root > .dir:not(.hidden) > .dir:not(.hidden)'); var element = last[last.length - 1].querySelector('.file:last-child'); console.log(element.innerHTML);
Modifié par OP: supprimé : last-child
, au cas où le fichier 10 existe.
Merci! Cela fonctionne dans mon exemple. Mais j'obtiens 9
lorsque je déplace la classe hidden
d'un niveau vers le bas. Est-il possible que j'obtienne encore 6
dans ce cas?
@ElgsQianChen Ah, vous voulez envisager des niveaux imbriqués?
Oui, les sélecteurs semblent bien fonctionner lorsqu'il n'y a qu'un seul niveau de dir.
merci, cela fonctionne dans l'exemple spécifique, mais si j'ai ajouté plus de niveaux de dir, j'ai toujours 9
. jsbin.com/mizaqobiza/1/edit?html,js,console
@ElgsQianChen bien, si vous ajoutez plus de niveau, nous devons continuer à éditer :) comme vous pouvez voir le sélecteur, la logique sera la même, nous ajoutons simplement plus de > .dir: not (.hidden)
@ElgsQianChen je vais éditer avec une manière plus générique qui considère n'importe quel niveau;)
Quels sont les niveaux de dir seront dynamiques?
@ElgsQianChen vérifiez la mise à jour, j'ai ajouté un exemple avec un niveau dynamique
Vous pouvez utiliser querySelectorAll
, puis découper pour obtenir le dernier élément du tableau.
Voir ci-dessous.
<div id='root'> <div class='dir'> <div class='dir'> <div class='file'>1</div> <div class='file'>2</div> <div class='file'>3</div> </div> </div> <div class='dir'> <div class='dir'> <div class='file'>4</div> <div class='file'>5</div> <div class='file'>6</div> </div> </div> <div class='dir'> <div class='dir hidden'> <div class='file'>7</div> <div class='file'>8</div> <div class='file'>9</div> </div> </div> </div>
const root = document.querySelector('#root'); const last = Array.prototype.slice.call(root.querySelectorAll('.dir:not(.hidden):first-child > .file:last-child')).slice(-1)[0]; console.log(last.innerHTML);
Merci, mais désolé j'ai mis à jour ma question, en ce sens que le niveau des répertoires sera dynamique.
Je vois, utilisez Jquery à la place alors. C'est la meilleure solution :)
Vous allez devoir utiliser la récursivité pour vérifier tous les nœuds parents de la classe cachée. J'ai téléchargé deux extraits, un pour chacun de vos cas d'utilisation. Même JS pour les deux.
Pour référence: https://codeburst.io/learn-and-understand-recursion- in-javascript-b588218e87ea
<div id='root'> <div class='dir'> <div class='dir'> <div class='file'>1</div> <div class='file'>2</div> <div class='file'>3</div> </div> </div> <div class='dir'> <div class='dir'> <div class='file'>4</div> <div class='file'>5</div> <div class='file'>6</div> </div> </div> <div class='dir'> <div class='dir'> <div class='dir hidden'> <div class='dir'> <div class='file'>7</div> <div class='file'>8</div> <div class='file'>9</div> </div> </div> </div> </div> </div>
const root = document.querySelector('#root'); const files = root.querySelectorAll('.file'); var div; for (var i=0; i< files.length; i++){ if (!doesParentContainClass(files[i])) { div = files[i]; } } console.log(div.innerHTML) function doesParentContainClass(element) { if (element.className && element.className.split(' ').indexOf('hidden')>=0) return true; return element.parentNode && doesParentContainClass(element.parentNode); }
<div id='root'> <div class='dir'> <div class='dir'> <div class='file'>1</div> <div class='file'>2</div> <div class='file'>3</div> </div> </div> <div class='dir'> <div class='dir'> <div class='file'>4</div> <div class='file'>5</div> <div class='file'>6</div> </div> </div> <div class='dir hidden'> <div class='dir'> <div class='file'>7</div> <div class='file'>8</div> <div class='file'>9</div> </div> </div> </div>
const root = document.querySelector('#root'); const files = root.querySelectorAll('.file'); var div; for (var i=0; i< files.length; i++){ if (!doesParentContainClass(files[i])) { div = files[i]; } } console.log(div.innerHTML) function doesParentContainClass(element) { if (element.className && element.className.split(' ').indexOf('hidden')>=0) return true; return element.parentNode && doesParentContainClass(element.parentNode); }
Vous recherchez essentiellement une fonction
nth-child-of-selector ()
, qui n'existe pas en CSS.@Utkanos J'ai trouvé si je réduis le niveau de dir à 1, sans considérer le
: not (.hidden)
. Je pourrais en fait obtenir9
. Je me demande donc que le code JS récursif est inévitable.@Utkanos: Le problème est un peu plus profond que cela. Ils veulent le dernier
.file
descendant de#root
qui ne correspond pas à#root .dir.hidden .file
.