Events on DOM elements not yet created, in Javascript? - javascript

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.

Related

Is there a way to determine if a function is running in document ready or not?

Is there a way to determine if a function is running in document ready?
I mean something like this:
function myfunction() {
var isinside = //... what to write here?
if (isinside) {
}
}
(It is also possible my (very beginner) concept is not optimal, so I write what I am trying to achieve:
I would like to create a reusable object, what can instantiated in multiple instances within a page (hopefully with one line of JavaScript per instance). However there are things what this object must do in document ready, like attaching event handlers.)
I am not sure why you have a problem here? The calling code is normally responsible for being in a DOM ready handler, or not, not the functions.
You can just put a DOM ready redundantly inside any function, if needed, but this sounds like an odd situation so you need to show the rest of the code.
e.g. any function can have a DOM ready handler:
function myfunction() {
$(document).ready(function(){
// I am inside DOM ready!
// Connect my DOM element events here
});
// Do my other non-element stuff here
}
or, shorter:
function myfunction() {
$(function(){
// I am inside DOM ready!
// Connect my DOM element events here
});
// Do my other non-element stuff here
}
The key here is that DOM ready handlers can be called after DOM ready and they fire immediately.
The downside to this is that you cannot rely on a return value as DOM ready is potentially async.

pass event to eventhandler

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);

call javascript callback explicitly

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');

Clearing a jquery document.ready() call

How do I clear out anonymous functions that are set to trigger via a jQuery document.ready() call?
For example:
<script type="text/javascript">
//some code sets a doc ready callback
$(document).ready(function ()
{
alert('ready');
});
//my attempt to prevent the callback from happening
window.onload = null;
$(document).unbind("ready");
</script>
The alert happens regardless of my attempts to circumvent it. Is there any way to do this?
You'd probably get the most appropriate answer if you described what problem you're really trying to solve.
jQuery doesn't have a publicly documented way to undo or block document.ready() handlers. If you control the code, you can use a global variable and a conditional like this:
var skipReady = false;
$(document).ready(function ()
{
if (!skipReady) {
alert('ready');
}
});
// skip the document.ready code, if it hasn't already fired
skipReady = true;
Or, if you want to hack into jQuery a bit (beyond the documented interfaces), you can do this:
$(document).ready(function() {
alert("ready");
});
// stop the ready handler
$.isReady = true;
You can see this last one work here: http://jsfiddle.net/jfriend00/ZjH2k/. This works because jQuery uses the property: $.isReady to keep track of whether it has already fired the ready handlers or not. Setting it to true makes it think it has already fired them so it won't every do it again.
This works:
$(document).bind("ready", function () { alert("hey!"); });
$(document).unbind("ready");
Seems like a bug to me - all other events in jQuery are able to be unbound. Omitting this one is inconsistent.
Not a direct answer as to the omission, but here's some related info from jQuery docs:
All three of the following syntaxes are equivalent:
$(document).ready(handler)
$().ready(handler) (this is not recommended)
$(handler)
There is also $(document).bind("ready", handler). This behaves similarly to the ready method but with one exception: If the ready event has already fired and you try to .bind("ready") the bound handler will not be executed. Ready handlers bound this way are executed after any bound by the other three methods above.
$(document).ready() is dependent on the onLoad event which is triggered by the browser meaning you can not prevent it from happening. If the alert() is determined by some condition then I would use an if/else statement to decide whether it is called.
Super old question, but came across the need to do this recently to prevent document.ready code I didn't control from running in certain instances. This can be achieved by proxying jQuery's ready function, rather like a test spy. The following will work:
var ready = $.prototype.ready;
// proxy the ready function
$.prototype.ready = function ( fn, allowed ) {
allowed = allowed || false;
if ( allowed ) {
ready.call( this, fn );
}
};
All calls to $( document ).ready will now be ignored. You can override this behaviour by passing true as the second argument: $( document ).ready( fn, true )

Pass function to jQuery .ready() function

I am currently making use of Simon Willson's addLoadEvent function to add functions that I want to run after the load event. I ran into a problem wherein the the function I passed to the addLoadEvent function referenced a div that had not yet been loaded by the DOM and so my action (showing the div) did not do anything. When I changed to using the jQuery $(document).ready function, the div has been loaded by the DOM and I can execute actions with it (make it show up).
So, a couple questions. Why is my function being executed before the DOM has completed loaded using the above function? Is there a way to delay it? The other alternative that I can think of is passing in a function to a jquery equivalent:
function jqueryAddReadyEvent(myFunc)
{
$(document).ready(function()
{
//execute already existing functions
//add a new function to the ready event
myFunc();
}
}
When I try the above code, I get a javascript error "myFunc is not a function". Is there a way to generically pass in a function to the jquery ready function and have it execute? Equivalent to the following:
$(document).ready(function()
{
funcA();
}
$(document).ready(function()
{
funcB();
}
...//more of the same
Replaced with the following:
jQueryAddReadyEvent(funcA);
jQueryAddReadyEvent(funcB);
You can just do:
$(document).ready(myFunc);
to attach functions to the DOM ready event. Here's the fiddle: http://jsfiddle.net/padtE/
If you will require many functions to be added then I suggest you do the following:
Create an array that will old all the functions you want to call.
Add functions to that array as you please.
In the .ready(function() { ... }) call every function in that array.
You're set.
It looks correct to me. Most likely you are calling it with something not a function.
Btw you can shorten this to:
var jqueryAddReadyEvent = $(document).ready
or just use $(document).ready() directly for the same effect, as it specifically does what you want to do, run functions after the load, and is actually shorter.
$(document).ready(funcA);
$(document).ready(funcB);
function jqueryAddReadyEvent(myFunc) {
$(myFunc);
}
jqueryAddReadyEvent(function() {
alert('hello world');
});
Demo: http://jsfiddle.net/AlienWebguy/UzMLE/

Categories