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

滚动时隐藏PDF遮罩div、停止后显示,PDF滚动异常求助

问题

客户要求用div遮罩embed里的PDF来阻止右键下载(明知这个操作无效),但必须允许用户滚动PDF。原本的逻辑是滚动时隐藏遮罩让PDF能接收滚动事件,停止滚动后重新显示遮罩拦截右键,但现在出现了需要多次滚动才能正常滚动PDF的问题。

原代码

JavaScript代码

var wheeling;
window.addEventListener('wheel', function (e) {
        if (!wheeling) {
            console.log('start wheeling!');
            document.querySelector("#lesson_pdf").style.display = "none";
        }

        clearTimeout(wheeling);
        wheeling = setTimeout(function() {
            console.log('stop wheeling!');
            document.querySelector("#lesson_pdf").style.display = "block";
            wheeling = undefined;
        }, 300);
    });

HTML代码

<div>
    <div style="position: relative;">
        <!-- 要被覆盖的embed标签 -->
        <embed src=" {{ getImageFile($pdf_src) }}" class="tw-w-full tw-h-[500px] pdf-reader-frame" style="position: absolute;">
    </div>
    <!-- 遮罩div -->
    <div style="position: absolute;
                height: 100%;
                width: 100%;
                display: block;
                z-index: 1;" id="lesson_pdf">
    </div>
</div>

修复方案

问题根源在于两个点:一是监听window的滚轮事件太宽泛,触发时机不精准;二是用display:none切换遮罩会导致DOM重绘,延迟了PDF接收滚动事件的时机。

1. 调整HTML结构与样式

把遮罩放到和embed同级的相对定位容器内,确保层级和位置完全覆盖PDF,同时简化样式:

<div style="position: relative; width: 100%; height: 500px;">
    <!-- PDF嵌入标签 -->
    <embed src="{{ getImageFile($pdf_src) }}" class="tw-w-full tw-h-full pdf-reader-frame" style="position: absolute; top: 0; left: 0;">
    <!-- 遮罩div -->
    <div id="lesson_pdf" style="position: absolute; top: 0; left: 0; height: 100%; width: 100%; z-index: 1; pointer-events: auto;"></div>
</div>

2. 优化JavaScript逻辑

  • 改为监听PDF容器的滚轮事件,触发更精准
  • 用pointer-events代替display:none,避免DOM重绘延迟
  • 简化滚动状态判断逻辑
let wheelTimer;
const mask = document.querySelector("#lesson_pdf");
const pdfContainer = mask.parentElement;

pdfContainer.addEventListener('wheel', function(e) {
    // 滚动时让遮罩不拦截鼠标事件,让PDF接收滚动
    mask.style.pointerEvents = 'none';
    
    clearTimeout(wheelTimer);
    // 停止滚动300ms后恢复遮罩的右键拦截
    wheelTimer = setTimeout(() => {
        mask.style.pointerEvents = 'auto';
    }, 300);
}, { passive: true }); // 提升滚动性能

为什么这么改?

  • pointer-events: none/auto只是控制元素是否接收鼠标事件,不会改变DOM布局,响应速度比display:none快得多,不会出现滚动延迟
  • 监听容器的滚轮事件,只会在用户滚动PDF区域时触发,避免了其他区域滚动误触发遮罩隐藏
  • passive: true告诉浏览器这个事件不会调用preventDefault(),能提升滚动的流畅度

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 04:52:43