skip to Main Content

Let’s say that I have two span elements. Class is changing width "selected" based on which one is selected. I just need to know when span2 is selected or not.

<span class="swatch swatch-image span1">
<span class="swatch swatch-image span2 selected">

I’m trying to listen which one is selected (which one has class "selected") and then show or don’t show div in other place. Is it possible?

I’ve tried this way:

let targetNode = document.getElementsByClassName('swatch swatch-image span2 selected');

const config = { attributes: true, childList: false, subtree: false, attributeFilter: ['class'] };

const callback = function(mutationsList, observer) {
    for (let mutation of mutationsList) {
        if (mutation.attributeName === "class") {
            var classList = mutation.target.className;
            if(/red/.exec(classList).length > 0) {
                console.log('Found match');
            }
        }
    }
};

const observer = new MutationObserver(callback);

observer.observe(targetNode, config);

observer.disconnect();

Is MutationObserver is proper way to listen which span is selected? I’m not familiar with javascript, do I need to call MutationObserver somehow after constructing code?

2

Answers


  1. Chosen as BEST ANSWER

    Alright, @mplungjan answer works like a charm. It's really nice and clean code. Thank you. But let's say I was able to add id of div which is parent of span.swatch but I need to find nearest of a div which I was trying to hide/show because I need to show and hide whole tr element:

    window.addEventListener('DOMContentLoaded',() => { // when page has loaded
                const container = document.getElementById('someContainer'); // change as needed 
                const container2 = document.getElementById('someOtherContainer'); //looking for div of tr element
                const tr = container2.closest('tr'); //looking nearest tr element
                if (!tr) return;
                tr.style.display = "none"; //hide on page load
                container.addEventListener('click', (e) => {
                const tgt = e.target.closest('span.swatch');
                if (!tgt) return; // not a swatch
    

    Should I use:

    document.tr.display.block = !tgt.matches('.span2'');
    

    It's not working because of syntax I think...

    And more... display.block is not really want I'm looking for. I would like to delete style.display = "none" at all from tr element


  2. Find the closest container enclosing the spans and delegate

    window.addEventListener('DOMContentLoaded',() => { // when page has loaded
      const container = document.getElementById('someContainer'); // change as needed 
      container.addEventListener('click', (e) => {
        const tgt = e.target.closest('span.swatch');
        if (!tgt) return; // not a swatch
        console.log(tgt.textContent, 'clicked')
        document.getElementById('showWhenSpan2').hidden = !tgt.matches('.span2')
      });
    
    // somewhere else out of your control
      document.addEventListener('click', (e) => {
        const tgt = e.target.closest('span.swatch');
        if (!tgt) return; // not a swatch
        document.querySelectorAll('span.swatch').forEach(span => span.classList.toggle('selected',span===tgt))
      });
    
    
    
    });
    .selected { border: 1px solid red; }
    <div id="someContainer">
    ...
    
    <span class="swatch swatch-image span1 selected">Span 1</span>
    <span class="swatch swatch-image span2">Span 2</span>
    
    
    ...
    </div>
    
    <div id="showWhenSpan2" hidden>Shown when span 2 is clicked</div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search