rails 中的 Turbolinks 与使用 javascript 的 Alpine JS 下拉菜单和 Hubspot 表单冲突

Turbolinks in rails is conflicting with Alpine JS dropdown and Hubspot form that uses javascript

我在使用 Rails Turbolinks + Alpine JS and TailwindCSS drop-downs 时遇到问题。

问题是由于与“联系我们”页面上的 Hubspot 联系表发生冲突。这是网站:

bailoutwatch.org

联系我们 link 在页脚中,我正在 link 以关闭 turbolinks 的方式进入联系我们页面:

<%= link_to "Contact Us", contact_path, data: { turbolinks: false } %>

您可以直接在 bailoutwatch.org/contact 访问该页面,但请务必在第一次访问该页面时注意 "Dropdown flash"。

如果我在 link 转到“联系我们”页面时不关闭 turbolinks,则 turbolinks 会破坏通过 [= 加载的 Hubspot 表单48=] 并且是该页面的要求。

因为我已经关闭了此“联系我们”页面的 turbolinks,所以当您第一次访问该站点时,它会触发使用 Alpine JS 的下拉菜单。这是一个快速的闪光,一旦下拉菜单被缓存在 turbolinks 中,它就不会再发生了,但是我无法找到加载所有这些 JS 要求的正确方法,而不是在访问联系我们页面。

我应该如何在 Rails 中执行此操作,以便我可以在站点的其余部分使用 turbolinks 而不会破坏 Hubspot 表单或重新加载所有 javascript(在访问“联系我们”页面时导致下拉菜单闪烁)?

我正在通过我的 header 像这样加载 js:

<%= javascript_pack_tag "application", "data-turbolinks-track": "reload" %>

然后,通过 webpack 加载 Alpine JS(它与 Yarn 一起安装)。然后通过页面 body 中的内联 javascript 加载 Hubspot 表单。看起来像这样 (_hubspot_contact_form.html.erb):

<!--[if lte IE 8]>
<script charset="utf-8" type="text/javascript" src="//js.hsforms.net/forms/v2-legacy.js"></script>
<![endif]-->
<script charset="utf-8" type="text/javascript" src="//js.hsforms.net/forms/v2.js"></script>
<script>
  hbspt.forms.create({
    portalId: "HUBSPOT ACCOUNT NUMBER HERE",
    formId: "90fb717a-6ce5-42e1-9e6d-aa1470042cbc"
});
</script>

这是我正在描述的 "dropdown flash" 的屏幕截图。

Alpine.js x-show 通过在元素上切换 style="display: none;" 来工作,因此您可以自己在代码中添加它(下面的示例,基于我从您的站点提取的源代码)。

这样,当页面加载时,无论 JavaScript 加载了什么,它都会开始隐藏,但是一旦加载,Alpine.js 就会控制该样式属性。

<div x-data="{ isOpen: false }" ...>
  <div x-show="isOpen" style="display: none;" ...>
    ...
  </div>
</div>

根据文档将其放入您的 CSS。这比在每个组件上放置 display:none 要好一点,因为它掩盖了整个页面:

[x-cloak] { display: none; }

x-cloak 属性在 Alpine 初始化时从元素中移除。这对于隐藏预初始化的 DOM 很有用。通常添加以下全局样式才能使其正常工作。

正如 Alpine 在其自述文件中所建议的,使用 Turbolinks Adapter

来自 CDN

只需在页面中的 Alpine 脚本之前包含 <script src="https://cdn.jsdelivr.net/npm/alpine-turbo-drive-adapter@1.0.x/dist/alpine-turbo-drive-adapter.min.js" defer></script>

来自 NPM

安装包

npm i alpine-turbo-drive-adapter

将它与 Alpine JS 一起包含在您的脚本中。

import 'alpine-turbo-drive-adapter'
import 'alpinejs'