jQuery .html function with .load - javascript

I am loading HTML content using jQuery's .html() function. Part of the HTML content I am trying to load are images, which take some time to be loaded. What I do is on an onclick event,
$('div').on('click',function() {
$('html').fadeOut(1000)
.html(content)
.load(function() {
$('html').fadeIn(1000)
});
});
What I wanted to happen is that, when the DOM has finished loading, I want it to fadeIn. If it is still not finished, I want it to stay hidden hence, the fadeOut function before the html load.
Is this possible? That method doesn't seem to work for me.

First, if you are replacing the entire HTML element, you might as well just do a full request cycle. That's essentially what you're going to end up with and it will be easier to hook to the window load event using a full request than to handle this with AJAX. If you're not replacing the entire page, then you've got your selector wrong.
Second, if you are just loading the DIV, then you can try hiding the DIV, binding the load event to it, then loading it with content. See the caveats for the http://api.jquery.com/load-event/ method for more information.
$('div').on('click',function() {
var $this = $(this); // save reference for future use
$this.fadeOut(1000) // hide
.load(function() { // hook up handler
$this.fadeIn(1000)
})
.html(content); // load content
});

Related

Ruby on Rails - JavaScript in dynamically generated partials

I know putting JavaScript in partials is a bad idea because the page will have to load up a new script every time a new partial is loaded. I am aware of and have read this question, but its answer did not work for me (putting the script into app/javascripts/application.js). I think it is because I am working with partials that are dynamically generated onto the page. I think the dynamically generated partial does not react to the script loaded up on the initial page.
For example, I have a "Rule" div with a select input that has a script to do something when the select input is changed. This works for every Rule div that is generated on page load. But then there is also a "+" or "ADD" button which will dynamically generate more Rule divs which do not respond to the script, unless that script is in the partial.
Is there a good way to keep the script out of the partial when the partial is dynamically generated?
JQuery sets listeners on page load (i.e. $(selector).on(etc.)), so it doesn't listen for events on dynamically added elements. There is a way around it, though. You need to use what is called a delegate.
$(document).ready( function() {
$('body').on('change', 'input.selector', function(e) {
// do something
});
});
I'm not sure what your event (here I put change) or selector for the select you are using (here I put input.selector), but if you replace those with the appropriate information, it should work even with dynamically added elements.
You can use JQuery to execute the code only after the document has loaded onto the DOM:
$( document ).ready(function() {
//Call your functions here
});
That way, your JS will have access to whatever is on the page, because you are ensuring that it is fully loaded.
If your divs are not in place on document ready, you can use event delegation, as suggested by ptd. Basically what this means is that you install a handler on a parent div (which will be present on document ready) which says, "hey, when you click on this dynamic div inside of me, call this function".
$('div#master').on('click', 'div.dynamic', function(event) {
console.log("action here")
var $dynamicDiv = $(event.currentTarget) //The current Target is the thing you clicked on, not the parent.
});
If you are adding elements to the DOM using AJAX calls, but want to keep your JavaScript in your assets folder only, here's a quick and clean way to accomplish this.
// /app/assets/javascript/foo.js
// On intial page load
$(document).ready(function() {
yourJavaScriptForPartials();
});
// After a subdomain field is loaded via AJAX
$(document).ajaxComplete(function() {
yourJavaScriptForPartials();
});
function yourJavaScriptForPartials() {
// Insert your javascript here.
};
Now, any JavaScript you put in the yourJavaScriptForPartials() function will be available both to the initially loaded DOM, and to any DOM elements added via AJAX. For reference, here is the JQuery page for the ajaxComplete event listener.

jQuery.ready() equivalent event listener on elements?

