Literal Objects with onclick event handlers JavaScript

Literal Objects with onclick event handlers JavaScript
0

#1

Hello Everyone! Can somebody please help me to understand what I am doing wrong with this Game Task.
I have 3 diferent contents in this object:
1.- Start of the game
2.- End of the Game to show results
3.- the Game board where the users can play…
Now, what I want to do and it does not work is:

  • in my Literal Object i have the Key with the name displayGame (like a constructor).
    Problem: I have the key with the name: gameHandler, it should display the key: displayBoard content when the user click on the class button - Star Game which is in Keys: displayStart and displayEnd.
    Here is my Code:
const UserInterface = {
	displayGame: function(){
		this.displayStart();
	},
	displayStart: function() {
		var gameStart = '<div class="screen screen-start" id="start">'; /* strat Game*/
			gameStart += '<header>';
			gameStart += '<h1>Game</h1>';
			gameStart += '<a href="#" class="button">Start Game</a>';
			gameStart += '</header>';
			gameStart += '</div>';
		this.populateDivWithHTML(gameStart);
	},
	displayEnd: function() {
/*to show the Game results an start a new Game from 0*/
		var gameEnd = '<div class="screen screen-win" id="finish">';
			gameEnd += '<header>';
			gameEnd += '<h1>Game</h1>';
			gameEnd += '<p class="message">display the winner</p>';
				gameEnd += '<a href="#" class="button">New game</a>';
			gameEnd += '</header>';
			gameEnd += '</div>';
		this.populateDivWithHTML(gameEnd);
	},
	displayBoard: function(){
		var gameBoard = '<div class="board" id="board">'; /*The Game */
		  	gameBoard += '<header>';
		        gameBoard += '<h1>Game</h1>';
		        gameBoard += '<ul>;'
		        gameBoard += '<li class="players player1">my game board</li>';
		        gameBoard += '</ul>';
		  	gameBoard += '</header>';
			gameBoard += '</div>';
		this.populateDivWithHTML(gameBoard);
	},
	populateDivWithHTML: function(div) {
		document.body.innerHTML = div;
	},
	gameHandler: function() {
		button = document.getElementsByClassName('button');
		button.onclick = function() {
			this.displayBoard();
		}
	}
};
GameUI.displayGame(); /*it display the Game*/

on click at the the button start Game it should display my Game board but it does not. something I doing wrong and I dont know…

many thanks!!!


#2
this.gameHandler() // run function after you render `gameStart`

button = document.getElementsByClassName('button') // is calling a HTMLcollection
var button = document.getElementsByClassName('button')[0] // should set its index
var button = document.querySelector('.button') // or use querySelector

button.onclick =  function() {
  this.displayBoard(); // `this` value doesn't refer to the originating context
}.bind(this) // bind your object UserInterface or use es6 arrow function

#3

Hi pseudop ! thank to answer.
I don’t really understand what you mean…
This is what I have:

const UserInterface = {
	displayGame: function(){
		this.displayStart();
	},
	displayStart: function() {
		var gameStart = '<div class="screen screen-start" id="start">';// strat Game
			gameStart += '<header>';
			gameStart += '<h1>Game</h1>';
			gameStart += '<a href="#" class="button">Start Game</a>';
			gameStart += '</header>';
			gameStart += '</div>';
		this.populateDivWithHTML(gameStart);
	},
	displayBoard: function(){
		var gameBoard = '<div class="board" id="board">';//The Game 
		  	gameBoard += '<header>';
		    gameBoard += '<h1>Tic Tac Toe</h1>';
		    gameBoard += '<ul>;'
		    gameBoard += '<li class="players player1"></li>';
		    gameBoard += '<li class="players player2"></li>';
		    gameBoard += '</ul>';
		  	gameBoard += '</header>';
			gameBoard += '</div>';
		this.populateDivWithHTML(gameBoard);
	},
	populateDivWithHTML: function(div) {
		document.body.innerHTML = div;
	},
	gameHandler: function() {
		var button = document.getElementsByClassName('button');
		button.onclick = function() {
			this.displayBoard();
		}
	}

};
GameUI.displayGame();

I want to run the key: gameHandler: function() with onclick event, and which class button is in the Key: displayStart: function()

And gameHandler: function() as well as displayStart: function() are part of my Object const UserInterface

Lets say i do this:

const UserInterface = {
	displayGame: function(){
		this.displayStart();
                this.gameHandler();
	}, ....

But it does not work…

you say:

this.displayBoard(); // `this` value doesn't refer to the originating context

Why?


#4

hi @pantera-bo,

i made a fiddle of your project.
i made two buttons which logs this values for you to compare.
1 which doesn’t use .bind() and another which is bound to its parent object.
open your browser console and check logs whenever button’s clicked.

https://jsfiddle.net/q42o3p4v/


#5

Hi @pseudop thank you very much to reply my question :blush:
and sorry to answer too late.

What I did to solve this problem is:

gameHandler: function() {
		let button = document.getElementsByClassName('button')[0];
		button.onclick = function() {
			GameUI.displayBoard();
		}
	},

I just call the GameUI object and their Object Key : GameUI.displayBoard() to display displayBoard
I don’t know if this solution is ok… but it works. Would you recommend this solution as a one of the alternative solutions?