So I am trying to remove my addEventListener function using the removeEventListener function. I've read alot about it needing to include an handler function, which I have done.
One of the issues is that I am running into is that I would like to remove the eventlistener when I change an input using google's searchbox. Don't mind google but really all what is happening is it is identifying when the input value has changed and providing new results. So a bit of code
var input = document.getElementById('search-input');
var searchBox = new google.maps.places.SearchBox(input);
google.maps.event.addListener(searchBox, 'places_changed', locationChange);
function previousButtonFunction(){
//Does something here and does not return anything. Lets just say it places markers all over the map
}
function locationChange() {
var previousButton = document.getElementById('previous');
previousButton.removeEventListener('click', previousButtonFunction());
previousButton.addEventListener('click', function () { previousButtonFunction()})
};
So this code looks like it doesn't make any sense to you probably, but what I am trying to get is that on the first input it would run the add event listener, and not run the removeEventListener function. Once the value of input has changed, I would like to remove the current listener and re-identify the previousButton with a new addeventlistener.
At the first go, I realize that the function of previousButtonFunction() is run, which I thought that it would only run if there was an identified listener. So the first question is the removeEventListener function supposed to run if the eventlistener wasn't added? Second how can I remove the addEventListener without running the function? Would I need to pass in a tracking identifier such as true => run it/false => don't run?
Thanks any help is greatly appreciated
Don't use ()after the function name. You want to pass only a reference to the function. Putting() after the name calls the function and passed the return value. This is a very common mistake.
Change this:
previousButton.removeEventListener('click', previousButtonFunction());
to this:
previousButton.removeEventListener('click', previousButtonFunction);
The same goes for .addEventListener(). Don't put () after the function name unless the function returns another function that you want to be the listener.
FYI, it's a little unclear why you're attempting to remove and then add back the same exactly same listener function. Unless there are multiple listeners on that object and you're trying to change the order of listeners, this is essentially a noop.
Related
Here's a function where it suppose to work when I click a "button
but surprisingly it immediately invoked without calling!
const show_card = (shopping_card_checkout) => {
console.log("ali el-deeb");
};
document.querySelector('.fa-shopping-cart').addEventListener('click', show_card()) ;
If I tried to redo the code after the event listener it says reference error as I called the function before declaration.
Help a beginner.
Saw your post request in JS FB group and thought I'd answer here.
First you need to use document.ready or make sure that all js is loaded as last cause else the element might not yet exist. This is not th cause of your problem btw. The problem I explain as last but some advice. You use a class and querySelector, querySelector will fetch the first element in the document and if you want all elements returned you need querySelectorAll and this is not unique or would you like to bind the same action and functionality to many elements? So better would be to use the unique id of an element and use something like:
const myElement = document.getElementById("idName");
myElement.addEventListener("click", myFynction);
const myFunction = () => console.log("Clicked");
The real cause of your issue
You bind the function to the click event and bind it with () behind it and that triggers the execution cause now you don't bind the function but the result of the bound function, you can't pass parameters like that to a bound event. You will need to fetch them inside the function cause only event and a callback can be triggered.
So your working code is:
const show_card = (shopping_card_checkout) => console.log("ali el-deeb");
document.querySelector('.fa-shopping-cart').addEventListener('click', show_card);
And if only one return or one statement inside an arrow function there is no need for the curly brackets and no need to use return since it will automatically return the result of the oneliner.
I am currently writing a program in JS using jQuery, which is basically a checkers game.
I am using jQuery's .on() and .off() functions to create events for each of the pieces. What happens is that the program will loop through each of the pieces and will set a function to be called when the piece is clicked. This function will then show the player the available moves that the piece can make.
This is setup using a for-loop and this code:
$("#" + String(playerPositions[i])).on('click', function() {movePiece(validMoves, this)});
This passes the valid moves of that piece as well as the id of that piece to the movePiece function which then deals with highlighting the moves.
The problem lies in my "clean up" function, where I want to remove the onClick handler from all the pieces once a move is made. I use this code:
var elements = $('.' + classToClean);
//clean off the onclick
elements.off("click"); <-- this doesn't work
//clean off the classes
elements.removeClass(classToClean);
The strange thing is that a) the .removeClass function works perfectly, and b) the onClick attribute only is removed from the piece that I have just moved.
I have tried using attaching an empty function to the piece, but this did not work. I also cannot use $('.validPieces').on('click', function () ... ) because I need to pass variables unique to the piece with each piece's onclick.
Thanks in advance for any help, and I apologise about the wall of text but I wanted to make sure everything was clear.
Using .off('click') should remove all event handlers of that type. If that doesn't work it is likely the element(s) you are removing from don't match the ones they were attached to.
If that removes more than you want, you will need to include a reference to your handler in the .off() call. To preserve the different validMoves variable for each call you will need to use a closure:
function move(validMoves) {
return function() {
movePiece(validMoves, this);
}
}
// within your for loop
keepMoveFn[i] = move(validMoves);
$("#" + String(playerPositions[i])).on('click', keepMoveFn[i] );
// elsewhere in your code:
//clean off the onclicks
keepMoveFn.forEach(function(fn) {
el.off("click", fn );
}
Note that you will need to either keep a reference to the move function or have access to it when you call the .off() function. In the snippet above I assume you are keeping an array of functions that you can then later iterate to remove the click events.
I am a beginner in javascript. and have no experience in programming, at all.
So I'd like you to be generous to beginner.
And here is my question.
I'm trying to code javascript unobtrusively.
So I put in all of my js codes into external js file. for example : test.js
and deleted these codes. to do unobtrusive js coding. for example :
and I tried to use these 2 methods :
variable.onclick=test(arg1, arg2);
variable.addEventListener('click',test(arg1, arg2),true);
but these triggers didn't work.
to put it delicately, function test(arg1, arg2) worked right after dom loding finished. regardless of activating 'click' trigger.
So I spent several hours solving this problem, and finally got a solution. this is it.
variable.onclick = function(){
variable.addEventListener('click',test('arg1','arg2'),true);
}
I wanna know why first two methods didn't work, and why that solution works well.
I solved the problem, but don't know why, and how...
In JavaScript, when you reference a function by name and follow that reference by a parenthesized list of arguments, that means that you want to call the function, right then and there. Thus a statement like
variable.onclick=test(arg1, arg2);
will assign to the "onclick" property the value obtained by calling the "test" function. In other words that statement means
Please call the function "test" passing it "arg1" and "arg2", and assign whatever it returns to the "onclick" property of the object referenced by "variable".
An event handler must be a function, however, and your "test" handler probably returns either nothing, or something that's not a function. So it didn't work.
Your solution, however, is also incorrect. You're successfully assigning a function to the handler property, but your function is itself installing another event handler. There's no reason to do that here, and in general setting up event handlers from within other event handlers is a suspicious practice. All you need is:
variable.onclick = function() { test(arg1, arg2); };
variable.onclick requires a function declaration by design. In your case you could have just done
variable.onclick = function(){
test(arg1,arg2);
};
The way you did it won't work because you're not giving the click handler any instructions. The corrections I have made say that when the variable (the one with the click handler attached) is clicked trigger this function that will in turn trigger the test function.
Same thing goes for the second one
variable.addEventListener('click', function(){
test(arg1,arg2);
});
This works again because you are saying when this variable is clicked run the function that will trigger the test function.
Basically you are trying to assign the result of running a function, the test function as a task for the click handler to run. This won't work except maybe your test function returns a function that contains code that you want to run when the click event is triggered. Hope this helps.
I have a string I am using to get a pointer to my function. Then I want to use this function to set an onclick while passing arguments to the function.
var functionPtr = window[stringFunction];
pTag.onclick = function () {
functionPtr(args);
};
When I do this, the onclick event tries to call "functionPtr(args)" instead of calling the function I'm pointing to. Using break points, I can see that functionPtr is definitely a reference to the function I want when I assign the onclick function. What steps am I missing here?
Thanks in advance!
I couldn't get my above attempt to work so I decided to set the onclick event using the setattribute() function instead.
var stringFunction = 'myFunction(args)';
pTag.setAttribute('onclick', stringFunction);
This seems to do the trick. Its important to note this doesn't work for earlier versions of IE, but I'm only required to work with IE 10 and up so this works for me.
I am trying to change the value of the onblur attribute of a text input after the page has finished loading.
When I do the following, it simply fires the function:
ip.onblur = stopCalcUpInt(this,10);
When I do the following, I have success:
ip.onblur = function onblur(event){stopCalcUpInt(this,10);}
Unfortunately, the whole point of this is to be able to dynamically set the second parameter for stopCalcUpInt(). If I hard code a value for it... it works fine... but any attempts to pass varibles to this fails... instead of putting the value of the variable as the second param it just puts the plain text of the variable name itself. Here is ideally what I am TRYING to do:
ip.onblur = function onblur(event){stopCalcUpInt(this,this.value);}
In this example, when I alert the ip.onblur I get:
It depends what this is intended to refer to. In an event handler this refers to the element on which the event is being handled. If that's what you want then your code looks good as written; this will point to ip.
If you intend this to refer to the this from outside the event handler and not ip then try this:
var self = this;
ip.onblur = function(event) { stopCalcUpInt(self, self.value); };
The answer to getting this to work was super easy, yet not overly obvious. Instead of:
ip.onblur = function onblur(event){stopCalcUpInt(this,this.value);}
I did this:
ip.setAttribute('onblur','stopCalcUpInt(this,\'' + ip.value + '\');');
Works perfectly... no more banging my head against the wall! Yay!
ip.onblur = function() {stopCalcUpInt(this,this.value);}
ip.onblur is an event handler... i.e. it's a function
Now, when you alert a function, FF will show you the source code for that function (if it's user defined).
That is why you're seeing the plain text of the variable name.
For an event handler, this is the element that is currently handling the event. So, if you're setting the onblur handler of an input box, you will have access to the contents of that input box.
The code sample that you provided:
ip.onblur = function onblur(event){stopCalcUpInt(this,this.value);}
should work correctly. Try
ip.onblur = function onblur(event){alert(this.value); stopCalcUpInt(this,this.value);}
if you want to be sure
Is stopCalcUpInt expecting a number in the second parameter? The value attribute will return a String, while in your hardcoded example you're passing a number type. Try this:
ip.onblur = function onblur(event){stopCalcUpInt(this,this.value * 1);}
As explained in QuirksMode:
Since multiplying assumes numbers,
JavaScript makes the string a number,
if possible.