rails6でjavascriptでhello worldとデベロッパーツールのコンソールに表示しようとしたらnullが返って来た話
対象者
これからjavascriptをrailsで動かそうとしている人.
javascriptをrails6で動かそうとするとコンソールにnullが表示される人
目次
エラー内容と経緯
解決策
エラー内容と経緯
エラー内容 ⇨デベロッパーツールにnullと表示される.
処理の流れとしては home.jsで記載していることをapplication.jsで読み込んでapplication.html.erbでapplication.jsの内容を読み込むことでhome.html.erbのファイル内のhello worldを取得しようとしました。
home.html.erb <h1 id="hello">Hello World</h1>
javascript/packs/application.js
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
require("@rails/ujs").start()
require("turbolinks").start()
require("@rails/activestorage").start()
require("channels")
require('jquery')
//= require popper
//= require bootstrap-sprockets
import 'bootstrap'
import '../src/application.scss'
import "./home"
// Uncomment to copy all static images under ../images to the output folder and reference
// them with the image_pack_tag helper in views (e.g <%= image_pack_tag 'rails.png' %>)
// or the `imagePath` JavaScript helper below.
//
// const images = require.context('../images', true)
// const imagePath = (name) => images(name, true)
javascirpt/packs/home.js
console.log(document.getElementById('hello'));
application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>猫検索</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<meta name="description" content="あなたのお好みの猫が探せます">
<%= stylesheet_link_tag 'application', media: 'all', data: { turbolinks: true } %>
<%= javascript_pack_tag 'application', data: { turbolinks: true } %>
</head>
<body>
<header>
<%= render 'layouts/header'%>
</header>
<div class="background">
<%= yield %>
<%= image_tag "background.jpg" %>
</div>
</body>
</html>
↑のコードの処理の流れのイラストは↓

経緯 cloud9で開発していたのですが無料期間が終わりそうなのでローカルで開発し始めました。 そこでjavascriptを使ってコンソールにhello worldと出力しようとしました。 しかしなぜか以下のようにするとnullが出力されます。
原因と解決策
原因.
→htmlファイルが読み込まれる前にjavascriptファイルが読み込まれているのでconsole.log(document.getElementById('hello'));でhtml要素を取得しようとしても、まだhtml読み込まれていないのでnullが出力される。
ちなみにapplication.html.erbの <%= javascript_pack_tag 'application', data: { turbolinks: true } %>これでjavascriptを読み込んでいる。htmlファイルは上から順番に実行されているのでhead内に書いているとjavascriptが先に読み込まれる。
解決策. html.ファイル読み込んでからjavascriptファイルを読み込む
.addEventListener(処理)
このメソッドを使うことでhtml.ファイルを読み込んでからjavascriptの(処理)を行なってくださいというメソッド。 なので上のメソッドを使用すると無事コンソールにhello worldを取得できました。
document.addEventListener('DOMContentLoaded', () => {
const helloText = document.getElementById('hello');
console.log(helloText.textContent);
});
