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

嵌入YouTube视频30秒后显示领取奖励按钮问题求助

问题:YouTube视频观看满30秒后未显示Claim Reward按钮

我嵌入了YouTube视频,希望用户观看满30秒后显示Claim Reward按钮,后续逻辑交由Livewire处理。但目前观看满30秒后按钮仍未显示,请求帮助:

原代码

HTML部分

<div class="p-3">
    <div class="space-y-3">
        <h2 class="font-bold">{{$video->title}}</h2>
        <div class="relative rounded-lg overflow-hidden" style="padding-bottom: 56.25%;">
            <iframe id="videoFrame" class="absolute top-0 left-0 w-full h-full rounded-lg" src="https://www.youtube.com/embed/{{$video->embed_code}}" frameborder="0" allowfullscreen></iframe>
        </div>

        <div id="claimButton" style="display: none;">
            @if (!$claimed)
                <button wire:click="claimReward" class="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">
                    Claim Reward
                </button>
            @else
                <div class="mt-2 text-green-500">Reward claimed</div>
            @endif
        </div>

    </div>
</div>

JS部分

<script>
    // Initialize YouTube Player API
    var player;

    // Function to initialize the player
    function onYouTubeIframeAPIReady() {
        player = new YT.Player('videoFrame', {
            events: {
                'onStateChange': onPlayerStateChange
            }
        });
    }

    // Function to handle player state change
    function onPlayerStateChange(event) {
        if (event.data == YT.PlayerState.PLAYING) {
            // Video has started playing, start tracking time
            startTime = Date.now();
        } else if (event.data == YT.PlayerState.ENDED) {
            // Video has ended, check if user can claim reward
            checkWatchTime();
        }
    }

    // Function to check watch time and show the "Claim Reward" button
    function checkWatchTime() {
        const currentTime = Date.now();
        const elapsedTime = (currentTime - startTime) / 1000; // Convert to seconds

        if (elapsedTime >= 30 && !claimed) {
            document.getElementById('claimButton').style.display = 'block';
        }
    }
</script>

<script src="https://www.youtube.com/iframe_api"></script>

问题分析

  1. YouTube API未启用:iframe的URL缺少enablejsapi=1参数,导致Player API无法正常控制视频,状态监听失效。
  2. 变量作用域错误:startTime未声明为全局变量,在checkWatchTime函数中无法访问,会引发未定义错误。
  3. Livewire变量无法直接访问:JS中的!claimed是PHP后端变量,前端JS无法直接读取,需要将其传递到前端。
  4. 检查逻辑不完善:仅在视频结束时检查时长,用户未看完视频但已观看满30秒时,不会触发按钮显示;且用系统时间差计算时长不准确(用户可能暂停、快进)。

修复方案

步骤1:修改iframe的src,启用YouTube API

在iframe的URL中添加enablejsapi=1参数,确保API能正常工作:

<iframe id="videoFrame" class="absolute top-0 left-0 w-full h-full rounded-lg" 
        src="https://www.youtube.com/embed/{{$video->embed_code}}?enablejsapi=1" 
        frameborder="0" allowfullscreen></iframe>

步骤2:传递Livewire的claimed变量到前端

在HTML中添加一个隐藏元素存储claimed值:

<!-- 添加隐藏元素存储claimed状态 -->
<input type="hidden" id="claimedStatus" value="{{ $claimed ? 'true' : 'false' }}">

步骤3:修正JS逻辑,准确跟踪观看时长

使用YouTube API的getCurrentTime()获取视频实际播放进度,并且在播放过程中定时检查,确保满足条件时立即显示按钮:

<script>
    var player;
    var watchTimer;
    // 从隐藏元素获取claimed状态
    const isClaimed = document.getElementById('claimedStatus').value === 'true';

    function onYouTubeIframeAPIReady() {
        player = new YT.Player('videoFrame', {
            events: {
                'onStateChange': onPlayerStateChange
            }
        });
    }

    function onPlayerStateChange(event) {
        if (event.data === YT.PlayerState.PLAYING) {
            // 播放时启动定时检查
            watchTimer = setInterval(checkWatchTime, 1000);
        } else {
            // 暂停、结束时清除定时器
            clearInterval(watchTimer);
        }
    }

    function checkWatchTime() {
        const claimButton = document.getElementById('claimButton');
        // 已显示按钮或已领取奖励则不再检查
        if (claimButton.style.display === 'block' || isClaimed) {
            clearInterval(watchTimer);
            return;
        }
        // 获取视频当前播放进度(秒)
        const currentVideoTime = player.getCurrentTime();
        if (currentVideoTime >= 30) {
            claimButton.style.display = 'block';
            clearInterval(watchTimer);
        }
    }
</script>

<script src="https://www.youtube.com/iframe_api"></script>

步骤4:优化按钮显示逻辑(可选)

如果用户已经领取过奖励,直接让按钮区域显示“Reward claimed”而不是隐藏:

<div id="claimButton" style="display: {{ $claimed ? 'block' : 'none' }};">
    @if (!$claimed)
        <button wire:click="claimReward" class="bg-green-500 hover:bg-green-700 text-white font-bold py-2 px-4 rounded">
            Claim Reward
        </button>
    @else
        <div class="mt-2 text-green-500">Reward claimed</div>
    @endif
</div>

这样修改后,用户观看视频满30秒(无论是否看完),按钮都会自动显示;同时避免了快进、暂停等情况导致的时长计算错误,也解决了API无法正常工作的问题。

内容的提问来源于stack exchange,提问作者Niffey Dovie

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 02:44:58