TransWikia.com

jQueryの内の記述とファイルの記述の違い

スタック・オーバーフロー Asked by kojkz on December 9, 2020

発生している問題

jQueryをhtmlファイルに<script>タブで記述する場合と
jsファイルに別途記述する場合では、挙動に差があるのでしょうか?

Bootstrapの練習のためにこちらのサンプルをRuby on Railsで試しに使ってみたのですが、
以下のjQueryをindex.html.erb<script>タブで記述した場合は正常に動作しますが、
application.jsに記述するとToggleMenuボタンを押してもうまく動作しませんでした。

$("#menu-toggle").click(function (e) {
    e.preventDefault();
    $("#wrapper").toggleClass("toggled");
});

jQuery自体が問題なく動作しているか確認のため試しに以下のスクリプトをapplication.js
記述してみたところ正常に動作していることが確認できましたので、jQuery自体の書き方の問題なのかなと思っています。

$(document).ready(function () {
    $(".a").text("jQuery稼働テスト");
});

application.js

//= require rails-ujs
//= require activestorage
//= require jquery
//= require jquery3
//= require popper
//= require bootstrap-sprockets
//= require_tree .

$("#menu-toggle").click(function (e) {
    e.preventDefault();
    $("#wrapper").toggleClass("toggled");
});

$(document).ready(function () {
    $(".a").text("jQuery稼働テスト(稼働中)");
});

application.html.erb

<!DOCTYPE html>
<html lang="ja">
  <head>
    <title><%= full_title(yield(:title)) %></title>    
    <%= csrf_meta_tags %>
    <%= stylesheet_link_tag    'application', media: 'all' %>
    <%= javascript_include_tag 'application' %>
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <%= render 'layouts/shim' %>
  </head>
  <body>
    <div class="d-flex" id="wrapper">
      <%= render 'layouts/sidebar' %>
      <div id="page-content-wrapper">
        <%= render 'layouts/header' %>
        <div class="container-fluid">
          <%= render 'layouts/search' %>
          <%= yield %>
        </div>
      </div>
    </div>
  </body>
</html>

index.html.erb

<div class="container-fluid">
    <h1 class="mt-4">Simple Sidebar</h1>
    <p class="a">The starting state of the menu will appear collapsed on smaller screens, and will appear non-collapsed on larger screens. When toggled using the button below, the menu will change.</p>
    <p>Make sure to keep all page content within the <code>#page-content-wrapper</code>. The top navbar is optional, and just for demonstration. Just create an element with the <code>#menu-toggle</code> ID which will toggle the menu when clicked.</p>
</div>

開発環境

  • Ruby 2.5.5
  • Ruby on Rails 5.2.3
  • Bootstrap4

フロントエンドは初学者でかなり基礎的な質問かもしれませんが、よろしくおねがいします。
不足している情報があれば、お手数ですがコメントください。

One Answer

インラインスクリプト (<script> ~ </script>) や、 async, defer 属性または type="module" を持たない script 要素は、ブラウザがページの解析を続ける前に、読み込みと実行が行なわれます

今回のスクリプトとファイルの読み込み箇所を見ると、 application.js は、ページの読み込みが完了することを待たずに head 要素で読み込まれ、実行されます。すると、スクリプト実行時点では #menu-toggle を持つ要素が存在しないため、クリックイベントは期待したとおりに動作しません。

今回の場合、 script 要素に defer 属性を付与するか、

<%= javascript_include_tag "blah.js", :defer => "defer" %>

DOM の読み込みが完了してからクリックイベントを設定するなどの方法で、この問題を解決出来ると思います。

$(function() {
  $("#menu-toggle").click(function (e) {
    e.preventDefault();
    $("#wrapper").toggleClass("toggled");
  });
});

Correct answer by supa on December 9, 2020

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP