Rails JavaScript在重新加载后才工作

在使用 Rails 开发应用时,经常会涉及到与 JavaScript 的交互。然而,有时候我们会遇到一个问题:当页面重新加载后,之前绑定的事件或者修改过的 DOM 元素无法正常工作。这篇文章将介绍这个问题的原因和解决方法。

问题背景

假设我们有一个 Rails 应用,其中有一个 app/views/posts/show.html.erb 文件,包含以下代码:

---- ----------
  ------- ----------- -------
  ------ ---------- ------
  --- ------- ------- --------------------- --
------

--- ------------------- ------------ --

javascript_pack_tag 方法是 Rails 6 中新增的方法,它可以将打包后的 JavaScript 文件引入到页面中。我们假设 posts/show.js 中包含以下代码:

-------------------------------------------- -- -- -
  ----- ----------- - --------------------------------
  ----- -------- - -------------------------------

  ---------------------------------- ------- -- -
    -----------------------
    ----------- ---- -----------
  ---
---

上述代码会在页面加载完成后,为编辑按钮绑定一个点击事件,并弹出一个提示框。然而,当我们点击编辑按钮并保存后,页面会重新加载,此时再次点击编辑按钮时,就无法弹出提示框了。

问题原因

这个问题的原因是,当页面重新加载时,旧的 JavaScript 代码已经被销毁了。这是因为 Turbolinks 在页面重新加载时会将整个页面替换成新的 HTML,其中包括之前绑定的事件和修改过的 DOM 元素。所以,我们需要重新绑定事件或者修改元素。

解决方法

使用 turbolinks:load 事件

为了避免在页面重新加载后出现问题,我们可以使用 Turbolinks 提供的 turbolinks:load 事件。该事件会在页面重新加载后触发,因此我们可以在该事件中重新绑定事件或修改元素。

修改 posts/show.js 文件如下:

-------------------------------------------- -- -- -
  ----- ----------- - --------------------------------
  ----- -------- - -------------------------------

  -------- ------------------ -
    -----------------------
    ----------- ---- -----------
  -

  ------------------------------------- -------------
  ---------------------------------- -------------
---

上述代码中,我们首先定义一个名为 handleClick 的函数来处理编辑按钮的点击事件。然后,我们使用 removeEventListener 方法移除之前绑定的事件,再使用 addEventListener 方法重新绑定事件。这样,即使页面重新加载,我们也能够正常地处理事件了。

使用 data-turbolinks-permanent 属性

除了使用 turbolinks:load 事件外,我们还可以使用 data-turbolinks-permanent 属性来使某些元素在页面重新加载后保持不变。我们只需要在需要保持的元素上添加该属性即可。例如:

---- --------- --------------------------
  ---
------

上述代码中,我们为 #post 元素添加了 data-turbolinks-permanent 属性,这样无论页面如何重新加载,该元素都会一直存在。

结语

以上就是解决 Rails JavaScript 在重新加载后才工作的两种方法。使用这些方法可以避免因为页面重新加载而导致的 JavaScript 事件无法正常工作的问题。希望本文能对大家有所帮助。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/24767