Tribes
Tribes

Reputation: 35

Event listener set on the wrong elment

I was wondering why this javascript doesn't work:

var element = document.querySelector('#element1');
var button= document.querySelector('#button1');
button.addEventListener('click', function() {
    element.doSomething();
});

var element = document.querySelector('#element2');
var button= document.querySelector('#button2');
button.addEventListener('click', function() {
    element.doSomething();
});

Both of the buttons are doing something to "element2".

Is it something like the event listener keeps a pointer to the variable instead of its value ?

Thanks for your answers

Upvotes: 0

Views: 515

Answers (4)

Mr. Polywhirl
Mr. Polywhirl

Reputation: 48600

You can wrap your block-level code with an anonymous; self-executing function.

This is similar to when you wrap { /* {{code}} */ } a block of code, with curly-braces, in Java. You can have duplicate variables, as long as they exist in their own block.

That way, the variables can be the same. You should really create a separate function and pass in the selector IDs; especially if they are doing the same thing.

(function() {
  HTMLDivElement.prototype.doSomething = function () { 
    this.innerHTML = this.innerHTML == 'Hello' ? 'Goodbye' : 'Hello';
  }
}());

(function() {
  var element = document.querySelector('#element1');
  var button = document.querySelector('#button1');
  button.addEventListener('click', function() {
    element.doSomething();
  });
}());

(function() {
  var element = document.querySelector('#element2');
  var button = document.querySelector('#button2');
  button.addEventListener('click', function() {
    element.doSomething();
  });
}());
div {
  display: inline-block;
  width: 5em;
  height: 2em;
  border: thin solid black;
  text-align: center;
  line-height: 2em;
  margin-bottom: 0.25em;
}
<div id="element1">?</div>
<input type="button" id="button1" value="Button 1" />
<br />
<div id="element2">?</div>
<input type="button" id="button2" value="Button 2" />

You should try this.

function addButtonClick(btnSelectorId, elSelectorId) {
  document.querySelector(btnSelectorId).addEventListener('click', function() {
    document.querySelector(elSelectorId).doSomething();
  });
}

addButtonClick('#button1', '#element1');
addButtonClick('#button2', '#element2');

Upvotes: 1

Bubble Hacker
Bubble Hacker

Reputation: 6723

You are using the same variable for both the elements and so the last declared variable is the one that will be used.
For example:

x = "Hello";
x = "World";
console.log(x); //This will print out "World"

You need to declare them as different variables. Example with your code(Notice I changed the second element):

var elment = document.querySelector('#element1');
var button= document.querySelector('#button1');
button.addEventListener('click', function() {
    elment.doSomething();
});

var elment2 = document.querySelector('#element2'); //Changed to elment2
var button2 = document.querySelector('#button2'); //Changed to button2
button2.addEventListener('click', function() {
    elment2.doSomething();
});

Upvotes: 0

JLRishe
JLRishe

Reputation: 101662

The problem is that you are referencing the elment variable inside your event handler functions. When you assign a new value to elment, you change its value and this affects both handlers.

The solution: use a different variable name for each:

var element1 = document.querySelector('#element1');
var button = document.querySelector('#button1');
button.addEventListener('click', function() {
    element1.doSomething();
});

var element2 = document.querySelector('#element2');
var button = document.querySelector('#button2');
button.addEventListener('click', function() {
    element2.doSomething();
});

Or better yet, perhaps, do away with the closure variables altogether and just query as needed:

document.querySelector('#button1').addEventListener('click', function() {
    var element = document.querySelector('#element1');

    element.doSomething();
});

document.querySelector('#button2').addEventListener('click', function() {
    var element = document.querySelector('#element2');

    element.doSomething();
});

Upvotes: 0

Vaibhav Jain
Vaibhav Jain

Reputation: 727

Try this, you have given same name to both the elements & buttons which is overwriting the previous one :

var element1 = document.querySelector('#element1');
var button1= document.querySelector('#button1');
button1.addEventListener('click', function() {
    element1.doSomething();
});

var element2 = document.querySelector('#element2');
var button2 = document.querySelector('#button2');
button2.addEventListener('click', function() {
    element2.doSomething();
});

Upvotes: 0

Related Questions