简体   繁体   English

addEventListener 点击在轻弹中被多次触发 slider

[英]addEventListener click being fired multiple times within a flickity slider

I'm using flickity , which is a bit irrelevant, and on first load and for each 'change' of a slide I'll search the slide for any videos that have audio enabled (set as a data attribute via PHP via CMS) and then it'll autoplay the video and if the user clicks an unmute button then it'll unmute and vice versa.我正在使用flickity ,这有点无关紧要,并且在第一次加载和幻灯片的每个“更改”时,我将在幻灯片中搜索任何启用音频的视频(通过 CMS 通过 PHP 设置为数据属性)和然后它会自动播放视频,如果用户单击取消静音按钮,它将取消静音,反之亦然。

This worked fine going forward but going back once the mute button is clicked, the eventListener for the click will fire every time it's existed.这在前进时工作得很好,但是一旦单击静音按钮就会返回,每次单击的 eventListener 都会在它存在时触发。 I'm guessing the eventListener is being added to each time but I can't work out how to remove the eventListener.我猜每次都会添加 eventListener,但我不知道如何删除 eventListener。

Any help on how to prevent the muteButton.addEventListener('click') from being fired more than once?关于如何防止muteButton.addEventListener('click')被多次触发的任何帮助?

//
playVideo = function(index) {
    var videos, video, muteButton = null, hasAudio = false;

    // Pause all other slide video content if it was playing
    flkty.cells.forEach(function(cell, i) {
        videos = cell.element.querySelectorAll('video.--autoplay');
        videos.forEach(function(video) {
            if (video !== null && typeof video !== 'undefined') {
                if (!video.paused) {
                    video.pause();
                }
            }
        });
    });

    // For current slide
    if (index == flkty.selectedIndex) {

        videos = flkty.selectedElement.querySelectorAll('video.--autoplay');
        muteButton = flkty.selectedElement.querySelector('a.button__mute');

        // If videos exist on the current slide
        if (videos.length) {
            videos.forEach(function(video, index) {
                if (video !== null && typeof video !== 'undefined') {
                    video.play();
                    if (muteButton !== null && typeof muteButton !== 'undefined' && index == 0) { // Only fire this once per video (as mute = mute all)
                        console.log(muteButton);
                        muteButton.addEventListener('click', function(e) {
                            e.preventDefault();
                            console.log('clicked'); // TOFIX; fires multiple times
                            muteVideo(videos, video, muteButton, true);
                        });
                    }
                }
                return;
            });
        }

    }

};
flkty.on('select', function(event, index) {
    if (index === 0) {
        playVideo(index);
        return false;
    }
});
flkty.on('change', function(index) {
    playVideo(index);
});

//
muteVideo = function(videos, video, muteButton, hasAudio) {
    console.log('hasAudio');
    if (videos.length > 1) {
        videos.forEach(function(video, index) {
            if (video.muted == true) {
                video.muted = false;
                if (index == 0) {
                    $(muteButton).text('mute');
                }
            } else {
                video.muted = true;
                if (index == 0) {
                    $(muteButton).text('unmute');
                }
            }
        });
    } else {
        if (video.muted == true) {
            $(muteButton).text('mute');
            video.muted = false;
        } else {
            $(muteButton).text('unmute');
            video.muted = true;
        }
    }
};

Just use removeEventListener() .只需使用removeEventListener()

To remove event handlers, the function specified with the addEventListener() method must be an external function.要删除事件处理程序,使用 addEventListener() 方法指定的 function 必须是外部 function。

Anonymous functions, like yours, will not work.像您这样的匿名函数将不起作用。

As for only attaching it once: Just set a flag to be checked before adding the eventhandler in the first place.至于只附加一次:只需在添加事件处理程序之前设置一个要检查的标志。

JohnnyAwesome's solution sounds good to me. JohnnyAwesome 的解决方案对我来说听起来不错。 If the playVideo routine is called more than once you are adding Events multiple times.如果 playVideo 例程被多次调用,您将多次添加事件。 In order to remove them use removeEventListener() like suggested为了删除它们,使用建议的removeEventListener()

If you have some Event bubbling going on - the e.preventDefault();如果您有一些事件冒泡 - e.preventDefault(); is not enough than you have to use e.stopPropagation();还不够,你必须使用e.stopPropagation(); or e.stopImmediatePropagation();e.stopImmediatePropagation(); . .

Don't use removeEventListener() in this case.在这种情况下不要使用removeEventListener() The real problem is that you are adding event listeners each time your playVideo() function is called.真正的问题是,每次playVideo() function 时,您都在添加事件侦听器。 So the problem you should solve is to make sure you only add the event listeners once , probably when the page initializes or something.所以你应该解决的问题是确保你只添加一次事件侦听器,可能是在页面初始化时或其他什么时候。

Here is what I would do:这是我要做的:

Extract the "add event listener code" into a separate function, addButtonListeners() by removing that piece of code from the playVideo() .通过从playVideo()中删除那段代码,将“添加事件侦听器代码”提取到单独的 function、 addButtonListeners() ) 中。 Then call the addButtonListeners() once when your page is loaded.然后在加载页面时调用addButtonListeners()一次。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM