IE doesn't respect the sequence of javascript line execution? - javascript

I'm trying to animate using jQuery but on IE7/8/9 it's not working before I show the element.
function callback() {
$('#content').animate([...]);
[...]
}
$('#content').hide();
[...]
$('#content').show();
callback();
It only works to me when a do setTimeout(function() { callback(); }, 300);, maybe I need to wait the IE to recognize the element that has been shown, before execute the callback. What is the problem here?

You need to wait for the element to exist within the page before you can select it with jQuery.
wrap your script with:
jQuery(function($){
//your code here
});
It's a shortcut for the document.ready event listener.

Since JS is single-threaded just because you call show() doesn't mean it's actually showing; you need to return control to the parent to allow it to draw and update the DOM before that happens. setTimeout allows your JS to yield to the parent, making it's updates before you continue with execution. setTimeout with 0 will most likely also work.

Related

Jquery Onclick functionality not working for div, as specific loaded after sometime

For <div class="editdiv">Test</div>. Jquery click functionality is added in document.ready function . But editdiv loading in page dynamically with delay.
So when I click on the div. Function is not calling. By using timeout function is working fine.
I need a different approach to solve this functionality.
If your .editdiv is loaded dynamically after your js loading so your click event can't detect it and it will not work, instead you should use event delegation on() to deal with fresh DOM :
$('body').on('click', '.editdiv', function(){
//Your click event code
})
If you want to avoid setTimeout you could use delay with queue callback method :
$('div.scroll-area-blue')
.delay(5000)
.queue(function() {
$(this).enscroll({
showOnHover: false,
verticalScrolling: true,
verticalTrackClass: 'vertical-track-blue',
verticalHandleClass: 'vertical-handle-blue'
});
});
If you will use setTimeout better to use it like :
setTimeout( enscrollDiv, 5000);
function enscrollDiv(){
$('div.scroll-area-blue').enscroll({
showOnHover: false,
verticalScrolling: true,
verticalTrackClass: 'vertical-track-blue',
verticalHandleClass: 'vertical-handle-blue'
});
}
Hope this helps.
It is really difficult to understand whats going wrong from your question. What I guess is you are loading a specific div using Ajax or similar technologies - meaning the div is not available initially.
The way jQuery works is that, it only binds the event to the elements only available at the time the part is executed.
If a <div id='myDiv'></div> is not present when $('#myDiv').click(function(){}) is called, it won't work.
One workaround is to do it like this:
$('body').on('click','#myDiv',function(){});
This registers the click on body and then checks if the clicked element is having a id 'myDiv' or not. We can expect the <body></body> to be present always. So the problem we had with previous code won't happen here.
maybe you're loading the javascript codes before the html elements(tags) are loaded.
try adding the script which includes "document.ready()" before the end tag of the body when all html tags have already finished loading.
I'm hitting targets in the dark. Hope it works for you. It's difficult to generate any solution without analyzing the problematic code......

How to put a delay that stops the code without stop the HTML render?

I need to stop my code in a for loop, a sleep() function that stalls time does not work because my HTML does not render in that time and a setTimeout function will continue the loop before doing the set code.
For example, this will display alerts with 1,2,3 before 3 alerts with Stop.
function test(){
for (var i = 1;i<4;i++) {
alert(i);
setTimeout(function(){alert("Stop");},1000);
}
}
How could I wait until continuing with my loop while letting the HTML render ?
Use the DOMContentLoaded event to check once your HTML is fully rendered:
<script>
document.addEventListener('DOMContentLoaded', function(event) {
alert('html loaded');
});
</script>
In your example you could instead just use confirm instead to show a message, and when the user clicks then you use the next setTimeout to show the next message.
But, I think this is not what you are actually looking for.
There are many ways to do asynchronous javascript that doesn't impact html rendering, such as using Web Workers, or pass functions inside of setTimeout and those can use closures to help track where you are, but, have the next setTimeout be called after some processing, and after some event, as these will allow the rendering to continue until certain events or time happens.

Call javascript function after CSS change

