【问题标题】:addEventListener click being fired multiple times within a flickity slideraddEventListener 点击在轻弹滑块内被多次触发
【发布时间】:2019-10-23 08:50:52
【问题描述】:

我正在使用flickity,这有点无关紧要,在第一次加载和幻灯片的每次“更改”时,我都会在幻灯片中搜索启用了音频的任何视频(通过设置为数据属性PHP 通过 CMS),然后它会自动播放视频,如果用户点击取消静音按钮,它就会取消静音,反之亦然。

这在前进时工作得很好,但是一旦点击静音按钮就会返回,每次点击的 eventListener 都会在它存在时触发。我猜每次都会添加 eventListener,但我不知道如何删除 eventListener。

有关如何防止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;
        }
    }
};

【问题讨论】:

  • 两种方法。您应该将“添加事件侦听器代码”提取到一个单独的函数中,并且只调用这个addMuteListener() 函数一次。也就是说,将其从playVideo() 中删除。或者使用变量来指示您是否添加了事件侦听器,并将 addEventListener 调用包装在 if 子句中
  • @MartinWickman 谢谢!我刚刚更新了我的代码以提高效率。你的评论还成立吗?

标签: javascript


【解决方案1】:

只需使用removeEventListener()

要删除事件处理程序,使用 addEventListener() 方法指定的函数必须是外部函数。

匿名函数(如您的函数)将不起作用。

至于只附加一次:只需在添加事件处理程序之前设置一个要检查的标志。

【讨论】:

  • 如果听众依赖于幻灯片是否有视频和静音按钮,我不确定它如何成为外部函数......
  • 您是指在playVideo() 函数之外还是videos.forEach 之外?
【解决方案2】:

在这种情况下不要使用removeEventListener()。真正的问题是每次调用playVideo() 函数时都在添加事件侦听器。所以你应该解决的问题是确保你只添加事件监听器一次,可能是在页面初始化的时候。

我会这样做:

通过从playVideo() 中删除那段代码,将“添加事件侦听器代码”提取到一个单独的函数addButtonListeners() 中。然后在加载页面时调用一次addButtonListeners()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-28
    • 1970-01-01
    • 1970-01-01
    • 2022-12-30
    相关资源
    最近更新 更多