【问题标题】:Open Bootstrap tab programmatically with turbolinks使用 turbolink 以编程方式打开 Bootstrap 选项卡
【发布时间】:2020-05-16 20:04:04
【问题描述】:

我正在尝试在页面加载后打开 Bootstrap 4 选项卡。如果我刷新页面,它确实可以工作,但如果我在网站内导航,我会收到一个查询选择器空错误。

这是我的代码,基本上是我对 https://webdesign.tutsplus.com/tutorials/how-to-add-deep-linking-to-the-bootstrap-4-tabs-component--cms-31180 所做的移植,因为我使用的是 Bootstrap-native,所以我不得不用原生 Javascript 重写它。

  document.addEventListener("turbolinks:load", function() {
    let url = location.href.replace(/\/$/, "");
    if (location.hash) {
      const hash = url.split("#");
      document.querySelector('#nav-tab a[href="#'+hash[1]+'"]').Tab.show();
      url = location.href.replace(/\/#/, "#");
      history.replaceState(null, null, url);
      setTimeout(() => {
        window.scrollTo(0,0);
      }, 400);
    }
  });

我将它放在结束 body 标记之前。如果我写http://www.myURL#mytab 并单击刷新,页面刷新并且选项卡会更改,但是如果我从(涡轮)链接到达那里,它不会找到要查询选择的选项卡。恐怕问题出在“加载”事件上,我尝试了不同的方法,但无法正常工作。

【问题讨论】:

    标签: javascript bootstrap-4 turbolinks bootstrap-native


    【解决方案1】:

    如果您将此代码包含在<body> 末尾的<script> 中,您可能不需要监听turbolinks:load 事件。 为什么?在第一次加载时,浏览器将能够查询位于脚本元素之前的任何元素。在 Turbolinks 加载脚本时,<body> 将有权访问页面上所有呈现的元素。

    值得补充的是,通过在主体<script> 元素中调用document.addEventListener("turbolinks:load", …),侦听器将在每次 后续页面加载时被调用,而不仅仅是在呈现脚本的页面上。如果 #nav-tab 元素在后续页面加载时不存在,然后您将看到 querySelector 错误。更重要的是,如果你在不止一个页面上包含脚本,那么监听器会一次又一次地重复,这可能不是你想要的!

    因此,解决问题的第一步是删除事件侦听器。我们会将您的代码包装在一个立即调用的函数中,以防止污染全局范围:

    ;(function() {
      let url = location.href.replace(/\/$/, "");
      if (location.hash) {
        const hash = url.split("#");
        document.querySelector('#nav-tab a[href="#'+hash[1]+'"]').Tab.show();
        url = location.href.replace(/\/#/, "#");
        history.replaceState(null, null, url);
        setTimeout(() => {
          window.scrollTo(0,0);
        }, 400);
      }
    })();
    

    接下来要知道的是,Turbolinks 管理自己的已访问页面缓存,因此当用户点击“返回”时,会从该缓存中呈现页面。为此,它有一个用于添加到浏览器自己的history 堆栈的系统。如果您绕过 Turbolinks 系统并自己致电history.replaceState(或history.pushState),那么您最终可能会破坏“返回”导航。 Turbolinks 没有手动添加到其历史堆栈的记录方法,但您可以尝试以下方法:

    ;(function() {
      let url = location.href.replace(/\/$/, "");
      if (location.hash) {
        const hash = url.split("#");
        document.querySelector('#nav-tab a[href="#'+hash[1]+'"]').Tab.show();
        url = location.href.replace(/\/#/, "#");
        Turbolinks
          .controller
          .replaceHistoryWithLocationAndRestorationIdentifier(url, Turbolinks.uuid())
        setTimeout(() => {
          window.scrollTo(0,0);
        }, 400);
      }
    })();
    

    请注意,这是未记录的,因此可能不会在未来的版本中公开提供。

    最后,可能值得考虑将这个 sn-p 包含在您的主应用程序 JavaScript 包中,并将其加载到 <head> 而不是正文中。在这种情况下,您需要使用 `turbolinks:load 处理程序。它可能看起来像:

    document.addEventListener('turbolinks:load', function () {
      let url = location.href.replace(/\/$/, "");
      const hash = url.split("#");
      const navLink = document.querySelector('#nav-tab a[href="#'+hash[1]+'"]')
      if (location.hash && navLink) {
        navLink.Tab.show();
        url = location.href.replace(/\/#/, "#");
        Turbolinks
          .controller
          .replaceHistoryWithLocationAndRestorationIdentifier(url, Turbolinks.uuid())
        setTimeout(() => {
          window.scrollTo(0,0);
        }, 400);
      }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-09-30
      • 1970-01-01
      • 1970-01-01
      • 2011-11-24
      • 2010-10-29
      • 2017-12-21
      • 1970-01-01
      相关资源
      最近更新 更多