I have two functions, one is for expanding tree view (i.e. ExpandAll()) and second one is for removing particular type of elements from that tree view (i.e. RemoveAbElements()).
ExpandAll() method checks if there are child nodes under the selected node. If not then it retrieves the child elements by ajax call. So now I am calling these methods as follows :
function(){
ExpandAll();
RemoveAbElements();
}
Now my problem here is, there is a callback in ExpandAll() method and it gets called for each child node expanded (which is expected). Now here the callback gets called even after the execution of RemoveAbElements() method. I want to execute ExpandAll() method and all of its callbacks before RemoveAbElements() execution. I tried lots of things for this but none worked. please help.
There could a be lot of ways you could be approaching.
One way could be, passing the RemoveAbElements itself to ExpandAll.
So you could be passing it as
ExpandAll(RemoveAbElements);
or, When you don't want to call RemoveElements, as :
ExpandAll();
And ExpandAll could be modified to accept the callback :
ExpandAll(callbackFunc) {
//... Do Work Here
if(callbackFunc) callbackFunc();
}
Or use triggerhandler & on if there is a jquery object, as suggested by slinky2000.
If I've understood you correctly you need to add a listener to EXpandAll() and when it's finished everything call RemoveAbElements()
I would look at jquerys custom event triggering:
http://api.jquery.com/trigger/
// Listen for finish
$('#tree').on('customFinishedEvent', function(event) {
alert('finished');
});
// On finished loading and expanding
$("#tree").trigger('customFinishedEvent');
Related
I'm having trouble understanding event listeners and what variables they send to the function they call.
For example, I added an event listener to this cell with the intention of calling a function which checks if the mouse is pressed down while moving over an element:
cell.addEventListener("mousemove", cellControl);
function cellControl(e) {
if (e.buttons == 1) {
// Do things
}
}
I was able to make this function work by finding other stack overflow answers but I don't understand why it works. The event listener calls cellControl without passing any variables, but the function cellControl receives an object anyways which I can check for data.
Why did the event listener send this data, and how can I find out what data different event listeners send to the functions I call? I read through this page but couldn't find the answer.
the callback accepts a single parameter: an object based on Event describing the event that has occurred
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#the_event_listener_callback
The parameter is a JavaScript Event Object. You can find the properties here
https://developer.mozilla.org/en-US/docs/Web/API/Event#properties
The callback function you supply to the addEventListener function can be an anonymous function. It would look like this:
cell.addEventListener("mousemove", function(e){
cellControl(e);
});
That can be useful if you want to supply other arguments to the callback function in addition to the event object:
cell.addEventListener("mousemove", function(e){
cellControl(e, anotherArgument);
});
You can find more about the event object as mentioned in the answer from Michael. I also find it very useful to console.log the event object or just certain properties of it. For example:
function cellControl(e) {
console.log('e', e);
console.log('e.buttons', e.buttons);
if (e.buttons == 1) {
// Do things
}
}
Now if you look at the console tab in your browser's developer tools (Ctrl Shift K in Firefox) you will see the information about the event object you want so long as you mouseover the relevant element in your web page.
To address your question,
how can I find out what data different event listeners send to the functions I call?
The addEventListener() method (ie. function) will always send the event object to the callback and nothing else. The event object will be different for almost every case but the properties will be (largely or possibly totally???) the same. The values of the properties will be different of course.
So, I am familiar with the fact that you cannot use a callback function on jQuery's .css function. Instead, I used the setTimeout function:
$('#header-nav').css({'left': leftBstr});
posBstr = '.level' + posB.toString();
setTimeout(function(e){
$('#header-nav ul' + posBstr).removeClass('menu-active');
}, 300);
This code is meant for a mobile menu animation. There are two typed of buttons:
go further into the menu (child categories)
go back (parent category)
But, when using the setTimeout function, when I click too fast, the menu disappears, because of the removed class menu-active.
I already tried putting the setTimeout function inside a var, and use the clearTimeout function, but that did not work.
My question: is there another way to recreate the callback function on the .css function, without using setTimeout?
You can try to use the promise
The .promise() method returns a dynamically generated Promise that is resolved once all actions of a certain type bound to the collection, queued or not, have ended.
$('.element').css("color","yellow").promise().done(function(){
alert( 'color is yellow!' );
});
I'm still confused sometimes by the way events are handled. I just wondered how to pass the event to it's handler.
The following example just works fine:
$(document).on('click', "div#foo", function(event) {
event.preventDefault();
});
But how to pass the event to an handler specified by name, like:
// this obviously wont work
$('div#foo').on('click', fooClick);
function fooClick(event){
event.preventDefault();
}
Thanks for your insights!
Your second example is exactly how to do it and that will work just fine.
It is the responsibility of .on() to set up the arguments to the callback it calls and what is passes has absolutely nothing to do with how you declare your callback. The first argument to the callback function will be the event object no matter how the callback is declared.
So, this will work just fine:
function fooClick(event){
event.preventDefault();
}
// this works just fine
$('div#foo').on('click', fooClick);
Working demo: http://jsfiddle.net/jfriend00/BWKde/
What's important to understand is that when you pass fooClick as the second argument to .on(), you are just passing a function reference. It is .on() who decides how to call that function reference and what to pass it.
FYI, your selectors will generally perform better if you pass just #foo, not div#foo unless you specifically want to only match #foo if it's in a div tag. Since id values can only be used once in a given page, you usually don't need to qualify them further and doing so just makes more (unnecessary) work for the selector engine.
your code is ok,
check at http://jsfiddle.net/9266U/ and read more at https://api.jquery.com/on/
$('div#foo').on('click', fooClick);
function fooClick(e){
alert("it work, nevrx");
e.preventDefault();
}
Javascript is synchronous, try to put it like this:
function fooClick(event){
event.preventDefault();
}
$('div#foo').on('click', fooClick);
I have a Javascript module the following Javascript:
EntryController = function$entry(args) {
MainView();
$('#target').click(function() {
alert('Handler called!');
});
}
MainView() has a callback that creates the #target button. Because of the callback the code will pick up and run through the rest of the code $('#target') ... before #target is created. If this is the case the event is never hooked up to the #target. If I put a breakpoint at $('#target') that'll give the callback enough time to return and build the #target, when I press play everything works as expected.
What's the best way to deal with this? I would like all events to take place in the controller so it can choose which view to send it to.
I was thinking about placing the entire $('#target').click ... inside MainView() and instead of alert('Handler called!'); I'd put a references to EntryController.TargetEventRaise(), but that started to look a bit like steady code. What's the best way to approach this?
You're looking for jQuery's live event handlers, which will handle an event on every element that matches the selector, no matter when the element was created.
For example:
$('#target').live('click', function() {
alert('Handler called!');
});
Alternatively, you could make the MainView function itself take a callback, and add the handler in the callback. You could then call the callback in MainView inside of its callback.
when i use jquery to create an element(a div, for example) in a callback function, it doesn't allow me to manipulate the newly created element outside the callback function, how can I get around this?
here is the example:
$.get('menu.xml',function(data){
//create a new element with an ID called "#newElement"
})
//I can't select the element outside the callback function so the following code dosen't work:
$('#newElement').css('background','black');
You can select it outside, but not yet, that $.get() callback takes some time to run (it has to get the data from the server, the callback happens later, when that finishes), so when you do this:
$('#newElement').css('background','black');
That element isn't there yet (and so the selector doesn't find anything...it's running before that callback creating it does), you need to wait until the callback finishes before continuing any code that needs elements created by it. Like this:
$.get('menu.xml',function(data){
//create a new element with an ID called "#newElement"
//kick off stuff that uses "#newElement"
$('#newElement').css('background','black');
});
$.get('menu.xml',function(data){
//create a new element with an ID called ".newElement"
$('<div/>').val(data).attr('id','newElement').css('background','black').append('#container');
})
Try modifying the element within the callback, also try using the class instead of the id
Judging from the code you've shown, it seems your trying to manipulate '#newElement' before it exists. The reason for that is '#newElement' is created in the callback of '$.get'.
Its important to remember that asynchronous functions in javascript don't cause the thread to wait, this is why callbacks exist. So, before your callback function for '$.get' has even been executed, you are trying to manipulate '#newElement'.
For instance, if you adjust your code to:
$.get('menu.xml',function(data){
//create a new element with an ID called "#newElement"
....
$('#newElement').css('background','black');
})
You will find that it works.