javascriptradio-groupsemantic-markupevent-delegationdeselect

javascript removing element style after clicking other


I'm trying to remove attribute "selected" from span element when other span element (not the same div) is clicked div1 span swatch clicked and another div1 span swatch clicked

How to remove attribute "selected" of span element in div_bottom1 while div1 another span is selected?

window.addEventListener('DOMContentLoaded', () => {
      const div1 = document.getElementById('div1');
      div1.addEventListener('click', (e) => {
        const div1span = e.target.closest('span.swatch');
        if (!div1span) return;
        const dj = document.getElementById('div_bottom1');
        const djp = document.getElementById('div_bottom2');
        const dd = document.getElementById('div_bottom3');

        if (div1span.matches('.div1swatch')) {
          const clodj = dj.closest('span.selected');
          const clodd = dd.closest('span.selected');
          clodj.removeProperty('selected');
          clodd.removeProperty('selected');
        }
      });
<div id="attribute_pa_wersja-okleiny" class="tawcvs-swatches oss-" data-attribute_name="attribute_pa_wersja-okleiny">
  <span class="swatch swatch-image swatch-dekor-jednobarwny selected" data-value="dekor-jednobarwny">
        <span class="swatch__tooltip"></span>
  <span class="swatches_image-container"><img src="standard.jpg" alt="dekory jednobarwne"></span>
  </span>
  <span class="swatch swatch-image swatch-dekor-jednobarwny-premium" data-value="dekor-jednobarwny-premium">
        <span class="swatch__tooltip"></span>
  <span class="swatches_image-container"><img src="premium.jpg" alt="dekory jednobarwne premium"></span>
  </span><span class="swatch swatch-image swatch-dekor-drewnopodobny" data-value="dekor-drewnopodobny">
        <span class="swatch__tooltip"></span>
  <span class="swatches_image-container"><img src="orzech-nicea.jpg" alt="dekory drewnopodobne"></span>
  </span>
</div>
<div id="attribute_pa_dekor-jednobarwny" class="tawcvs-swatches oss-" data-attribute_name="attribute_pa_dekor-jednobarwny">
  <span class="swatch swatch-image swatch-bialy selected" data-value="bialy">
        <span class="swatch__tooltip"></span>
  <span class="swatches_image-container"><img src="bialy-150x150-2.jpg" alt="biały"></span>
  </span><span class="swatch swatch-image swatch-czarny" data-value="czarny">
        <span class="swatch__tooltip"></span>
  <span class="swatches_image-container"><img src="AR_16_9-150x150-1.webp" alt="czarny"></span>
  </span>
</div>
<div id="attribute_pa_dekor-jednobarwny-premium" class="tawcvs-swatches oss-" data-attribute_name="attribute_pa_dekor-jednobarwny-premium">
  <span class="swatch swatch-image swatch-bialy-polysk" data-value="bialy-polysk">
        <span class="swatch__tooltip"></span>
  <span class="swatches_image-container"><img src="bialy-150x150-1.jpg" alt="biały połysk"></span>
  </span>
  <span class="swatch swatch-image swatch-burgundowy selected" data-value="burgundowy">
        <span class="swatch__tooltip"></span>
  <span class="swatches_image-container"><img src="burgundowy-150x150-1.webp" alt="burgundowy"></span>
  </span>
  <span class="swatch swatch-image swatch-czarny" data-value="czarny">
        <span class="swatch__tooltip"></span>
  <span class="swatches_image-container"><img src="czarny-polysk-150x150-1.webp" alt="czarny połysk"></span>
  </span>
  <span class="swatch swatch-image swatch-kaszmir-matowy" data-value="kaszmir-matowy">
        <span class="swatch__tooltip"></span>
  <span class="swatches_image-container"><img src="kaszmir-matowy-150x150-1.webp" alt="kaszmir matowy"></span>
  </span>
</div>

<script type="text/javascript">
   window.addEventListener('DOMContentLoaded',() => {
      const div1 = document.getElementById('div1');
         div1.addEventListener('click', (e) => {
            const div1span = e.target.closest('span.swatch');
            if (!div1span) return;
            const dj = document.getElementById('div_bottom1');
            const djp = document.getElementById('div_bottom2');
            const dd = document.getElementById('div_bottom3');
   
         if (div1span.matches('.div1swatch')) {
            const clodj = dj.closest('span.selected');
            const clodd = dd.closest('span.selected');
            clodj.removeProperty('selected');
            clodd.removeProperty('selected');
         }
   });
</script>

It works till getting div1span.matches('.div1swatch') and then:

"Uncaught TypeError: Cannot read properties of null" error

div 2-4 are separate divs outside div1 and have style.display = "none"; set while div1span is switched

Clicking on div1span sets style.display = "none"; to div_bottom2 and div_bottom3.

Clicking on div2span sets style.display = "none"; to div_bottom1 and div_bottom3

Clicking on div3span sets style.display = "none"; to div_bottom1 and div_bottom2

Is it related?

What I'm doing wrong? I'm javascript newbie, coding in php + html so far

html javascript


Solution

  • <script>
          document.getElementById("swatches")
         .addEventListener("click",function(ev) {
            var element = ev.target.closest(".swatch");
            var selectedSwatches = document.querySelectorAll(".selected");
            selectedSwatches.forEach(function (swatch) {
              swatch.classList.remove("selected");
            });
            if (element) {
              element.classList.toggle("selected");
            }
          });
        </script>
    
    <!-- language: lang-css -->
    
        <style>
        .row {
          display: flex;
          margin-bottom: 1rem;
          gap: 1rem;
        }
    
        .swatch {
          display: inline-flex;
          width: 3rem;
          background:red;
          aspect-ratio: 1;
          cursor: pointer;
          &.selected {
            border-color: #0bf;
            &::after {
              margin: auto;
              content: "✓";
            }
          }
        }
    
        </style>
    
    
    
    <!-- language: lang-html -->
    
        <!DOCTYPE html>
        <html>
        <body>
    
        <h2>JavaScript addEventListener()</h2>
    
        <p>This example uses the addEventListener() method to attach a click event to a button.</p>
    
        <button id="myBtn">Try it</button>
              <div id="swatches">
          <div class="row">
            <div class="swatch"></div>
            <div class="swatch"></div>
            <div class="swatch"></div>
          </div>
          <div class="row">
            <div class="swatch"></div>
            <div class="swatch"></div>
            <div class="swatch"></div>
            <div class="swatch"></div>
          </div>
        </div>
        </body>
        </html>