初始化通过 Ajax 附加的视频元素的 jQuery 和 JavaScript

Initialize jQuery & JavaScript for Video Elements Appended via Ajax

提问人:DCM CODING 提问时间:8/4/2023 最后编辑:mplungjanDCM CODING 更新时间:8/7/2023 访问量:102

问:

我正在使用 ajax 将视频元素附加到网页中。在附加了一个新视频后,我注意到一些JavaScript和jQuery没有初始化。

我需要 3 个代码片段协同工作。

1st. Ajax 调用的代码片段 2nd. 播放后取消静音视频的代码片段 3rd. 代码片段在网页上的任何位置首次初始单击或触摸手势后播放视频。

第一个代码片段以下代码片段用于在用户滚动页面后通过 Ajax 调用追加视频。

var step = 1;
var loading = false;

$(window).scroll(function() {
    if ($(window).scrollTop() >= $(document).height() - $(window).height() - 1900) {
        if (loading === false) {
            loading = true;
            $.ajax({
                url: 'HTTPS://ENTER URL HERE.COM' + step,
                success: function(data) {
                    step++;
                    $('main2').append(data);
                    loading = false;
                },
                dataType: 'html'
            });
        }
    }
});

我希望附加的视频在单击或触摸网页后自动开始播放,并在开始播放后取消静音。

我尝试了一些小的调整,但未能成功地将其与“通过ajax附加的视频”一起使用,但是当视频在初始加载期间已经在页面上时,这些代码可以完美地协同工作。

我需要下面的两个代码片段才能在ajax之后工作。

第二个代码片段(用于在启动后使用自动播放属性取消静音html视频)

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

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

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

第 3 个代码片段(用于通过单击或触摸手势在网页上播放 html 视频。

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

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

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

更新:

我在 ajax 中添加的附加功能将成功工作者称为我的魅力。我现在遇到的唯一问题是在上面列出的第 3 个代码片段中,有一个附加到事件侦听器的布尔属性,该属性仅触发并调用该函数一次。 如果我删除 Boolean 属性,则事件侦听器会在每次单击或触摸启动事件时触发,并连续调用分配的函数。{ once: true}

我需要事件侦听器触发一次,并且“在每次ajax调用之后”只调用分配的函数一次

javascript html jquery ajax dom

评论

0赞 mplungjan 8/7/2023
我不明白您在我从评论中更新您的问题的文本中询问的功能。什么是预期行为,什么是实际行为?
0赞 DCM CODING 8/7/2023
@mplungjan “Code Snippet 3” 在 CLICK 或 Touchstart 事件之后播放所有 html 视频。在第一个/初始 Click 或 Touchstart 事件之后,将删除事件侦听器。我需要能够重新绑定事件侦听器。我尝试了下面的代码,但没有成功。' function dsdvideoEvents2() { document.body.addEventListener(“click”, playVideoOnLowPower, { once: true }); document.body.addEventListener(“touchstart”, playVideoOnLowPower, { once: true });
0赞 mplungjan 8/7/2023
但为什么要删除该事件呢?这是我的问题。此外,将信息添加到问题中,而不是注释
0赞 DCM CODING 8/7/2023
我想删除该事件,因为我的网站上有一个无限的滚动效果,当用户向下滚动页面时,它通过ajax加载更多的html视频。在 ajax 调用呈现新的 html 视频后,“代码片段 3”中的第一个 Click or Touch Start 事件会立即启动页面上当前的所有视频,而我实现的另一个 JS 代码片段会在所有视频启动后暂停它们,然后删除 src 并重新加载 html 视频以停止缓冲。这个技巧适用于自动播放html视频,而不会被静音,并且在低功耗/省电模式下适用于设备。
0赞 DCM CODING 8/7/2023
@mplungjan 因此,正因为如此,每次 ajax 调用将新的 html 视频集呈现到页面时,我都需要运行“代码片段 3”,以便视频将在用户滚动时继续自动播放,而不会将视频静音。

答:

-1赞 Kiran Shahi 8/4/2023 #1

正如你提到的,你的第一个代码片段是附加新视频。因此,我假设只是一个拼写错误,并且是元素的 ID(也可以是类)。main2

因为,你通过ajax绑定了视频,但在ajax成功的情况下,你只是将视频绑定到它,而你没有将事件重新绑定到它。它不会自动具有您之前绑定的事件侦听器。因此,您需要在 ajax 成功后重新绑定事件。$('main2')$('main2').append(data);

请参阅以下示例:

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

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

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


$.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()
  }
});


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>

评论

1赞 mplungjan 8/4/2023
如果 main2(除非有标签,否则它不是有效的选择器)是静态的,那么代码应该可以工作,因为每次点击都会读取所有视频标签<main2>
0赞 mplungjan 8/4/2023
如果 main2 是静态容器,则仍然不需要重新绑定。授权将是一个更好的解决方案
0赞 mplungjan 8/6/2023
你在这里指的是谁?只有你和我,我们都被否决了。如果你是说我,那么是的,当然。我肯定会投票反对从 168,348 代表到 168,356,因为这非常重要;)
0赞 DCM CODING 8/7/2023
@AlbertEinstein & @mplungjan 我在ajax调用成功期间添加了一个额外的函数“dsdvideoEvents”,该函数重新绑定事件(见下文)' $.ajax({ url: 'HTTPS://ENTER URL HERE.COM' + step, success: function(data) { step++; $('main2').append(data); loading = false; dsdvideoEvents(); }, dataType: 'html' });} } });' ' 函数 dsdvideoEvents (){ videoEvents(); videoEvents2();
0赞 DCM CODING 8/7/2023
@AlbertEinstein & @mplungjan 我在 ajax 中添加的附加函数调用成功工作者对我来说就像一个魅力,我现在唯一的问题是在上面列出的第 3 个代码片段中,有一个布尔属性“{ once: true}”附加到事件侦听器,它只触发并调用函数一次。如果我删除 Boolean 属性,则事件侦听器会在每次单击或触摸启动事件时触发,并连续调用分配的函数。(((我需要事件侦听器触发一次,并且只在“每次ajax调用后”调用分配的函数一次)))