使用 jQuery on() 和 off() 切换 eventListener

Toggle eventListener using jQuery on() & off()

提问人:DCM CODING 提问时间:8/8/2023 最后编辑:Kiran ShahiDCM CODING 更新时间:8/8/2023 访问量:53

问:

我有一个 JavaScript 代码片段“代码片段 1 - 在用户触摸交互上播放通过 Ajax 加载的 html 视频”,它使用 jQuery 方法附加事件侦听器。我需要能够打开和关闭事件侦听器,或者删除并重新绑定它们。我遇到的问题是该方法继续调用该函数(播放页面上的所有视频)每个用户交互。on('touchstart')on('touchstart')

我需要事件侦听器在初始触摸交互时调用函数,然后禁用,直到ajax加载更多内容“视频”。在每次 Ajax 成功之后,我想重新绑定/重新添加事件 Listener,以便该函数再次工作。

代码片段 1

function videoEvents2() {
    Object.defineProperty(HTMLMediaElement.prototype, 'playing', {
        get: function() {
            return !!(this.currentTime > 0 && !this.paused && !this.ended && this.readyState > 2);
        }
    });

    $(document).on('click', 'body', playVideoOnLowPower);
    $(document).on('touchstart', 'body', playVideoOnLowPower);

    function playVideoOnLowPower() {
        try {
            const videoElements = document.querySelectorAll("video");
            for (i = 0; i < videoElements.length; i++) {
                if (videoElements[i].playing) {
                    // video is already playing so do nothing
                    console.log('Playing');
                } else {
                    // video is not playing so play video now
                    videoElements[i].play();
                    console.log('Not Playing');
                }
            }
        } catch (err) {
            console.log(err);
        }
    }
}

我已经尝试了以下解决方案,但没有成功。

尝试 1.将 Boolean 属性添加到 eventlistener,但它没有提供所需的结果。Boolean 属性只允许函数执行一次。{once: true}

尝试 2.我为 eventlistener 使用了 instead 而不是方法,但它提供了与one()on(){once : true}

尝试 3.我尝试了 & 方法,将 eventListeners 重新格式化为“请参阅本段下方的代码片段”,但是“removeEventListener”方法会立即执行,而不是在调用函数时执行。document.body.addEventListenerdocument.body.removeEventListener

document.body.addEventListener("click", playVideoOnLowPower, {
    once: true
});
document.body.addEventListener("touchstart", playVideoOnLowPower, {
    once: true
});

function dsdvideoEvents3 {
    document.body.removeEventListener("click", playVideoOnLowPower, {
        once: true
    });
    document.body.removeEventListener("touchstart", playVideoOnLowPower, {
        once: true
    });
}

尝试 4.我目前正在研究更多的布尔属性、Unbind 和 Rebind 方法、Delegation Methods、SetTimOut 和 SetInterval 方法,但我没有取得任何成功。

javascript jquery ajax dom addeventlistener

评论

2赞 Jaromanda X 8/8/2023
请检查您的问题的格式,它目前采用的格式称为“狗早餐”
0赞 DCM CODING 8/8/2023
@JaromandaX 哈哈狗早餐!我是新手,希望能好起来.从本质上讲,我需要一种方法在事件侦听器调用所需函数后将其删除。然后,我需要在 Ajax 调用加载更多元素后重新绑定事件侦听器,以便可以再次调用函数。

答:

1赞 Kiran Shahi 8/8/2023 #1

创建一个保存单击计数的标志,例如,我在这里创建了它,并在您调用时增加它,并在成功时将其重置为 0。还要检查方法中的值,如果它大于 0,则返回而不执行任何操作,否则执行您的逻辑。请参阅以下示例。var clickCount = 0;playVideoOnLowPower()ajaxCallclickCountplayVideoOnLowPower

var clickCount = 0;

Object.defineProperty(HTMLMediaElement.prototype, 'playing', {
  get: function() {
    return !!(this.currentTime > 0 && !this.paused && !this.ended && this.readyState > 2);
  }
});

document.body.addEventListener("click", playVideoOnLowPower);
document.body.addEventListener("touchstart", playVideoOnLowPower);

function playVideoOnLowPower() {
  try {
    if (clickCount > 0) {
      return;
    }
    clickCount = 1;
    const videoElements = document.querySelectorAll("video");
    for (i = 0; i < videoElements.length; i++) {
      if (videoElements[i].playing) {
        // video is already playing so do nothing
        console.log('Playing');
      } else {
        // video is not playing so play video now
        videoElements[i].play();
        console.log('Not Playing');
      }
    }
  } catch (err) {
    console.log(err);
  }
}

$("#getVideo").off("click").on("click", function() {
  getVideo()
});

function getVideo() {
  $.ajax({
    url: 'https://dummyjson.com/http/200/mov_bbb.mp4',
    success: function(data) {
      if (data.status == 200) {
        var videoHtml = `<video width="400" controls>
                           <source src="https://www.w3schools.com/html/${data.message}" type="video/mp4">
                       </video>`;
      }
      $('#main2').append(videoHtml);
      videoEvents();
      clickCount = 0;
    }
  });

}

function videoEvents() {
  $("video").on('play', function() {
    $(this).prop('muted', false);
  });

  $("video").on('pause', function() {
    $(this).prop('muted', true);
  });

  $("video").on('ended', function() {
    $(this).prop('muted', true);
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="main2"></div>
<button id="getVideo">Add next video</button>

评论

0赞 DCM CODING 8/8/2023
@AlberEinstein这对我不起作用。初始单击会播放视频,但是在ajax调用之后,函数不会再次调用。在上面的示例中,这正是我希望它的工作方式。
0赞 Kiran Shahi 8/8/2023
@DCMCODING给我看你的代码。或者正确检查每个步骤。我的代码中有 4 个新东西。在第 1 行、第 14 行、第 17 行和第 49 行var clickCount = 0;if (clickCount > 0) { return; }clickCount = 1;clickCount = 0;
0赞 DCM CODING 8/8/2023
@AlberEinstein我复制并粘贴了您在触摸时播放视频的代码片段,因此这是完全匹配的。我能看到的唯一区别是ajax调用。如何在评论中显示我的代码?
0赞 Kiran Shahi 8/8/2023
ajax调用成功后,您需要重置计数,这就是您需要做的clickCount = 0;
0赞 DCM CODING 8/8/2023
@AlberEinstein已经添加的。我不确定我做错了什么。这就是ajax调用的样子 $.ajax({ url: 'randomurlhere.com'+step, success: function (data) { step++; $('main2').append(data); loading = false; dsdvideoEvents (); clickCount = 0; }, dataType: 'html' });