Event trigger on a class change

前端 未结 3 1475
别跟我提以往
别跟我提以往 2020-11-30 04:44

I\'d like my event to be triggered when a div tag containing a trigger class is changed.

I have no idea how to make

相关标签:
3条回答
  • 2020-11-30 05:28

    Here's a simple, basic example on how to trigger a callback on Class attribute change
    MutationObserver API

    const attrObserver = new MutationObserver((mutations) => {
      mutations.forEach(mu => {
        if (mu.type !== "attributes" && mu.attributeName !== "class") return;
        console.log("class was modified!");
      });
    });
    
    const ELS_test = document.querySelectorAll(".test");
    ELS_test.forEach(el => attrObserver.observe(el, {attributes: true}));
    
    
    // Example of Buttons toggling several .test classNames
    document.querySelectorAll(".btn").forEach(btn => {
      btn.addEventListener("click", () => ELS_test.forEach(el => el.classList.toggle(btn.dataset.class)));
    });
    .blue {background: blue;}
    .gold {color: gold;}
    <div class="test">TEST DIV</div>
    <button class="btn" data-class="blue">RED BG</button>
    <button class="btn" data-class="gold">GOLD COLOR</button>

    0 讨论(0)
  • 2020-11-30 05:29

    The future is here, and you can use the MutationObserver interface to watch for a specific class change.

    let targetNode = document.getElementById('test')
    
    function workOnClassAdd() {
        alert("I'm triggered when the class is added")
    }
    
    function workOnClassRemoval() {
        alert("I'm triggered when the class is removed")
    }
    
    // watch for a specific class change
    let classWatcher = new ClassWatcher(targetNode, 'trigger', workOnClassAdd, workOnClassRemoval)
    
    // tests:
    targetNode.classList.add('trigger') // triggers workOnClassAdd callback
    targetNode.classList.add('trigger') // won't trigger (class is already exist)
    targetNode.classList.add('another-class') // won't trigger (class is not watched)
    targetNode.classList.remove('trigger') // triggers workOnClassRemoval callback
    targetNode.classList.remove('trigger') // won't trigger (class was already removed)
    targetNode.setAttribute('disabled', true) // won't trigger (the class is unchanged)
    

    I wrapped MutationObserver with a simple class:

    class ClassWatcher {
    
        constructor(targetNode, classToWatch, classAddedCallback, classRemovedCallback) {
            this.targetNode = targetNode
            this.classToWatch = classToWatch
            this.classAddedCallback = classAddedCallback
            this.classRemovedCallback = classRemovedCallback
            this.observer = null
            this.lastClassState = targetNode.classList.contains(this.classToWatch)
    
            this.init()
        }
    
        init() {
            this.observer = new MutationObserver(this.mutationCallback)
            this.observe()
        }
    
        observe() {
            this.observer.observe(this.targetNode, { attributes: true })
        }
    
        disconnect() {
            this.observer.disconnect()
        }
    
        mutationCallback = mutationsList => {
            for(let mutation of mutationsList) {
                if (mutation.type === 'attributes' && mutation.attributeName === 'class') {
                    let currentClassState = mutation.target.classList.contains(this.classToWatch)
                    if(this.lastClassState !== currentClassState) {
                        this.lastClassState = currentClassState
                        if(currentClassState) {
                            this.classAddedCallback()
                        }
                        else {
                            this.classRemovedCallback()
                        }
                    }
                }
            }
        }
    }
    
    0 讨论(0)
  • 2020-11-30 05:34

    Well there were mutation events, but they were deprecated and the future there will be Mutation Observers, but they will not be fully supported for a long time. So what can you do in the mean time?

    You can use a timer to check the element.

    function addClassNameListener(elemId, callback) {
        var elem = document.getElementById(elemId);
        var lastClassName = elem.className;
        window.setInterval( function() {   
           var className = elem.className;
            if (className !== lastClassName) {
                callback();   
                lastClassName = className;
            }
        },10);
    }
    

    Running example: jsFiddle

    0 讨论(0)
提交回复
热议问题