I am using jQuery JavaScript library. I like the event listener ready on $(document) that fires when the DOM is set up.
( Pretty similar to .onload but without external sources )
I would find it very useful, if there was an event listener which has a very similar behavior to this, but fires when an element is fully loaded. (f.e.: Picture, a Div with an extremely long text content, such )
I would appreciate both jQuery or JavaScript methods.
There is no event fired when an arbitrary DOM element such as a <div> becomes ready. Images have their own load event to tell you when the image data has been loaded and has been rendered and a few other special types of elements have an event. But, regular DOM elements do not have such an event.
If you want javascript code to be executed as soon as an arbitrary DOM element is ready, the only way to do that is to place a function call in an inline script right after that DOM element. At that point that DOM element will be ready, but the rest of the DOM afterwards may not yet be ready. Otherwise, the script can be placed at the end of the document or the script can be fired when the whole document is ready.
Here are the existing load events expressed in jQuery form (these can all be done in plain JS too):
// when a particular image has finished loading the image data
$("#myImage").load(fn);
// when all elements in the document are loaded and ready for manipulation
$(document).ready(fn);
// when the DOM and all dynamically loaded resources such as images are ready
$(window).load(fn);
In jQuery, you can also dynamically load content and be notified when that content has been loaded using the .load() method like this:
$( "#result" ).load( "ajax/test.html", function() {
alert( "Load was performed." );
});
Internally, this just does an ajax call to fetch the data and then calls the callback after the data has been retrieved by ajax and then inserted into the document. It isn't a native event.
If you have some code that is dynamically loading elements in to the DOM and you want to know when those DOM elements are present, then the best way to know when they are ready is to have the code that adds them to the DOM create some sort of event to tell you when it's ready. This prevents battery wasting polling efforts trying to find out if the element is now in the DOM.
It is also possible to use the DOM MutationObserver to see when specific types of changes have been made to the DOM.
All elements (including div and img) are ready as soon as DOMReady fires - that's what it means.
However, you can use the load() event to run some code when an img tag has fully loaded the image in it's src attribute:
$('img').load(function() {
console.log('image loaded');
});
jQuery don't have it, but we can create our own onDomElementIsReady, Tools: jQuery, ES6, Promise and Interval (I'm lazy, but you can get the idea)
We will wait until the element existed on the DOM and as soon is available we will resolve the promise result.
const onDomElementIsReady = (elementToWatch)=> {
//create promise
return new Promise((res, rej)=> {
let idInterval = setInterval(()=> {
//keep waiting until the element exist
if($(elementToWatch).length > 0) {
clearInterval(idInterval); //remove the interval
res($(elementToWatch)); //resolve the promise
}
},100);
});
};
//how to use it?
onDomElementIsReady(".myElement").then(element => {
//use jQuery element
});
NOTE: To improve this we should add a timer that reject the promise if the DOM element never exists.

script not working on Ajax-loaded Content

I have a jquery powered voting system, and the items on other pages are loaded via ajax, but on ajax-loaded contents the jquery voting needs the page to be refreshed for the vote to be processed.
http://ohmygosh.vr.lt/
I think the problem is within the actions in this file (?) But i'm not really sure. I don't have any code to start since I don't even know where to start. How do I fix this Problem?
Seems that you are using a SmartAjax to load the page content. What SmartAjax does is that it changes the page url (using pushState or hash), loads data and REPLACES the content of #posts div with the loaded content.
The problem is that you are listening click events from DOM elements which are later deleted and replaced with new DOM elements. Thus, the click events from the ajax loaded content are not listened. live() doesn't help in this case.
To fix this, you have at least these two options:
1) Use jQuery's delegate() to attach the handler and use #posts div as the root element, since it remains after the new content is loaded.
Something like this should work:
$('#posts').delegate(':input', 'click', function() {
var value = $(this).val();
alert('You have clicked thumbs up/down, value: ' + value);
return false;
});
2) Add click listener to the loaded items after data loading is completed.
Notice: Starting jQuery 1.7 you should use on() instead of delegate()

jQuery .load() not working when called from loaded content

My primary navigation [Our Clients, Our Culture, Our People] uses .load() to pull the content and display it in a div on the same page w/o refresh.
I would like for links within the new content to do the same, just display whatever content is being referenced in this same div. However, when they're clicked it goes directly to the new page.
$(function(){
$("a.aboutContent").click(function (e) {
e.preventDefault();
$("#aboutContainer").load($(this).attr("href"));
});
});
So, when Our People is clicked, it pulls ourpeople.htm in to the #aboutContainer div. If you click on a link inside of ourpeople.htm, I'd simply like for that content to display in the same #aboutContainer div. I'm assigning the aboutContent class to links in the subpages as well, but it still isn't working.
You will need to use .live() to listen to clicks from everything, including new DOM elements:
$(function(){
$("a.aboutContent").live('click', function (e) {
e.preventDefault();
$("#aboutContainer").load($(this).attr("href"));
});
});
The reason for doing this is, jQuery code runs when the page is ready - it will attach a click handler to every dom anchor with the class aboutContent - when you load new content, those elements where not there when the page was ready, so never have a click handler attached to them.
Using .live() takes care of that for you. Alternatively, you could place your code in a function, and run that function when the new content is loaded, that way when it runs, it will attach a click handler and the DOM elements will be there, trouble with this is, you would have to mark elements as already having a click handler, or you would end up adding x number of click handlers to some elements.
Probably you can return false from click handler to prevent browser to exeucte HREF on its own.
Like,
$(function(){
$("a.aboutContent").click(function (e) {
e.preventDefault();
$("#aboutContainer").load($(this).attr("href"));
return false;
});
});
Otherwise I would suggest to call some javascript function on href using href="javascript:clickhandler('')"

Javascript/jQuery HasLoaded or equivalent?

I know in jquery it is possible to call the javascript/jquery onload()/load() functions on, for example an image (<img>).
However, if in jquery if i use .html(htmlString) to insert an image after the dom has loaded, how can i add a listener to handle the images onload event? Is there a property I can check to see various images and if they have loaded?
After appending your html, you can bind the load event to the contained images:
$("#foo").html(htmlString).find("img").one("load", function() {
...
}).each(function() {
// image has been cached, so load event won't fire unless we explicitly call it
if(this.complete) $(this).trigger("load");
});
Check the complete property of the image(s)

Categories