I am trying to use a closure, to call a function when the user scrolls on the document in JavaScript.
Therefore i create the constant scroll and call the inner function via scroll() when the event 'scroll' happens.
I don't get an error when I'm trying to do this with the code below but the inner function doesn't get called for some reason.
const scroll = scrollEvent();
document.addEventListener("scroll", scroll());
function scrollEvent() {
debugger;
var positions = {pos1: 3, pos2: 5};
return function() {
loadContent(positions);
}
}
Thanks in advance for your help.
You've almost the correct code. But the closure is already created when you create scroll variable and call scrollEvent (after that scroll contains a reference to the returned function), hence you have to pass only scroll to addEventListener, because calling it just returns undefined.
Another way is to omit scroll variable, and call scrollEvent in the argument, like so:
document.addEventListener("scroll", scrollEvent());
Now scrollEvent returns the function to use as an event listener, and the closure is created, and positions is available in the event handler when the event fires.
Related
I have a button on which I want to attach an event listener. I also need to pass a extra parameter url to this function. I read about apply and I'm doing the following:
$('#list-button').on('click',postListing.apply([url]));
My problem is that as soon as this script is loaded postListing is called. I am not calling the function anywhere else. I need it to be called only on click.
The difference between bind and call/apply is that bind doesn't call the function immediately much like it loads the data with the variable when needed
You can reformat your code so it looks like this
$('#list-button').on('click', postListing.bind(this, url));
Found a way. It can be done using a closure:
var postListing = function(event, url){
return function(){
//Main functionality wrapped here
};
};
And the event listener setting remains the same:
$('#list-button').on('click',postListing.apply([url]));
I have added an event listener that points to a method of the current object. Because the context of this was lost, I binded the method. From what I understand, .bind(this) creates a new bound function, which means to remove the event listener, I have to keep the bound function in a variable for future use.
MyObject.prototype.addListener = function () {
var checkAnchorBound = this.checkAnchor.bind(this);
//anAnchorElement points to an anchor tag on the page
this.anAnchorElement.addEventListener("click", checkAnchorBound);
}
Now, whenever I click that anchor, checkAnchor runs and everything works perfectly. The problem is removing the event listener because that event listener needs to be removed inside this.removeListener which is called by this.checkAnchor. That means I cannot pass the bound function as a parameter.
MyObject.prototype.removeListener = function (event) {
//I cannot pass checkAnchorBound from MyObject.addListener as parameter
this.anAnchorElement.removeEventListener("click", checkAnchorBound);
}
I tried storing checkAnchorBound in the object so I would not have to pass the variable as a parameter like so:
MyObject.prototype.addListener = function () {
this.checkAnchorBound = this.checkAnchor.bind(this);
//anAnchorElement points to an anchor tag on the page
this.anAnchorElement.addEventListener("click", this.checkAnchorBound);
}
However, addEventListener no longer works. Is there a way to pass checkAnchorBound as a parameter even though my listener is a bound function? If not, is there a way I can store the bound function inside of MyObject?
I have an event binding for the scroll event on a DIV. For debouncing the handler I introduced a function on my model which creates the debounced handler, and I'm binding this factory function in my view.
I would expect that my factory creates the debounced function and knockout will bind that to the event. Instead, it seems like knockout recreates and calls my debounced function at every event trigger, so debouncing doesn't work at all.
My view
<div data-bind="event.scroll: getScrollHandler()"></div>
My model
var viewModel = {
getScrollHandler: function(data, evt) {
return debounceFunction(function(data, evt) {
// dp the actual handling...
});
}
};
I would expect that the getScrollHandler method would execute only once at binding initialization time, and it would bind the returned function.
Instead, it seems like knockout is wrapping it all to a new function so it runs on every scroll event.
How exactly does it work in Knockout?
UPDATE
As I'm using TypeScript and this handler is a member method of a class, I'm limited to this kind of function member assignment, I cannot directly assign the debounced function as a member (or actually I could, but in some uglier way only).
Assuming you have an implementation similar to this one, the idea is it creates a new function which you then use in place of your original function. Try changing your code to this:
getScrollHandler: debounceFunction(function(data, event) {
...
})
This will create the function once and re-use it every time the scroll is activated.
I want to load a function on click event using $.proxy.
If i load the function using the below click event then everything works fine.
click event which is working
$('element').click($.proxy(this.doProcess, this));
click event which is not working
$('element').click(function(){
// Perform other things
$.proxy(this.doProcess, this);
});
As you can see that i want to perform other things on the click event before loading the function. Can you please help me figure out why it is not loading if i use ".click(function()..." instead of simply '.click()..'
Because in the first snippet the click function calls the returned function. In the second snippet you are binding the current this value to the function, but you don't call the returned function. You can use the invocation operator (()) for calling the function:
$.proxy(this.doProcess, this)();
Note that this in the context of the anonymous function (which is the current event handler) doesn't refer to the this keyword's value of the outer context, you can cache the value:
var that = this;
$('element').click(function() {
// Perform other things
$.proxy(that.doProcess, this)(/* arguments go here */);
// | |
// | ----- refers to the clicked element
// ----- reference of the outer context's `this` value
});
Is there a way to parse data to a function from the event listener ?
I have this:
div.addEventListener('mousedown',run(id),false);
function run(e,id){
console.log(id);
}
Thing is it executes straight away. The other problem is - if i want to parse the variable id, and the run function recieves e for the event, how do you parse any thing else =/ It's a bit confusing to work out what order e is (before or after your designated variables that you want to parse)
The current work around so far was to assign id to window so its basically a global... but i'm wondering if parsing via the event is possible at all ?
One way is to create a new listener function in which the id variable is already bound to the value that you want, like this:
function newListener(id) {
var listener = function(e) {
console.log(id);
}
return listener;
}
div.addEventListener('mousedown',newListener(id),false);
newListener(id) defines a new function, in which the value that the id variable had at the time is available inside that function. Then the javascript environment will call that function when the mouse button is pressed.
An event handler does not take arguments directly, you are calling the function run(id), not passing a handler, here is how you pass it (using anonymous function)
https://developer.mozilla.org/en/docs/DOM/element.addEventListener
div.addEventListener('mousedown',function(e){
doSomething(id);
},false);
function doSomething(id){
console.log(id);
}