• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Przechwytywanie zmian klas ze slidera

VPS Starter Arubacloud
+2 głosów
211 wizyt
pytanie zadane 22 kwietnia w JavaScript przez batmat1903 Początkujący (340 p.)

Witam wszystkich bardzo serdecznie. Jestem dość początkujący i utknąłem z jednym problemem. Niestety nie mogę dodać pełnego kodu, jednak objaśnię tutaj strukturę oraz zastosowane rozwiązania.

Korzystam ze slidera SplideJS.

Struktura wygląda mniej więcej tak:

<section>
<div class='city__table'>
<a href="#" data-city-link="miasto" > Nazwa miasta</a>
<a href="#" data-city-link="miasto" > Nazwa miasta</a>
<a href="#" data-city-link="miasto" > Nazwa miasta</a>
<a href="#" data-city-link="miasto" > Nazwa miasta</a>
</div>
<div class='city__table'>
<a href="#" data-city-link="miasto" > Nazwa miasta</a>
<a href="#" data-city-link="miasto" > Nazwa miasta</a>
<a href="#" data-city-link="miasto" > Nazwa miasta</a>
<a href="#" data-city-link="miasto" > Nazwa miasta</a>
</div>
<div>
<ul class='SplideJS'>
<li data-city-name> Tutaj zdjęcie miasta </li>
<li data-city-name> Tutaj zdjęcie miasta </li>
<li data-city-name> Tutaj zdjęcie miasta </li>
</ul>
</div>
</section>

Dwa pierwsze divy generowane są przez PHP (lista 40 miast podzielona na dwa divy po równo)
atrybut data-city-link posiada nazwę miasta pobraną z tablicy owych miast

Trzeci div zawiera slider (SplideJS) i zawiera zmieniające się zdjęcia co 4 sekundy, każdy element listy ma dopisany atrybut data-city-name, który jest identyczny z atrybutem data-city-link

Aktualnie widoczny slide otrzymuje ze SplideJS klasę "is-active".

Teraz mój problem:

Chciałbym w JS przechwycić aktualnie wyświetlony slajd, odczytać z niego atrybut data, odnaleźć w jednym z poprzednich divów ten sam atrybut data oraz nadać na czas widoczności slajdu inną klasę dla <a> o odpowiednim atrybucie data.

Próbowałem to wykonać za pomocą:

1. Pobrania wszystkich elementów poprzez querySelectorAll( poprzez klasę ). W pętli for spróbowałem ustawić MutationObserver korzystając stąd: Developer Mozilla
Niestety nic to nie dało - jest ogromne prawdopodobieństwo, że coś robiłem źle lub kompletnie nie zrozumiałem działania MutationObserver. Chciałem tutaj wkleić kod, jednak nerwy wygrały i usunąłem cały kod, pozostawiając jedynie pobranie elementów...

2. Nie znalazłem także żadnego eventu w addEventListener aby mógł pasować do mojego problemu.

Prosiłbym chociaż o nakierowanie mnie, abym mógł w jakiś sposób to rozwiązać.

2 odpowiedzi

+2 głosów
odpowiedź 23 kwietnia przez VBService Ekspert (255,840 p.)
edycja 23 kwietnia przez VBService

Użyj zdarzenia active z listy zdarzeń, które "oferuje" Splide.js.

active - Fired when the active slide is changed

var splide = new Splide('.splide').mount();
splide.on('active', function() {
  // do something
});

 

przykład użycia zdarzenia active z pomocą document.querySelector()

  document.addEventListener('DOMContentLoaded', function() {
    const splide = new Splide('.splide', { type:'loop', autoplay:true, interval:2000 }).mount();
    
    splide.on('active', function() {
      const active_slide_city_name = document.querySelector('.splide .is-active').dataset.cityName;
      const a_tag_city_link = document.querySelector(`.city__table a[data-city-link="${active_slide_city_name}"]`);
      
      try { 
        document.querySelector('.city__table a.active').classList.remove('active');
      } finally {
        a_tag_city_link.classList.add('active');
      }      
    });
  });

 

[ pełny kod przykładu on-line ]

<script src="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/js/splide.min.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@splidejs/splide@4.1.4/dist/css/splide.min.css">

<style>
  a.active {
    font-weight: bold;
    text-decoration: none;
    color: red;
  }
</style>

<section>
  <div class='city__table'>
    <a href="#" data-city-link="miasto1" > Nazwa miasta</a>
    <a href="#" data-city-link="miasto2" > Nazwa miasta</a>
    <a href="#" data-city-link="miasto3" > Nazwa miasta</a>
    <a href="#" data-city-link="miasto4" > Nazwa miasta</a>
  </div>
  <div class='city__table'>
    <a href="#" data-city-link="miasto5" > Nazwa miasta</a>
    <a href="#" data-city-link="miasto6" > Nazwa miasta</a>
    <a href="#" data-city-link="miasto7" > Nazwa miasta</a>
    <a href="#" data-city-link="miasto8" > Nazwa miasta</a>
  </div>
  <div class="splide">
    <div class="splide__track">
      <ul class="splide__list">
        <li data-city-name="miasto1" class="splide__slide">
          <img src="https://picsum.photos/id/169/600/362">
        </li>
        <li data-city-name="miasto2" class="splide__slide">
          <img src="https://picsum.photos/id/170/600/362">
        </li>
        <li data-city-name="miasto3" class="splide__slide">
          <img src="https://picsum.photos/id/171/600/362">
        </li>
        <li data-city-name="miasto6" class="splide__slide">
          <img src="https://picsum.photos/id/172/600/362">
        </li>       
      </ul>
    </div>
  </div>
</section>

<script>
  document.addEventListener('DOMContentLoaded', function() {
    const splide = new Splide('.splide', { type:'loop', autoplay:true, interval:2000 }).mount();
    
    splide.on('active', function() {
      const active_slide_city_name = document.querySelector('.splide .is-active').dataset.cityName;
      const a_tag_city_link = document.querySelector(`.city__table a[data-city-link="${active_slide_city_name}"]`);
      
      try { 
        document.querySelector('.city__table a.active').classList.remove('active');
      } finally {
        a_tag_city_link.classList.add('active');
      }      
    });
  });
</script>

 


 

W odniesieniu do slide component [ slide , Elements ]

  document.addEventListener('DOMContentLoaded', function() {
    const splide = new Splide('.splide', { type:'loop', autoplay:true, interval:2000 }).mount();

    splide.on('active', function() {
      // Pobieramy element slajdu na podstawie indeksu aktualnego slajdu
      const active_slide = splide.Components.Elements.slides[splide.index].dataset.cityName;
      const a_tag_city_link = document.querySelector(`.city__table a[data-city-link="${active_slide}"]`);

      try { 
        document.querySelector('.city__table a.active').classList.remove('active');
      } finally {
        a_tag_city_link.classList.add('active');
      }      
    });
  });

 

komentarz 24 kwietnia przez batmat1903 Początkujący (340 p.)
Hej! Dzięki za odpowiedź. Jakoś ominąłem to zdarzenie w dokumentacji. Jeszcze raz dzięki za odpowiedź i objaśnienie problemu!
+1 głos
odpowiedź 22 kwietnia przez overcq Pasjonat (22,150 p.)
edycja 22 kwietnia przez overcq

Coś w rodzaju:

const target = document.getElementsByClassName( "SplideJS" )[0];
function I_mo( mrs
, mo
){  for( const mr of mrs )
        if( mr.type === "attributes"
        && mr.target.parentNode === target
        && mr.target.classList.contains( "isActive" )
        )
        {   const city_name = mr.target.getAttribute( "data-city-name" );
            const es = document.getElementsByClassName( "city__table" );
            for( const div of es )
                for( const a of div.children )
                {   const city_link = a.getAttribute( "data-city-link" );
                    if( city_link === city_name )
                        a.classList.add( "active" );
                    else
                        a.classList.remove( "active" );
                }
        }
}
const mo = new MutationObserver( I_mo );
mo.observe( target
, { subtree: true
  , attributes: true
  , attributeFilter: [ "class" ]
  }
);

Ale nie sprawdzałem działania tego kodu.

komentarz 24 kwietnia przez batmat1903 Początkujący (340 p.)
Hej! Dzięki za odpowiedź. Chętnie spróbuje z tym kodem aby poćwiczyć MutationObserver
komentarz 24 kwietnia przez VBService Ekspert (255,840 p.)

a może MutationObserver użyć tylko jako trigger do "wywołania" i wykonania kodu, po wykryciu zmian (mutacji) w zadanym miejscu drzewa DOM

  document.addEventListener('DOMContentLoaded', function() {
    const splide = new Splide('.splide', { type:'loop', autoplay:true, interval:2000 }).mount();

    // Funkcja do obsługi mutacji w drzewie DOM
    const observer = new MutationObserver(function() {
      const active_slide = splide.Components.Elements.slides[splide.index].dataset.cityName;
      const a_tag_city_link = document.querySelector(`.city__table a[data-city-link="${active_slide}"]`);

      const activeLink = document.querySelector('.city__table a.active');
      activeLink && activeLink.classList.remove('active');
      a_tag_city_link.classList.add('active');
    });

    // Rozpoczęcie obserwacji mutacji w drzewie DOM
    observer.observe(document.querySelector('.splide .splide__list'), { attributes:true });
  });

 

komentarz 26 kwietnia przez batmat1903 Początkujący (340 p.)
Dzięki za odpowiedź. W teorii właśnie tak chciałem zbudować tą funkcję, ale po Twoim kodzie widzę, że źle się za to zabierałem. Ale za to zmotywowałeś mnie, żebym pobawił się tą funkcją i poznał ją o wiele bardziej :)

Podobne pytania

+1 głos
2 odpowiedzi 215 wizyt
pytanie zadane 7 kwietnia 2021 w HTML i CSS przez Nearr Obywatel (1,890 p.)
0 głosów
2 odpowiedzi 366 wizyt
pytanie zadane 28 czerwca 2015 w Nasze projekty przez eliminati007 Nowicjusz (220 p.)
–1 głos
1 odpowiedź 197 wizyt
pytanie zadane 29 czerwca 2016 w JavaScript przez Rafał Michalik 1 Początkujący (490 p.)

93,018 zapytań

141,982 odpowiedzi

321,283 komentarzy

62,365 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...