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

Przechwytywanie zmian klas ze slidera

Object Storage Arubacloud
+2 głosów
145 wizyt
pytanie zadane 22 kwietnia w JavaScript przez batmat1903 Nowicjusz (140 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 (254,260 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 Nowicjusz (140 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 (21,730 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 Nowicjusz (140 p.)
Hej! Dzięki za odpowiedź. Chętnie spróbuje z tym kodem aby poćwiczyć MutationObserver
komentarz 24 kwietnia przez VBService Ekspert (254,260 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 Nowicjusz (140 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 138 wizyt
pytanie zadane 7 kwietnia 2021 w HTML i CSS przez Nearr Obywatel (1,890 p.)
0 głosów
2 odpowiedzi 333 wizyt
pytanie zadane 28 czerwca 2015 w Nasze projekty przez eliminati007 Nowicjusz (220 p.)
–1 głos
1 odpowiedź 170 wizyt
pytanie zadane 29 czerwca 2016 w JavaScript przez Rafał Michalik 1 Początkujący (490 p.)

92,619 zapytań

141,468 odpowiedzi

319,789 komentarzy

62,002 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.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...