You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为Ajax动态追加的视频元素初始化jQuery与JavaScript的问题

Ajax追加视频后的事件绑定与单次触发解决方案

问题背景

滚动触发Ajax加载视频元素,页面初始加载的视频可正常触发播放/静音控制,但新追加的视频无法响应事件;同时点击/触摸事件要么仅触发一次,要么每次点击都重复触发,需要实现每次Ajax请求完成后,事件监听器可单次触发播放新视频。


问题分析

  1. 事件绑定失效:原视频的play/pause/ended事件直接绑定在初始DOM元素上,新追加的视频元素未被绑定事件,需要用事件委托处理动态生成的元素。
  2. 单次触发逻辑冲突:原代码{once: true}会让事件仅执行一次,但Ajax加载新视频后无法重新触发;移除该属性则每次点击都会重复执行播放函数,需要手动控制事件的绑定与移除。

解决方案

1. 修复视频静音控制的事件委托

将原有的视频事件绑定改为委托到父容器(main2),确保动态追加的视频也能触发事件,同时只操作当前触发事件的视频(避免影响全局所有视频):

// 替换原第2段代码
$('main2').on('play', 'video', function() {
    $(this).prop('muted', false);
});

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

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

2. 实现Ajax加载后单次触发的点击/触摸事件

重构播放函数与事件绑定逻辑,每次Ajax加载完成后重新绑定单次触发的事件,触发后自动移除监听器:

第一步:重构播放函数与事件绑定逻辑
// 保留原原型扩展,替换第3段代码的其余部分
Object.defineProperty(HTMLMediaElement.prototype, 'playing', {
    get: function() {
        return !!(this.currentTime > 0 && !this.paused && !this.ended && this.readyState > 2);
    }
});

function playVideoOnLowPower() {
    try {
        const videoElements = document.querySelectorAll("video");
        // 使用let声明循环变量,避免全局变量污染
        for (let i = 0; i < videoElements.length; i++) {
            if (!videoElements[i].playing) {
                videoElements[i].play();
                console.log('开始播放视频');
            } else {
                console.log('视频已在播放');
            }
        }
        // 触发后手动移除事件监听器,实现单次触发
        document.body.removeEventListener("click", playVideoOnLowPower);
        document.body.removeEventListener("touchstart", playVideoOnLowPower);
    } catch (err) {
        console.log(err);
    }
}

// 封装单次事件绑定函数
function bindPlayEventOnce() {
    // 不使用{once: true},改为手动移除
    document.body.addEventListener("click", playVideoOnLowPower);
    document.body.addEventListener("touchstart", playVideoOnLowPower);
}

// 页面初始加载时绑定第一次事件
bindPlayEventOnce();
第二步:修改Ajax回调,每次加载后重新绑定事件
// 修改原第1段代码的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;
                    // 每次加载新视频后,重新绑定单次触发的播放事件
                    bindPlayEventOnce();
                },
                dataType: 'html'
            });
        }
    }
});

逻辑说明

  • 事件委托:通过父容器main2监听子元素video的事件,动态追加的视频自动继承事件绑定。
  • 单次触发控制:每次Ajax加载后调用bindPlayEventOnce绑定事件,播放函数执行后手动移除监听器,确保每次仅触发一次,下次Ajax加载后重新绑定。
  • 变量优化:循环变量i改用let声明,避免全局变量污染导致的逻辑错误。

内容的提问来源于stack exchange,提问作者DCM CODING

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 03:05:56