78397


## 発生している問題

外部Javascript内で`document.getElementById`を使用しHTMLのIDを取得しようとすると`Uncaught
TypeError: document.getElementById(...) is null` が発生します。

app/javascript/chk_waittime/index.js

[code]

    document.getElementById('post_waittime').onclick = function(){
      alert('index.js');
    };
    
[/code]

開発者ツールのコンソール画面

[code]

    Uncaught TypeError: document.getElementById(...) is null
        js index.js:1
        Webpack 5
            __webpack_require__
            js
            __webpack_require__
            <anonymous>
            <anonymous>
    index.js:1
        js index.js:1
        Webpack 5
            __webpack_require__
            js
            __webpack_require__
            <匿名>
            <匿名>
    
[/code]

## 環境

  * Ruby 2.6.3
  * Rails 6.0.3

## Javascriptの構成

app/javascript配下の構成

[code]

    app % find javascript
    javascript
    javascript/packs
    javascript/packs/application.js
    javascript/chk_waittime
    javascript/chk_waittime/index.js
    javascript/channels
    javascript/channels/index.js
    javascript/channels/consumer.js
    
[/code]

app/javascript/packs/application.js

[code]

    require("@rails/ujs").start()
    require("turbolinks").start()
    require("@rails/activestorage").start()
    require("channels")
    require("chk_waittime")
    import "bootstrap"
    
[/code]

app/javascript/chk_waittime/index.js

[code]

    document.getElementById('post_waittime').onclick = function(){
      alert('index.js');
    };
    
[/code]

## html.erbの構成

app/views/layouts/application.html.erb

[code]

    <!DOCTYPE html>
    <html>
      <head>
        <title><%= full_title(yield(:title)) %></title>
        <%= csrf_meta_tags %>
        <%= csp_meta_tag %>
        <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
        <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
      </head>
      <body>
        <%= render 'layouts/header' %>
        <% flash.each do |message_type, message| %>
          <%= content_tag(:div, message, class: "alert alert-#{message_type}") %>
        <% end %>
        <%= yield %>
      </body>
    </html>
    
[/code]

app/views/shops/index.html.erb

[code]

    (省略)
    <% if logged_in? %>
    (省略)
    
    <% else %>
      <ol class="shops">
        <% @shops.each do |shop| %>
          <%= render partial: "shop_not_login", locals: {shop: shop} %>
        <% end %> 
      </ol>
    <% end %>
    
[/code]

app/views/shops/_shop_not_login.html.erb

[code]

    <li class="shops">
      (省略)
      <%= link_to "待ち時間を投稿する", "#", id:"post_waittime" %><br>
    </li>
    
[/code]

## 外部Javascriptが動作していることの確認

app/javascript/chk_waittime/index.js

[code]

    alert('index.js');
    
[/code]

ブラウザ

[![画像の説明をここに入力](https://i.stack.imgur.com/A4YS1.png)](https://i.stack.imgur.com/A4YS1.png)

何卒よろしくお願いいたします。


CC BY-SA 4.0
2021-07-25T02:20:53.780
78389
2021-07-26T03:04:18.613
36122
question
javascript ruby-on-rails ruby webpack erb
Rails6/Webpacker環境で外部JSファイル内でHTMLのIDを取得したい


`app/javascript/chk_waittime/index.js`を下記のように  
`window.onload = function() {}` で囲うことで解決しました。  
javascriptが読み込まれるタイミングが原因のようです。

変更前

[code]

    document.getElementById('post_waittime').onclick = function(){
      alert('index.js');
    };
    
[/code]

変更後

[code]

    window.onload = function() {
      document.getElementById('post_waittime').onclick = function(){
        alert('index.js');
      };
    };
    
[/code]

コメントいただいたリンク先の内容を参考に解決することができました。

[Why does jQuery or a DOM method such as getElementById not find the
element?](https://stackoverflow.com/a/8716680)


CC BY-SA 4.0
2021-07-25T23:28:20.973
78397
2021-07-26T03:04:18.613
2021-07-26T03:04:18.613
3060
36122
78389
answer