Selektor CSS do pobrania ostatniego widocznego elementu div

161

Podchwytliwe pytanie dotyczące selektora CSS, nie wiem, czy to w ogóle możliwe.

Powiedzmy, że to jest układ HTML:

<div></div>
<div></div>  
<div></div>  
<div style="display:none"></div>
<div style="display:none"></div>  

Chcę wybrać ostatnią div, która jest wyświetlana (tj. Nie display:none), która byłaby trzecią divw podanym przykładzie. Pamiętaj, liczba divs na prawdziwej stronie może się różnić (nawet display:nonejedna).

Vishal Shah
źródło

Odpowiedzi:

62

Możesz wybrać i stylizować to za pomocą JavaScript lub jQuery, ale sam CSS nie może tego zrobić.

Na przykład, jeśli masz zaimplementowane jQuery w witrynie, możesz po prostu zrobić:

var last_visible_element = $('div:visible:last');

Chociaż miejmy nadzieję, że będziesz mieć klasę / identyfikator zawinięty wokół wybranych elementów div, w takim przypadku Twój kod wyglądałby tak:

var last_visible_element = $('#some-wrapper div:visible:last');
Surreal Dreams
źródło
22
pytanie wyraźnie mówi, że nie "selektor JQuery CSS", mówi "A CSS SELECTOR", to powinna być akceptowana ODPOWIEDŹ = P
AgelessEssence
2
To jest rzeczywiście odpowiedź na pierwotne pytanie. Pytający nigdy nie wspomniał o javascript ani jquery, a te tagi zostały dodane przez inną osobę odpowiadającą. 1nfected - czy naprawdę chcesz jQuery? Jeśli tak, umieść to w swoim pytaniu. W przeciwnym razie powinieneś zaakceptować tę odpowiedź.
jep
Myślę, że jQuery jest akceptowalne dla OP. W końcu to było przyjęte rozwiązanie.
Surreal Dreams
7
Whhyyyy to pierwsza odpowiedź allllwaaayyysss jquery? To jest odpowiedź javascript na pytanie CSS . CSS! == javascript
dudewad
2
@dudewad: Zobacz ostatnią część pierwszego zdania: „ale sam CSS nie może tego zrobić”. Odpowiedź może na tym poprzestać, bez żadnej alternatywy w zasięgu wzroku ... lub stanowić alternatywę. Ale ta odpowiedź przynajmniej dołożyła należytej staranności, stwierdzając, że CSS nie może zrobić tego, o co jest proszony (chociaż nie wyjaśnia, dlaczego ). Z drugiej strony, odpowiedź, która po prostu trafia w rozwiązanie JavaScript, nie biorąc pod uwagę charakteru CSS pytania, jest warta krytyki.
BoltClock
23

Prawdziwa odpowiedź na to pytanie brzmi: nie możesz tego zrobić. Alternatywy dla odpowiedzi zawierających tylko CSS nie są poprawnymi odpowiedziami na to pytanie, ale jeśli rozwiązania JS są dla Ciebie akceptowalne, powinieneś wybrać jedną z odpowiedzi JS lub jQuery tutaj. Jednak, jak powiedziałem powyżej, prawdziwa, poprawna odpowiedź jest taka , że nie możesz tego zrobić w CSS niezawodnie, chyba że chcesz zaakceptować :notoperator z [style*=display:none]innymi takimi zanegowanymi selektorami, które działają tylko w stylach wbudowanych i ogólnie są kiepskie rozwiązanie.

dudewad
źródło
Po pierwsze, zgadzam się z tobą, ale myślę, że używanie :notoperatora, jak powiedziałeś, może działać w pewnych okolicznościach. Na przykład działa to idealnie w mojej sytuacji, w której mam JS warunkowo ukrywający elementy, który następnie dodaje style w
wierszu,
1
No cóż, myślę, że to działa :) Jestem po prostu idealistą i lubię podkreślać, gdzie rzeczy nie są najlepsze, ważne jest, aby móc odróżnić, co jest „hacky”, a co nie, ponieważ czyni nas wszystkich lepszymi programistami.
dudewad
Tak, słyszę, zgadzam się, że to rozwiązanie nie powinno być używane jako jedyne rozwiązanie CSS dla zapytania OP, myślę, że działa to bardzo dobrze w połączeniu z JS.
doz87
Możesz także użyć klasy CSS do ukrycia elementów (zamiast stylu wbudowanego). W takim przypadku możesz równie dobrze zanegować selektor dla tej klasy ukrywania. To zawsze wybiera to samo, co jest ukryte, ponieważ oba są ustawiane przez tę samą klasę CSS. Twoja odpowiedź idzie więc we właściwym kierunku, ale nie wystarczająco daleko. :-)
jgo
8

Jeśli możesz używać stylów wbudowanych, możesz to zrobić wyłącznie za pomocą CSS.

Używam tego do wykonywania CSS na następnym elemencie, gdy poprzedni jest widoczny:

div [style = 'display: block;'] + table {
  filtr: rozmycie (3px);
}
Alex Grande
źródło
1
[style*='display: block']display: block !important;<div style="display: block">
Zmieniłbym
U mnie działa w pliku css takim jak ten .btn-group > .btn.d-none + .btn(używanym do grup wejściowych bootstrapa "
Jean-Charbel VANNIER
7

Myślę, że nie można wybrać według wartości css (wyświetlacz)

edytować:

moim zdaniem sensowne byłoby użycie tu trochę jquery:

$('#your_container > div:visible:last').addClass('last-visible-div');
Guillaume86
źródło
6

Czyste rozwiązanie JS (np. Gdy nie używasz jQuery lub innego frameworka do innych rzeczy i nie chcesz tego ściągać tylko do tego zadania):

<div>A</div>
<div>B</div>  
<div>C</div>  
<div style="display:none">D</div>
<div style="display:none">E</div>    

<script>
var divs = document.getElementsByTagName('div');
var last;

if (divs) {
    for (var i = 0; i < divs.length; i++) {
        if (divs[i].style.display != 'none') {
            last = divs[i];           
        }
    }
}

if (last) {
    last.style.background = 'red';
}
</script>

http://jsfiddle.net/uEeaA/90/

pantera
źródło
Dzięki za fragment, jedyną odpowiedź spoza jQuery! Jednak to nie działa, gdy masz wiele elementów nadrzędnych do zastosowania do: jsfiddle.net/uEeaA/100 - czy możesz pomóc mi zbudować rozwiązanie dla innych, które działa? Potrzebuję tego, inni tego potrzebują, więc proszę o pomoc :)
mnsth
Zdaję sobie sprawę, że to stary wątek, ale dla przyszłych odwiedzających możesz zrobić coś podobnego do jsfiddle.net/uEeaA/103
xec,
Chciałem zagłosować w górę, po prostu b / c upuściłeś jQuery - dobrze. Moją jedyną skargą jest to, że element div można ukryć na wiele sposobów, nie tylko na podstawie parametru stylu. Naprawdę szybko: [1] szerokość i wysokość można ustawić na 0, [2] skala transformacji może wynosić 0, [3] i możemy ją umieścić poza widocznym obszarem.
Markus
4

Próbować

div: not ([style * = "display: none"])

Tyler Wayne
źródło
2

w inny sposób możesz to zrobić za pomocą javascript, w Jquery możesz użyć czegoś takiego jak:

$('div:visible').last()

* ponownie zredagowane

eveevans
źródło
2

Nie jest to możliwe w przypadku CSS, jednak można to zrobić za pomocą jQuery.

JSFIDDLE DEMO

jQuery:

$('li').not(':hidden').last().addClass("red");

HTML:

<ul>
        <li>Item 1</li>
        <li>Item 2</li>
        <li>Item 3</li>
        <li class="hideme">Item 4</li>    
</ul>

CSS:

.hideme {
    display:none;
}

.red {
    color: red;
}

jQuery (poprzednie rozwiązanie):

var $items = $($("li").get().reverse());

$items.each(function() {

    if ($(this).css("display") != "none") {
        $(this).addClass("red");
        return false;
    }

});
martynas
źródło
3
To dużo jQuery dla $('li:visible:last').addClass('red').
Alex
Co? $('li').not(':hidden').last().addClass("red");
martynas
0

Jeśli nie potrzebujesz już ukrytych elementów, po prostu użyj element.remove()zamiast element.style.display = 'none';.

Masoud Shariati
źródło
-6

To zadziałało dla mnie.

.alert:not(:first-child){
    margin: 30px;
}
kmukku
źródło
3
nie odpowiadasz na pytanie
Serginho