[RUBY] JavaScript (vanilla) does not respond in Rails.

In rails5, jQuery gem is introduced from the beginning, and it is available by default unless it is deleted. When I started learning Rails, I became accustomed to using jQuery rather than plain JavaScript (hereinafter "vanilla"), so this time I dared to find a way to not use jQuery to learn vanilla again.

environment

Ruby 2.5.7 Rails 5.2.4

Background

When I started writing code in vanilla again, I was quite addicted to it. If I could write it in jQuery, that would be fine, but it was unpleasant to leave it as it was, so I decided to face it a little.

Immediate function does not work

I tried to check the console log with a click event to get started. In jQuery, $ (function () {processing}); as shown below It is necessary to write. (The reason will be described later.)

application.js


// jQuery
$(function() {
  $("Selector name").on('click', function() {
    console.log('It was clicked.');
  });
});

Vanilla's immediate function without jQuery is written as follows.

application.js


//vanilla
(function() {
  document.getElementById("Selector name").addEventListener('click', function() {
    console.log('It was clicked.');
  });
}());

Both of the above two codes have the same processing, but for some reason the vanilla error occurs and is not output to the console log. .. ..

I used to switch to jQuery here, but I really wanted to solve it, so I came up with this search.

Why does jQuery work and vanilla not?

It was hidden in $ (function () {});. (Not hidden.) $ (function () {}); is abbreviated, and the original form is as follows.

application.js


$(document).ready(function {
 //processing
});

The ready method is a method that performs the internal processing when the HTML has finished loading. In other words, by writing all js processing in $ (function () {processing});, you can perform processing without thinking about anything.

In vanilla, it is necessary to write this "waiting for loading html" without using jQuery.

DOMContentLoaded In vanilla, by specifying DOMContentLoaded in the event of the addEventListener method, you can do the same thing as the ready method of jQuery, and the code will be as follows.

application.js


window.addEventListener('DOMContentLoaded', function() {
  //processing
});

How to do a click event in vanilla?

Now let's look back at the code that compared the first jQuery with vanilla.

application.js


// jQery
$(function() {
  $("Selector name").on('click', function() {
    console.log('It was clicked.');
  });
});

If you write this jQuery without omitting it

application.js


// jQery
$(document).ready(function() {
  $("Selector name").on('click', function() {
    console.log('It was clicked.');
  });
});

It will be like that.

Next, let's look at vanilla.

application.js


//vanilla
(function() {
  document.getElementById("Selector name").addEventListener('click', function() {
    console.log('It was clicked.');
  });
}());

This is an immediate function, but in fact it may work in this way as well.

Method 1. Write the script tag for reading the external js file at the bottom of the body element.

Normally, in Rails, the loading tag of an external js file is often written inside the head tag. However, if you read the js file in the head, the js function will be activated before taking the element in the body, so an error will occur. So, it is a method to write the reading tag of the external js file at the end of the body tag.

erb:application.html.erb


<head>
...
<%#= javascript_include_tag 'application' %>
...
<head>
<body>
...
<%= javascript_include_tag 'application' %>
</body>

By doing this, the js file will start loading when the body finishes loading, so you can also load the elements. However, other external files, services, API loading settings, etc. are all written in the head tag, so if possible, I would like to unify the loading of external js files in the head.

Method 2. Use DOMContentLoaded

As I mentioned earlier, this is how to use the DOMContentLoaded event of the addEventListener method. It is necessary to rewrite only the js file while leaving the js external file reading tag in the head.

application.js


//vanilla
window.addEventListener('DOMContentLoaded', function() {
  document.getElementById("Selector name").addEventListener('click', function() {
    console.log('It was clicked.');
  });
});

Now that the HTML is loaded and the function is executed, it works fine.

Caution

By the way, the DOMContentLoaded event only waits for the HTML to finish loading, so it doesn't include loading css or image files. If you have an image or css operation, you can use the load event of the addEventListener method to fire the function after all the loading is completed.

Summary

So far, I've told you how to write in vanilla, but I personally think that jQuery can be used as long as it is compatible with jQuery. I actually wrote vanilla and found out how easy it is to write with jQuery ... lol This can be inferred from the fact that it is also installed as standard in Rails.

If you have any questions, differences in interpretation, or any discomfort in the description method, we would appreciate it if you could point them out in the comments.

Thank you for reading until the end.

Reference site

Reason for using immediate functions in JavaScript [JQuery] $ (function () {...}) "meaning and timing of execution" Difference between DOMContentLoaded event and load event [Timing]

Recommended Posts

JavaScript (vanilla) does not respond in Rails.
Localhost3000 does not start up in Docker / Rails development.
Data is not registered in Rails.
[Rails] What to do when rails s does not respond or does not stop
[Rails] Video does not play with video_tag
[JavaScript] Negative rounding does not match Excel
MySQL container does not start in Docker
.sql file does not run in docker-compose
[Rails] Bootstrap form-control does not apply to date_select
Group_by in Rails
[Rails] Added in devise: username not added to database
@BeforeStep does not work in Tasklet of spring-batch
Remedy for command not found in rails s
rails code doesn't respond well in atom erb
How to deal with errors in Rails s could not find a JavaScript runtime.
Many error lines ... Rails server does not start 2. "Autodetect': Could not find a JavaScript runtime."
Bundle install with docker + rails6 does not reflect gem
Correspondence when Ruby version does not switch in rbenv
[Rails] How to load JavaScript in a specific view
Hivernate Validator does not work in WAS Liberty environment
When the server does not start with rails s
Do not write 〇〇 logic in Rails View (* added later)
[Ruby on Rails] credential does not work in production environment even though I saved production.key
Model association in Rails
Terminal does not start
Disable turbolinks in Rails
CSRF measures in Rails
^, $ in Rails regular expression
Use images in Rails
Understand migration in rails
Split routes.rb in Rails6
What to do when Rails on Docker does not reflect controller changes in the browser
Sidekiq-limit_fetch does not work
Implement markdown in Rails
The story when the test folder was not created in Rails
[Ruby on Rails] When parameter id acquisition does not work
[Rails] Couldn't find with'id'=: id does not execute update action
[Rails] The problem that pry-byebug does not stop through breakpoints
What to check when rails db: migration does not pass
[Rails] Solving the problem that session timeout does not work
Docker does not work when DOCKER_HOST is specified in WSL2
[AWS S3] AWS Access Key Id you provided does not exist in our records error [Rails AWS EC2]