I am trying to use an event listener for when I click on an object.
My HTML file
<div id="left">
</div>
<div id="right">
</div>
My JavaScript file
function changeImg(which)
{
if(which === "left")
{
alert("left");
}
else
{
alert("right");
}
}
var leftClick = document.getElementById("left");
leftClick.addEventListener("click", changeImg("left"), true);
var rightClick = document.getElementById("right");
rightClick.addEventListener("click", changeImg("right"), false);
Here is my JSFiddle, https://jsfiddle.net/pb4759jh68/zqzdhcnw/1/
My question is, why does my function run as soon as I run the page, rather than waiting until I click on either the left or right div?
Thanks!!!
The problem is with these 2 lines:
leftClick.addEventListener("click", changeImg("left"), true);
rightClick.addEventListener("click", changeImg("right"), false);
The changeImg function is being called immediately, since you are using the parenthesis after the function name. You can do this to prevent it:
var leftClick = document.getElementById("left");
leftClick.addEventListener("click", function() {
changeImg('left');
}, true);
var rightClick = document.getElementById("right");
rightClick.addEventListener("click", function() {
changeImg('right');
}, false);
Here, we pass an anonymous function as a refernce, which will be called by the browser upon the click event. Inside the function, we are calling our own function changeImg.
addEventListener requires a function as second argument. You're currently evaluating the handler function changeImg("left"), and assigning the result as the event handler. Try this instead:
var leftClick = document.getElementById("left");
leftClick.addEventListener("click", function() { return changeImg("left") }, true);
var rightClick = document.getElementById("right");
rightClick.addEventListener("click", function() { return changeImg("right") }, false);
Related
Im using jQuery too. Im trying to call one method keyPressEvent on pressing enter button. Whats wrong in the code
var AplOperations = function() {
// this function i want to call when an enter button is pressed
this.keyPressEvent = function() {
// my code goes here
}
}
var myOpr = new AplOperations();
document.onkeyup = myOpr.keyPressEvent();
You don't need the () after myOpr.keyPressEvent, other wise the function will be executed intermediately.
Working example: (click first on the panel for the focus)
var AplOperations = function() {
// this function i want to call when an enter button is pressed
this.keyPressEvent = function() {
// my code goes here
var elem = document.getElementById("test");
elem.innerHTML += "key pressed<br>"
}
}
var myOpr = new AplOperations();
document.onkeyup = myOpr.keyPressEvent;
<div id="test"></div>
You have to wait for the keyup and execute your things in callback. Right now it executes when the script gets execute.
document.onkeyup = function () {
myOpr.keyPressEvent();
}
Updated Demo
This line is wrong:
document.onkeyup = myOpr.keyPressEvent();
Using brackets immediately calls the function and the result is assigned to the onkeyup handler. If you remove the brackets your function will be assigned as a handler
I'm adding checkboxchange event to checkbox here. (moveButton is a checkBox because im using CSS checkbox hack)
var self = this;
this.moveButton.addEventListener("change", function(e){self.toggleMove(e, self)});
if the checkbox is checked it adds an eventListener to body.document
DR.prototype.toggleMove = function(e, self){
if(self.moveButton.checked){
document.body.addEventListener("click", function bodyEvent(e){self.removeableEventHandler(e, self)}, false);
}else{
console.log("unchecked");
document.body.removeEventListener("click", function bodyEvent(e){self.removeableEventHandler(e, self)}, false);
}
}
if i don't wrap self.removeableEventHandler in a function i am unable to attach self to the function, but when i wrap it in a function i will be unable to remove the event when the checkbox is unchecked.
DR.prototype.removeableEventHandler = function(e, self){
console.log(e.clientX, e.clientY);
self.ele.style.top = e.clientY + "px";
self.ele.style.left = e.clientX + "px";
};
So it seems to be like I'm having a bit of a scope conundrum here. Not sure how to fix it. I'm trying to make a form moveable when the checkbox is checked and then removing the move event when the checkbox is unchecked.
removeEventListener works by passing the original function reference. If you pass a copy it wont work.
You can do:
DR.prototype.toggleMove = (function () {
var boundBodyEvent;
function bodyEvent(e) {
this.removeableEventHandler(e);
}
return function (e) {
if (this.moveButton.checked) {
boundBodyEvent= bodyEvent.bind(this);
document.body.addEventListener("click", boundBodyEvent, false);
} else {
document.body.removeEventListener("click", boundBodyEvent, false);
}
};
}());
I don't think you need to pass self around, that seems strange to me. I'm using bind to override the this in bodyEvent to refernce your DR instance instead of the DOM Element.
I'm also using immediate invocation to avoid having to put the bodyEvent in the global scope.
Alternatively, you could also not bother removing the event listener and have a switch inside the event listener:
DR.prototype.init = function () {
var self = this;
document.body.addEventListener("click", function (e) {
if (self.moveButton.checked) {
self.removeableEventHandler(e);
}
}, false);
}
removeEventListener callbak function need to be reference to the same function as in addEventListener, try this:
function bodyEvent(e) {
self.removeableEventHandler(e, self);
}
DR.prototype.toggleMove = function(e, self) {
if (self.moveButton.checked) {
document.body.addEventListener("click", bodyEvent, false);
} else {
console.log("unchecked");
document.body.removeEventListener("click", bodyEvent, false);
}
};
I'm trying to remove an event listener after a function has been called. But the event listener for "keyup" stays attached to the body, no matter what I try. What is wrong with the code?
function displayImage() {
//this is a simplified version of the code
var outerFrame = document.createElement('div');
outerFrame.className = 'popup-outer';
document.body.appendChild(outerFrame);
document.body.addEventListener('keyup', hideImage.bind(outerFrame), false);
}
function hideImage(e) {
if (e.keyCode === 27) {
// this doesn't work, it stays attached to the body element
document.body.removeEventListener('keyup', hideImage, false);
document.body.removeChild(this);
}
e.preventDefault();
}
It's because technically
hideImage.bind(outerFrame)
is different from
hideImage
because the first one returns a copy of the function hideImage.
So when you try to unbind hideImage, the event manager does not find it because it registred a copy of it and thus nothing is removed :-/.
EDIT :
In your case, I guess you have no other choice but keeping track of your listeners. I went ahead and made this quickly, it should fix your problem.
var listeners = {};
function createDiv() {
var outerFrame = document.createElement('div');
outerFrame.className = 'popup-outer';
return outerFrame;
}
function displayImage() {
var div = createDiv();
bindEvent(div);
document.body.appendChild(div);
}
function bindEvent(el) {
var handler = function(e) {
hideImg.call(el, e);
}
listeners[el] = handler;
document.body.addEventListener('keyup', handler, false);
}
function hideImg(e) {
if (e.keyCode === 27) {
// listeners[this] refers to the "private" handler variable we created in the bindEvent function
document.body.removeEventListener('keyup', listeners[this], false);
delete listeners[this];
document.body.removeChild(this);
}
}
Example:
domNode.onmouseover = function() {
this.innerHTML = "The mighty mouse is over me!"
}
domNode.onmouseover = function() {
this.style.backgroundColor = "yellow";
}
In this example the text won't change, but the thing is also that I don't always know what was assigned before, so is there a way to tell to js: Run everything that was eventually assigned without knowing what was that and then run my function?
It's possible to do this by passing the current event handler to the new handler:
domNode.onmouseover = function()
{
console.log('first handler');
}
domNode.onmouseover = (function (current)
{
return function()
{
current();//call handler that was set when this handler was created
console.log('new handler');
};
})(domNode.onmouseover);//pass reference to current handler
See this fiddle, to see it in actionYou can keep on doing this as much as you want/need:
domNode.onmouseover = function()
{
console.log('first handler');
}
domNode.onmouseover = (function (current)
{
return function()
{
current();
console.log('second handler');
};
})(domNode.onmouseover);
domNode.onmouseover = (function (current)
{
return function()
{
current();
console.log('third handler');
};
})(domNode.onmouseover);
This will log:
first handler
second handler
third handler
That's all there is to it!
First of all, place it in a document.ready. (not sure if you done that)
If you want 2 actions for one action place it in once function.
You can also create 2 functions and call them in your mouseover.
$(document).ready(function(){
domNode.onmouseover = function() {
this.innerHTML = "The mighty mouse is over me!"
this.style.backgroundColor = "yellow";
}
});
I've got this self-executing function, which adds event listeners to a series of links. But the event listeners are automatically firing when the page loads, as opposed to onmouseover/out. Have I got the syntax wrong? How do I stop them autofiring?
;(function(){
var menuLink = $('.navItem');
var menuItem = $('.menuLinks');
for (a = 0; a <= 5; ++a) {
menuLink[a].addEventListener('onmouseover', linkChanger(), true);
menuLink[a].addEventListener('onmouseout', linkChanger(), true);
}
function linkChanger(event){
if (menuItem[a].style.color == "white") {
console.log("This is white")
menuItem[a].style.color = "black";
}
else {
console.log("This is black");
menuItem[a].style.color = "white";
}
}
})()
menuLink[a].addEventListener('onmouseover', linkChanger, true);
menuLink[a].addEventListener('onmouseout', linkChanger, true);
When you write linkChanger(), it is executing the function and giving the result to the Listener. Either wrap it with function() { linkChanger(); } or replace with linkChanger. The first option allows you to pass arguments and run other functions too.