Javascript 类更改的事件触发器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10612024/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 02:09:06  来源:igfitidea点击:

Event trigger on a class change

javascript

提问by Patrick Jeon

I'd like my event to be triggeredwhen a div tag containing a triggerclass is changed.

我希望在更改包含触发器类的 div 标签时触发我的事件。

I have no idea how to make it listen to the class' adding event.

我不知道如何让它听班级的添加事件。

<div id="test">test</div>

<script type="text/javascript">
    document.getElementById.setAttribute("class", "trigger");

    function workOnClassAdd() {
       alert("I'm triggered");
    }
</script>

采纳答案by epascarello

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

运行示例:jsFiddle

回答by TechWisdom

The future is here, and you can use the MutationObserverinterface to watch for a specificclass change.

未来就在这里,您可以使用MutationObserver接口来监视特定的类更改。

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 MutationObserverwith a simple class:

我用一个简单的类包装了MutationObserver

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()
                    }
                }
            }
        }
    }
}