Resolving the Issue with onClick Events in Closures

Secrets of the JavaScript Ninja provides an interesting example:

HTML

<button id="test">Click me!</button>

JavaScript

var button = {
    clicked: false,
    click: function() {
        this.clicked = true;
        console.log("this:", this, "button.clicked?", button.clicked);
    }
};

var elem = document.getElementById("test");
elem.addEventListener("click", button.click, false);

When testing this on http://jsfiddle.net/4hdQF/, the output is false.

After changing the console.log line to ...,this.clicked?", this.clicked)", it works correctly now - see http://jsfiddle.net/YG8ST/.

The book suggests using bind to improve the initial buggy application. But, is replacing button.clicked with this.clicked a valid solution? It appears so, as when the click function is triggered, it references `this` to check if the current button was clicked.

Answer №1

When using this, it is important to note that it is not the same as using button. In the event handler, this will be bound to the DOM node rather than the object.

If you are comfortable with this referring to the DOM node, then feel free to use it. However, keep in mind that the "clicked" property of the button object will not be affected by this code.

To ensure that this in the handler refers to the button object, you can set up the event handler with a bound function:

elem.addEventListener("click", button.click.bind(button), false);

This method guarantees that this in the handler will be the button object, regardless of how the runtime tries to invoke the handler. The function returned from bind essentially overrides the default setting of this.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Show a property from the local storage as an option in ng-options

Within my Angular application, I keep crucial victim data in local storage. This data is then showcased in the view where it can be altered (via a <select>): <h1>Victim #{{victim.numero}}</h1> <label>Victim status</label> &l ...

Interested in building an album app using Django Tastypie and Backbone?

I'm currently working on developing a new album application using django, with two essential django models: class Album(models.Model): name = models.CharField(max_length=100) family = models.ForeignKey(FamilyProfile) created_by = models.F ...

Loading pages asynchronously using Ajax with added interactivity through custom JavaScript scripts

Using jQuery Masonry in conjunction with another JavaScript for voting, here is the code: <div id="contain"> <?php $result = $mysqli->query("SELECT * FROM posts ORDER BY id DESC LIMIT 0, 20"); while($row = mysqli_fetch_array($result ...

Parsing JSON data in JavaScript with multiple objects

I just received a JSON Object from an HTTP request [ { "location": { "name": "Seattle, WA", "lat": "47.604", "long": "-122.329", "timezone": "-7", "alert": "", "degreetype": "F", "imagerelativeurl": "http:&b ...

Modifying an object property within a state container array in React using Hooks' useState

As a React beginner, I decided to create a simple Todo app. This app allows users to add tasks, delete all tasks, or delete individual tasks. The Todo Form component consists of an input field and two buttons - one for adding a task and the other for dele ...

Using importNode in the context of Microsoft Edge involves transferring a

I am facing an issue with a dynamic page that has the ability to change its main div content using a bar button. The pages are mostly static except for one which contains JavaScript (RGraph charts). To make it work, I am currently using the following code ...

Trouble encountered with bootstrap toggling when multiple identical inputs are used

Problem with Bootstrap toggle not working on multiple identical inputs unless the first input is pressed. Even then, not all inputs are checked/unchecked. I've created a small example I want to ensure that when one input is toggled, all others have ...

Utilizing the JavaScript Array.find() method to ensure accurate arithmetic calculations within an array of objects

I have a simple commission calculation method that I need help with. I am trying to use the Array.find method to return the calculated result from the percents array. The issue arises when I input a price of 30, as it calculates based on the previous objec ...

What is the best way to retrieve the duration of an object tag using JavaScript or jQuery?

My goal is to determine the duration and length of only mp4 type videos. Although I used the video tag to retrieve these values, it does not support mp4 files. Despite several attempts, I was unable to get the video tag to play only mp4 files, as it stric ...

How can you reset the chosen option in a Vue.js dropdown menu?

Within my dropdown menu, I have included a button that is intended to clear the selected city. Despite adding an event, the selected option is not being cleared. Can anyone provide insights on what I might be missing? Thank you in advance. Below is the bu ...

Hidden text within a webpage that remains concealed until a specific link is activated

Just getting started with HTML and wanting to add animation to my project. I have a vision of an animation where clicking on an image will split open a half page of text and stuff. It should be similar to this example: ...

What is the connection between {{result}} and $scope.result within AngularJS?

I comprehend the concept of binding a model to an element. An example would be... <pre ng-model="result">. This connection is established through the $scope.result variable. However, how are these two related? {{result}} $scope.result = data; ...

There appears to be an issue with the error handling function within React

I am facing an issue with my error function while checking the browser error, and I am unsure why adding a console.log with the error is causing trouble. I need some assistance in troubleshooting this problem which seems to be occurring at line 29 of my im ...

Distinguishing Features of HTML, Canvas, and WebGL

Is there a way to draw images in WebGL with the same quality as HTML, even when downscaled? I've noticed that scaling down images in WebGL results in poor quality compared to HTML. After reading about 'Handling High DPI (Retina) displays in WebGL ...

What is the reason for Jquery AJAX appending additional path to the relative path?

I am encountering an issue with the following code snippet $.ajax({ url: "search/prefetch", success: function (data) { $(".result").html(data); alert("Load was performed."); }, dataType: "json" } ...

Leverage the power of express-session in your NextJS project

Currently, I am working on developing a login system using NextJS and MySQL. I am looking to implement sessions for user login, but I am unsure of how to integrate express-session with NextJS. Can anyone provide guidance on whether express-session can be ...

Transfer information from one Angular JS page to another pager based on ID

In my use of the mobile angular js UI framework, I am a beginner in angular js and looking to transmit data from one page to another using city id. When a user clicks on a city, the data should be displayed according to that specific city. HOME PAGE: ht ...

javascript - convert a JSON string into an object without using quotation marks

Consider the following example: var mystring = `{ name: "hello", value: 1234 }` var jsonobj = JSON.parse(mystring) The code above will not output anything because the "name" and "value" keys are missing quotes. How can I parse this strin ...

Developing desktop applications with Angular 2 using NWjs

Looking to create an Angular 2 Desktop App using NWjs. Where can I find the entry point? Could someone provide some examples of developing Angular 2 Desktop Apps with NW.js? ...

When examining passwords, Bcrypt returns false

In my application, I am utilizing the Promise interface along with bcrypt. Despite using the same password for comparison, I am receiving a false result. const bcrypt = require('bcrypt'); const saltRounds = 10; const password = 'secret&ap ...