0

New to Javascript. I'm following a javascript tutorial to create a simple tictactoe game and I'm trying to adapt the code to work on Rails.

I have a JavaScript file with a function that is supposed to run once cell element is clicked.

When I load the page script js file loaded is displayed from console.log("script js file loaded") in the console so i know the javascript file is being loaded.

I suspect the rails js syntax is a little different from vanilla js?

app/views/tictactoe/index.html.erb:

<%= javascript_pack_tag 'script' %>

<div class="board" id="board">
    <!--- add data cell so can access in javascript   -->
    <div class="cell" data-cell></div>
    <div class="cell" data-cell></div>
    <div class="cell" data-cell></div>
    <div class="cell" data-cell></div>
    <div class="cell" data-cell></div>
    <div class="cell" data-cell></div>
    <div class="cell" data-cell></div>
    <div class="cell" data-cell></div>
    <div class="cell" data-cell></div>

</div>

app/javascript/packs/script.js

const cellElements = document.querySelectorAll('[data-cell]')

// loop through each cell, add event listener, every time cell is clicked, add this listener (handleClick),
// once:true --> once clicked once, wont fire again
cellElements.forEach(cell => {
    cell.addEventListener('click', handleClick, {once: true})
})

function handleClick(e){
    console.log('clicked')
}

console.log("script js file loaded")

Any help is appreciated thank you.

  • 1
    1st off, js is js; there's nothing special about "rails js". Your particular problem is simply one of order. Your script is loaded before the DOM you're querying about so your script has no effect. Moving the script to the end of body is common practice (for this and other reasons) and should solve your problem. See [this answer](https://stackoverflow.com/questions/9899372/pure-javascript-equivalent-of-jquerys-ready-how-to-call-a-function-when-t) for more details & alternative practices. – numbers1311407 Aug 28 '20 at 23:06

1 Answers1

0

@numbers1311407 is correct, in your application.html.erb you can use defer:true to make your JS run after your DOM is loaded.

<%= javascript_pack_tag 'application', defer: true %>
Yanou
  • 929
  • 8
  • 8