Animate something that doesn't exist on page load - javascript

Ajax sets up a scenario and jQuery then plays it out. The element does not exist before the page is loaded. I need a way to Animate something that was dynamically added to the page.
Something like:
$(document).on("animate", "div", function (){});
Does anything like this exist?
Okay, there seems to be some confusion, I am using queue() this isn't the issue creating it or doing something after I have the ajax return. After the Ajax the program builds and inserts imgs with specific IDs into the page. I need to reload the dom or something so that I can then animate the objects that were inserted into the page.
I have tested the animated on JSfiddle and they work fine, so my only assumption is that because these objects are not part of the initial dom they will not animate and thus I need the DOM to reload.

All you have to do is animate it with the proper function, like:
$("#nonexistent-element").animate({
right: '10%'
});
and it will animate once #nonexistent-element exists, regardless of whether it existed at page load. You only need to use on() when you want to bind an event to an element that does not exist on page load.
Working jsfiddle: http://jsfiddle.net/emFpw/26/

When the content is loaded via Ajax, we need to bind the events for them to work or we can use the live/on methods of jQuery which will bind the events to either parent/document depending on what we want.
Either of the two techniques ie binding when the content is loaded or using live/on should result in the event being triggered.
For ex: Once the content in inserted we can do as suggested by Lrdwhyt in the above answer.
Or we bind the element before its loaded like
$("#non-existing-elem").live("click",function(){
$(this).animate({right:'10'});
})

Related

Using JQuery to modify data written to document by functions

Most of my html is data that is provided via a Jquery request. It is written to the page by inserting it into a "main" div like such:
$("#main").html(passedData);
}
The page works great, but now i'm having problems trying to add any javascript to that data that is written to the div.
Namely I have tables that are inserted into the div and I am trying to write scripts that hide certain cells when others are clicked. I've used http://jsfiddle.net/ to make sure that all of my JS is correct, but for some reason it seems like the JS functions don't see that data in the div and won't manipulate it.
Is there anything I'm missing? When writing data to a page like this do you have to do certain things to reference that data with javascript?
You have to attach event handlers to those "future" elements like this:
$("#main").on("click", ".myelement", function(){
// Do something
});
Read more here. Also, it would be a lot easier if you posted your actual code.
It's hard to troubleshoot without the actual code, but I'm almost certain the problem is that when your jQuery code is executed, the elements that were pulled in through AJAX didn't exist. Therefor, no events will be attached to them.
You should look into using jQuery's .on() event handler. Attach it to a parent element that exists when DOM-ready is fired, and you can manipulate any elements inside it that were pulled in dynamically.

How do I hide all my label tags in my jQuery Mobile site in an accessibility friendly way?

I am trying to hide all the label tags on my jQuery Mobile site in an accessibility friendly way. To this end, I am using javascript to apply the class ui-hidden-accessible to every label tag on my site per documentation (http://jquerymobile.com/test/docs/forms/docs-forms.html).
However, my javascript is not working.
Here is a Fiddle demonstrating how the label tag still appears.
http://jsfiddle.net/tW4Xu/
Why is it not working? I have also scrutinized other jQM event handlers such as pageinit and pagecreate:
http://jquerymobile.com/test/docs/api/events.html
My javascript to hide label tags:
// done after page is loaded
$(document).on("pageshow", "label", function(event) {
$(this).addClass("ui-hidden-accessible");
});​
It seems like you have a few things going wrong here, although I'm not sure how much of it is coming from the jsfiddle summary and how much is in your full code.
The first thing to note is that 'pageshow' is a page transition event. It seems like you might want to use 'pageinit' instead. Here's how the jQM docs describe it:
Triggered on the page being initialized, after initialization occurs. We recommend binding to this event instead of DOM ready() because this will work regardless of whether the page is loaded directly or if the content is pulled into another page as part of the Ajax navigation system.
$( '#aboutPage' ).live( 'pageinit',function(event){
alert( 'This page was just enhanced by jQuery Mobile!' );
});
Note also here that 1) the event is being bound with live() instead of on() (no idea if there's a difference), and 2) it is being attached to a specific id for a jQM 'page'. This is part of what is missing in your jsfiddle example. There aren't any named jQM pages. jQM kind of messes up the whole idea of a page being ready, since everything is in one html file and then gets chunked out using ids and inserted via AJAX.
And so finally: Even though jQM says not to, if your goal is to add this class to every single label on every single jQM page, I would use good-old $(document).ready() and then use $.each() to change them all in one go. Again, from the jQM docs:
However, in jQuery Mobile, Ajax is used to load the contents of each page into the DOM as you navigate, and the DOM ready handler only executes for the first page. To execute code whenever a new page is loaded and created, you can bind to the pageinit event.
So there isn't anything evil about $.ready(), it's just that this event is only fired once so subsequent page transitions won't trigger it. But that could be exactly what you want in the first place.
This code works on jsfiddle:
$(document).ready( function(event) {
$("label").each( function(index, element) {
element.addClass("ui-hidden-accessible");
});
});​
If in your real site you notice that page transitions cause the labels to come back, then you'll want to bind to something else, again probably 'pageinit'.
Hope this helps! Apologies for the verbosity...I kind of got going there huh?
http://jsfiddle.net/tW4Xu/2/
That? Not sure what your specific requirement is for using on('pageshow'), in my fiddle I used
$(function() {
$('label').addClass("ui-hidden-accessible");
});​
Don't use live its deprecated as of jquery 1.7. You had the right idea just do it before pageshow and make sure you use the page id. Also in your fiddle the top drop down menu change from onload to no wrap(head). I have had issues with that in the past.
$(document).on("pageinit", "#thepageid", function(event) {
$('label').addClass("ui-hidden-accessible");
});​
This will work for all your JQM pages.
$(document).on("pageinit", "[data-role=page]", function(event) {
$('label').addClass("ui-hidden-accessible");
});​

jQuery plugin scrollTo works only from console

Im having an issue with scrollTo on newly created divs Im adding to the DOM via append(). For some reason I cant scroll to where I want from within the code, it only works from console command or if I add a button and call the scroll event that way.
Code:
$('#history').scrollTo('max');
Only works from console or attached to a button.
Edit: The history div has overflow:auto, not sure if that's causing it.
Just a guess, but are you calling "scrollTo" immediately after appending your new element to the DOM?
If that is the case, then the DOM layout likely hasn't had a chance to get recalculated. Relative offset values between elements aren't yet updated until after the current script processing finishes.
Two possible workarounds:
1. setTimeout("$('#history').scrollTo('max')", 1); // Call this after you append your element. This will allow the stack to unwind and update the DOM positions
2. $('#history').scrollTo(0, 9999); // Where "9999" is a value far larger than the actual height of the control.
This would indicate that you're trying to attach scrollTo() to elements which aren't actually existing at the time that you're calling the function on them. The fact that it works in the console would suggest this.
If that's the case, one way would be to use e.g. a library like livequery or then simply call the scrollTo() function on these elements once they have been appended.

Jquery AJAX and figuring out how NOT to nest callbacks for multiple reloads.

I have a site with a few containers that need to load content dynamically via AJAX.
Most of the links inside of the containers actually load new data in that same container.
I.E: $("#navmenu_item1").click(function() { $("#navmenu").load(blah); });
When I click on a link, lets say "logout," and the menu reloads with the updated login status, none of the links now work because I would need to add a new .click into the callback code.
Now with repeated clicks and AJAX requests I am not sure how to move forward from here, as I am sure nested callbacks are not optimal.
What would be the best way to do this?
Do I include the .click event inside the actual AJAX file being pulled from the server, instead of within index.php?
Or can I somehow reload the DOM?
Thanks for the help!
You're looking for the .live function, which will handle an event for all elements that match a selector, no matter when they were created.
Since you're reloading a particular element, you can store the event listener there using .delegate() like this:
$("#navmenu").delegate("#navmenu_item1", "click", function() {
$("#navmenu").load(blah);
});
This works by listening for the click to bubble up to the #navmenu element and executing any handlers that match the selector. The .delegate() format is .delegate(selector, event, handler).
Since you're loading inside #navmenu, the event handlers on that actual element won't get blown away like they do on the children that are replaced inside, so the clicks will now work for current or future elements inside #navmenu.

Does JQuery have a way to unbind events in random HTML string?

I'm using JQuery to set the HTML inside a div. Something like this:
$(div).html(strHtmlBlob);
strHtmlBlob is a chunk of HTML returned via Ajax from the server. After, it's assigned, I set up some events for elements in the new HTML blob by doing this:
$(div).find("a").click(a_ClickHandler);
That all works perfectly fine. The problem is REMOVING the events. I want to make sure I clean up the DOM properly.
I'm removing the HTML like so:
$(div).html("");
But I can see that the events are still there. Is there a way to clean up events for elements that no longer exist?
Use .remove() instead of .html("")
That will clear the elements and events all at once. JQuery does a lot of cleanup magic under the covers if you let it.
$(div).find('a').unbind('click');
Check out the documentation.
Alternatively, you should empty() it:
$(div).empty();
According to the docs:
Note that this function starting with 1.2.2 will also remove all event handlers and internally cached data.

Categories