I want to call a function after the css has been changed. For Example something like this
$("#ContentDiv").css('height','500px').change(function(){
alert('changed');
});
Call function immediately after above css change. I cannot use setTimeout or other timeouts. Actually i have applied some css animation for 1 sec which cause contentdiv to resize for 1 sec and that's why if i call a function immediately like this
$("#ContentDiv").css('height','500px');
myfunction();
myfunction() will start executing while the height is still not changed.
Thanks to John Smith for correcting my question, he suggested good but i could not find to accept his changes.
There is a DOMAttrModified event that is fired on some browsers that you could catch to detect this. You can probably use PropertyChanged on IE, but DOMAttrModified should work on Chrome/Firefox etc.
Something like this:
document.documentElement.addEventListener('DOMAttrModified', function(evt){
if (evt.attrName === 'class') {
// Code
}
}, false);
EDIT: Based on your update, if you just want to call code after the animation is done, and you are using jQuery to do the animation, you can chain a callback function to the animation, please refer to the documentation: http://api.jquery.com/animate/
Just call the function.
$("#ContentDiv").css('height','500px');
myFunction();

how can i invoke a function after page is done loading? (and only then..)

I'm having trouble with some jquery code.
in my HTML page I use ajax to get some info, and then I'm changing an HTML element
with $("#id").html(...).
The problem is, I also have a $(document).ready code which I wanna call only once
when the page is done loading, but after each change in the html with the $("#id").html(...)
the code is called once again.
How can I run the $(document).ready code only once?
Here is an example:
$(document).ready(function(){
// this code will run not only once...
}
function f(){
$("#id").html(...);
}
Try:
var run = false;
$(document).ready(function() {
if(!run) {
...
run = true;
}
});
...or...
$(window).load(function() {
...
});
The first one will make sure it is only run once; the 2nd one is run when the entire page is finished loading (useful if you need to resize things once images have finished loading).
From the comments on the .ready documentation:
Looks like .ready() fires not only when page initially has settled the
DOM, but apparently also after changes to the DOM. This is an issue if
your ready handler changes the DOM. That will result in ready() firing
more than once. It may result in an endless loop if each invocation
adds yet more to the DOM. Firefox and IE behave differently to this,
including different error messages, and leaving the page display in
different states. So, if ready() modifies the DOM, then it would be
wise to have a way to check whether ready has already been fired.
Replying to self: Well it appears that part of the problem is not that
the ready function fires again (though that is possible aparently),
but that changing the DOM causes the script that creates the ready
function to fire again, adding an additional ready function, etc etc.
This seems to happen if the javascript is embedded in the html at a
point beyond (or contained in) the part of the DOM that the ready
handler modifies. (Obviously would be better to put script that
creates a ready function in the document head, but in this case that's
not an option.) Problem fixed by checking a global flag variable to be
undefined before executing jQuery(document).ready(...).
If this might be your problem, you can adopt the same solution:
var onLoadFired = false;
$(document).ready(function() {
/* Ensure this function only runs once */
if (onLoadFired) {
return;
}
else {
onLoadFired = true;
}
/* Business logic */
// .. your code here ..
});
Or, better, move your handler into a separate script file that's included by a script tag in your page's head element.
Try this:
$(window).bind("load", function() {
...
});

Jquery fadeOut executes callback over and over again, why is this and how can I prevent this?

My method fades a div box out and has a callback that calls a method... like this:
function closeWindow(windowIdPrefix, speed) {
$("#" + windowIdPrefix + "_ViewPanel").fadeOut(speed,
function() {
resetWindow(windowIdPrefix);
numWindowsOpen--;
}
);
}
function resetWindow(windowIdPrefix) {
alert("resetting window");
}
When this executes (onClick of a button) I have an alert in resetWindow to see how many times it executes.
It seems to execute forever, but I haven't sat there long enough closing the alert windows to find out.
I did some research and read in the Jquery Documentation:
callback (Optional) Function
A function to be executed whenever the animation completes, executes once for each element animated against.
So I was wondering, even though I'm only fading out 1 div, does it count as 1.. plus 1 for each child element the div has?
Technically they are being animated because the inner elements are being faded out with the outer div, but if you watch the javascript in firebug only the outer div I'm fading out gets it's opacity/display changed.
If this is what's happening, how do I make sure the callback only gets executed once?
Edit: It was the line numWindowsOpen--; I hadn't defined numWindowsOpen before the function so for some reason that was making the call happen multiple times... Can anyone explain why this was happening?
The callback should only be invoked once for each element that matched the selector. Do you see multiple alerts when putting an alert message directly in the callback?
function() {
alert('Test');
resetWindow(windowIdPrefix);
numWindowsOpen--;
}
Problem was that numWindowsOpen wasn't declared before it was decremented there... Good reminder to make sure you look for simple things like that before going to more complicated tihngs.

Categories