简体   繁体   English

如何从 Rails 6 视图调用 JavaScript function

[英]How to call a JavaScript function from Rails 6 view

In my view I'm trying to call a JavaScript function which I've placed in application.js:在我看来,我正在尝试调用我放在 application.js 中的 JavaScript function:

/* Set the width of the side navigation to 250px */
function openNav() {
  document.getElementById("mySidenav").style.width = "250px";
}

/* Set the width of the side navigation to 0 */
function closeNav() {
  document.getElementById("mySidenav").style.width = "0";
}

This is my HTML:这是我的 HTML:

<div id="mySidenav" class="sidenav">
  <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>
  <a href="#">About</a>
  <a href="#">Services</a>
  <a href="#">Clients</a>
  <a href="#">Contact</a>
</div>

<span style="font-size:30px;cursor:pointer" onclick="openNav()">&#9776; open</span>

If I put this in my view within <script></script> tags, then it works.如果我将它放在<script></script>标记中的视图中,那么它可以工作。 My application.js works and it's being compiled but for some reason it only works if the JavaScript is in the actual view of the html.erb file.我的application.js有效并且正在编译,但由于某种原因,它仅在 JavaScript 位于html.erb文件的实际视图中时才有效。 But if it's in application.js in my pack folder, although it builds the JavaScript file, it returns this error in the console:但是如果它在我的包文件夹中的application.js中,虽然它构建了 JavaScript 文件,但它会在控制台中返回此错误:

(index):23 Uncaught ReferenceError: openNav is not defined
    at HTMLSpanElement.onclick ((index):23)

How can I get this to work in my pack/application.js file rather than having it in the theme in a <script> tag?我怎样才能让它在我的pack/application.js文件中工作,而不是在<script>标记中的主题中使用它?

" Rails 5/6: How to include JS functions with webpacker? " worked: Rails 5/6:如何在 webpacker 中包含 JS 函数? ” 工作:

window.closeNav = function() {
  document.getElementById("mySidenav").style.width = "0";
}

window.openNav = function() {
  document.getElementById("mySidenav").style.width = "250px";
}

Can anyone explain why in Rails 6?谁能解释为什么在 Rails 6 中?

It is unclear why the function openNav() does not work in Rails 6. I would suspect that it has to do with the changes from Sprockets to Webpacker.目前尚不清楚为什么function openNav()在 Rails 6 中不起作用。我怀疑它与从 Sprockets 到 Webpacker 的变化有关。 I did find a solution that may be more conventional than adding the methods to the "window" object.我确实找到了一个可能比将方法添加到“窗口”object 更传统的解决方案。 Adding methods or properties directly to the "window" object could inadvertently overwrite defaults.将方法或属性直接添加到“窗口”object 可能会无意中覆盖默认值。 I took guidance from the RailsGuides.我接受了 RailsGuides 的指导。

https://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html https://edgeguides.rubyonrails.org/working_with_javascript_in_rails.html

I added an "id" to the Open and Close elements and removed their "onclick" properties.我在 Open 和 Close 元素中添加了一个“id”,并删除了它们的“onclick”属性。 Adding the ids allowed me to target them in the side_nav.js file to add a "click" event listeners.添加 id 允许我在 side_nav.js 文件中定位它们以添加“点击”事件侦听器。

Index.html.erb索引.html.erb

<div id="mySidenav" class="sidenav">
  <a href="#" class="closebtn" id="close-nav >&times;</a>
  <a href="#">About</a>
  <a href="#">Services</a>
  <a href="#">Clients</a>
  <a href="#">Contact</a>
</div>

<span id="open-nav>Open</span>

<%= javascript_pack_tag 'side_nav' %>

I am using Turbolinks, and so I wait to add the event listeners until after the Turbolinks loads to make sure that the DOM is finished rendering.我正在使用 Turbolinks,所以我等到 Turbolinks 加载后才添加事件侦听器,以确保 DOM 完成渲染。 This will make sure the "id" are available to be targeted.这将确保“id”可用于定位。 If you are not using Turbolinks you may be able to change it out for "DOMContentLoaded".如果您不使用 Turbolinks,您可以将其更改为“DOMContentLoaded”。

javascript\packs\side_nav.js javascript\packs\side_nav.js

window.addEventListener("turbolinks:load", () => {
  // Open
  document.getElementById('open-nav').addEventListener("click", e => {
    e.preventDefault();
    document.getElementById("mySidenav").style.width = "250px";
  });

  // Close
  document.getElementById('close-nav').addEventListener("click", e => {
    e.preventDefault();
    document.getElementById("mySidenav").style.width = "0";
  });
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM