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

嵌入Fancybox的TikTok视频在弹窗中自动消失问题求助

Fancybox嵌入TikTok视频后打开立即消失的解决办法

问题情况

使用@fancyapps/ui": "^5.0.17"实现多平台视频嵌入,YouTube和VK视频显示正常,但TikTok视频放入Fancybox后,打开会立即消失:

  • 浏览器元素检查可见视频仍在DOM结构中
  • 打开视频后刷新页面,视频可正常观看
  • 快速点开视频也能查看,但关闭Fancybox后视频会消失

现有代码

后端获取TikTok数据(PHP)

$apiUrl = "https://www.tiktok.com/oembed?url={$link}";

try {
    $response = $client->get($apiUrl);
    $jsonResponse = json_decode($response->getBody(), true);
    
    $html = $jsonResponse['html'];
    $preview = $jsonResponse['thumbnail_url'];
} catch(Exception $exception) {
    $html = false;
    $preview = '';
}

return view('widgets.index_iframe_tik_tok_widget', [
    'html' => $html,
    'masterJob' => $this->config['index'],
    'key' => $this->config['key'],
    'preview' => $preview
]);

TikTok oEmbed返回的HTML内容

<blockquote class="tiktok-embed" cite="https://www.tiktok.com/@world_walkerz/video/7218998983937625349" data-video-id="7218998983937625349" data-embed-from="oembed" style="max-width: 605px;min-width: 325px;" id="v62804243901872250">  </blockquote>
<script async="" src="https://www.tiktok.com/embed.js"></script>

前端Blade视图代码

@if($html)
    <div>
        <span data-thumb="{{ $preview }}" data-fancybox="{{ $index->id }}" data-src="#dialog-content-{{ $index->id }}-{{ $key }}"></span>
        <div style="display: none" id="dialog-content-{{ $index->id }}-{{ $key }}">
            {!! $html !!}
        </div>
    </div>
@endif

问题原因

TikTok的embed.js是异步加载脚本,仅在页面初始加载时扫描tiktok-embed块完成渲染。但Fancybox打开时会将目标DOM元素移至自身容器,加上初始元素为display: none,导致脚本无法正确识别元素;同时Fancybox的动画过程也可能干扰TikTok的渲染逻辑,最终造成视频显示后消失。

解决方法

方法1:Fancybox打开后动态加载TikTok脚本

移除后端返回HTML中的自带脚本,改为在Fancybox打开后加载脚本并触发渲染:

  1. 修改视图代码,剔除自带的script标签:
@if($html)
    <div>
        <span data-thumb="{{ $preview }}" data-fancybox="{{ $index->id }}" data-src="#dialog-content-{{ $index->id }}-{{ $key }}" class="tiktok-fancybox-trigger"></span>
        <div style="display: none" id="dialog-content-{{ $index->id }}-{{ $key }}">
            {!! str_replace('<script async="" src="https://www.tiktok.com/embed.js"></script>', '', $html) !!}
        </div>
    </div>
@endif
  1. 添加JS监听Fancybox事件:
// 绑定TikTok触发元素的Fancybox事件
Fancybox.bind('.tiktok-fancybox-trigger', {
    onDone: (fancybox, slide) => {
        // 检查脚本是否已加载
        let tiktokScript = document.querySelector('script[src="https://www.tiktok.com/embed.js"]');
        if (!tiktokScript) {
            tiktokScript = document.createElement('script');
            tiktokScript.src = 'https://www.tiktok.com/embed.js';
            tiktokScript.async = true;
            document.body.appendChild(tiktokScript);
        } else {
            // 脚本已加载则手动触发渲染
            if (window.tiktokEmbed) {
                window.tiktokEmbed.render();
            }
        }
    },
    onClose: (fancybox) => {
        // 关闭时移除iframe,避免下次打开冲突
        const tiktokIframe = fancybox.container.querySelector('iframe.tiktok-embed');
        if (tiktokIframe) {
            tiktokIframe.remove();
        }
    }
});

方法2:直接使用Fancybox的iframe模式加载TikTok

绕开blockquote渲染逻辑,让Fancybox直接加载TikTok嵌入页面:

  1. 后端提取视频ID并构造嵌入URL:
// 从oEmbed返回的html中提取视频ID
preg_match('/data-video-id="(\d+)"/', $jsonResponse['html'], $matches);
$videoId = $matches[1] ?? '';
// 构造直接嵌入的URL
$embedUrl = "https://www.tiktok.com/embed/v2/{$videoId}";
  1. 修改视图代码,使用Fancybox的iframe类型:
@if($embedUrl)
    <span data-thumb="{{ $preview }}" data-fancybox="{{ $index->id }}" data-src="{{ $embedUrl }}" data-type="iframe" data-width="605" data-height="auto"></span>
@endif

此方法无需处理DOM移动问题,实现更简洁。

方法3:临时禁用Fancybox动画

若上述方法无效,可先关闭Fancybox入场动画,给TikTok脚本足够渲染时间:

Fancybox.bind('[data-fancybox]', {
    animationEffect: "none"
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 13:14:53