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

如何拦截用户离开产品页并自定义模态弹窗,规避浏览器默认提示?

解决方案:绕过beforeunload限制,实现自定义离开拦截模态框

现代浏览器对beforeunload事件做了严格的安全限制,目的是防止恶意网站劫持用户,所以没法直接绕过默认提示弹出自定义模态框。我们可以换个思路,主动监听用户的主动离开操作,覆盖大部分场景:

核心思路

放弃依赖beforeunload,转而监听用户的明确离开行为(点击外部链接、浏览器前进后退),对这些行为做拦截并弹出自定义模态框;对于用户直接关闭标签页、输入新网址的场景,只能用beforeunload做补充提示(无法完全自定义)。


1. 拦截外部/非目标站内链接的点击

监听页面所有链接的点击事件,判断用户是否要跳转到外部网站或非产品页,若是则阻止默认跳转,弹出自定义模态框让用户选择。

// 监听所有链接点击
document.addEventListener('click', function(e) {
  const target = e.target.closest('a');
  if (!target) return;

  const pageName = prestashop.page.page_name;
  // 仅在产品页(根据你的代码逻辑判断)触发
  if (pageName !== 'index') return;

  // 判断是否为外部链接或非产品页的站内链接
  const isExternal = target.host !== window.location.host;
  const isNonProductPage = !target.pathname.includes('/product/'); // 替换为你的产品页路径规则

  if (isExternal || isNonProductPage) {
    e.preventDefault();
    const leaveUrl = target.href;

    // 插入自定义模态框内容
    $('.modal-body').html(`
      <div class="jumbotron">
        <h1 class="display-4">等等,再看看?</h1>
        <p class="lead">这款产品还有专属优惠,不要错过哦!</p>
        <hr class="my-4">
        <p class="lead">
          <button class="btn btn-secondary btn-lg" id="stayOnPage" role="button">继续浏览</button>
          <button class="btn btn-primary btn-lg" id="leavePage" role="button">确认离开</button>
        </p>
      </div>
    `);
    $('#exampleModalCenter').modal('show');

    // 绑定按钮事件
    document.getElementById('stayOnPage').addEventListener('click', () => {
      $('#exampleModalCenter').modal('hide');
    });
    document.getElementById('leavePage').addEventListener('click', () => {
      $('#exampleModalCenter').modal('hide');
      setTimeout(() => window.location.href = leaveUrl, 300);
    });
  }
});

2. 处理浏览器前进/后退按钮

通过popstate事件监听浏览器的历史记录操作,拦截后退/前进行为并弹出模态框:

let isPageLoaded = false;
window.addEventListener('load', () => isPageLoaded = true);

window.addEventListener('popstate', function(e) {
  const pageName = prestashop.page.page_name;
  if (pageName !== 'index' || !isPageLoaded) return;

  // 恢复当前页面的历史状态,避免直接跳转
  history.pushState(null, null, window.location.href);

  // 弹出自定义模态框
  $('.modal-body').html(`
    <div class="jumbotron">
      <h1 class="display-4">真的要走吗?</h1>
      <p class="lead">再看看这款产品的细节,说不定正是你需要的!</p>
      <hr class="my-4">
      <p class="lead">
        <button class="btn btn-secondary btn-lg" id="stayBack" role="button">留在页面</button>
        <button class="btn btn-primary btn-lg" id="confirmBack" role="button">确认后退</button>
      </p>
    </div>
  `);
  $('#exampleModalCenter').modal('show');

  // 绑定按钮事件
  document.getElementById('stayBack').addEventListener('click', () => {
    $('#exampleModalCenter').modal('hide');
  });
  document.getElementById('confirmBack').addEventListener('click', () => {
    $('#exampleModalCenter').modal('hide');
    setTimeout(() => history.back(), 300);
  });
});

3. 补充:处理关闭标签页/输入新网址的场景

这种情况受浏览器安全限制无法完全自定义,只能用beforeunload提供默认提示(部分浏览器支持自定义文本):

window.addEventListener('beforeunload', function(e) {
  const pageName = prestashop.page.page_name;
  if (pageName !== 'index') return;

  // 自定义提示文本(部分浏览器支持)
  const message = '等等,还有专属优惠等着你!';
  e.returnValue = message;
  return message;
});

注意事项

  • 上述方案能覆盖绝大多数用户主动离开的场景,但关闭标签页、输入新网址的情况只能依赖浏览器默认提示,这是无法绕过的安全限制。
  • 确保模态框的选择逻辑清晰,不要强制拦截用户,避免影响体验。
  • 需在不同浏览器(Chrome、Firefox、Edge)中测试兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 02:46:25