Image slideshow at onload not working properly - javascript

I know this question has been asked before a lot but I checked most of those and didn't find solution to my problem so I'm asking here again.
So, question is:
I'm working on a cinema website project.
I added a few pictures as slide show in my home page but for some reason, slideshow is not working properly. It has some glitch in it like sometimes order is not correct and sometimes all pictures try to come up at one time or they change super fast etc.
I guessed maybe it's bcz somehow when I reload the website, the previous onlaod also keeps on working so it's like there are 2 slideshows going on or something like that, so from other solutions I guess I have to put onload=null somewhere maybe but I can't figure it out exactly.
Any help would be really appreciated.
This is my html code for slideshow:
<div class="bg-movies" style="top: 65%;">
<img src='images/slideshow/war.jpg' width='1000' height='300'
onload="setSlide();"/>
</div>
And this is my javascript code:
<script language='javascript'>
<!--
var toprated=new Array('sarkar.jpg','hajwala.jpg','96.jpg','war.jpg');
var pos=0,x;
document.images[1].src='images/slideshow/'+toprated[0];
function setSlide(){
x=setInterval('chgPic()',2000);
}
function chgPic(){
pos=(++pos)%toprated.length;
document.images[1].src="images/slideshow/"+toprated[pos];
}
-->
</script>

Your problem is recursion. You are calling the setSlide() method once your image is loaded. This will set up the interval to call the chgPic(), but when the chgPic() method is called and it updates the image src, the onload event on the img tag will be executed again (because an image has been loaded). Therefore setSlide() will be called again which will set up another interval to call the chgPic() method. And on and on etc. I'm surprised your browser hasn't crashed.
What you should do is set up the interval (i.e. call the setSlide() method) once the page has loaded, or even better yet, use jQuery's document ready if you're using jQuery:
$( document ).ready(function()
{
}
And call your setSlide() method in here.
Although, I wouldn't recommend doing it the way you are. You can use some simple jQuery and CSS to get this to work. Take a look at this link.

Related

How to resize an iframe after all jquery ajax requests are done

I have an html document with an iframe in it. The parent document and the document in the iframe (a wordpress blog) are in the same domain. The iframe auto-adjusts its height on load event to fit its content like this:
<iframe width="100%" height="100%" id="parent-iframe" name="parent-iframe" src="/blog" scrolling="no" onload="this.height=this.contentWindow.document.body.scrollHeight"></iframe>
It works fine. But now, the blog which is mostly one page with a facebook feed, has been updated with a "load-more" button to limit the number of posts displayed. Much like an infinite scroll but with a button.
What I want is to be able to resize the parent iframe on the "load-more" button click. Since the facebook feed is provided by a wordpress plugin and it gets updates every now and then, I'd rather not mess with its files directly. Also the javascript code is minified so it looks like jibberish to me.
Fortunately, it also provides a backoffice textbox to include custom code. Since jQuery is already loaded, I tried this:
jQuery(document).ready(function () {
jQuery("load-more").click(function () {
var frame = $('#parent-iframe', window.parent.document);
var height = jQuery('body').height();
frame.height(height);
});
});
It works as expected but with one caveat. Whenever the click event is triggered, the function is executed before the new post gets loaded therefore the body height is always one step behind. I could add a fixed amount of pixels
to compensate but some posts are significantly larger than others.
I don't do this kind of work very often so I need help. I was looking at the jQuery deferred objects but quite honestly I'm a bit lost. Can somebody briefly explain to me how does it work and how to fix it?
Thanks to #jfriend00 suggestion, I think I've found a somehow working solution.
Since the plugins javascript file is minified and I'm not used to javascript debugging, I couldn't find the end of the load-more ajax call.
All I needed then was to wait until all ajax requests were finished. So I found this post jquery.ajaxStop() and tried this:
jQuery(document).ready(function () {
jQuery("load-more").click(function () {
$(document).ajaxStop(function () {
var frame = $('#parent-iframe', window.parent.document);
var height = jQuery('body').height();
frame.height(height);
$(document).unbind("ajaxStop");
});
});
});
Now it works. Please excuse me if I haven't been able to explain myself better. As I said I'm not used to this so I'm lacking in proper terminology and concepts. If you have any suggestions regarding the post title, details or tags in order to make it useful to others I'd be glad to edit it accordingly.
It also works and looks cleaner like this:
<iframe width="100%" height="100%" id="parent-iframe" name="parent-iframe" src="/blog" scrolling="no" onload="this.height=this.contentWindow.document.body.scrollHeight" onresize="this.height=this.contentWindow.document.body.scrollHeight"></iframe>
parent iframe
$(document).ready(function () {
$("#load-more").click(function () {
$(document).one("ajaxStop", function () {
window.parent.$("#parent-iframe").trigger('resize');
});
});
});
child document jquery

JQuery not running correctly on document.ready();

I have placed this inside of my jsp file:
<script>
jQuery( document ).ready(function() {
jQuery('#resrcTypesTree').height(jQuery('.secondColumn').innerHeight() - 10);
});
</script>
If I run this directly in Chrome's console, it works with no problems. If I load the page, the #resrcTypesTree id is set to 10px (a css default). I cannot figure this out as to why it appears to not be setting the height of the resrcTypesTree to the secondColumn's height. Is there something else that I am missing? I could put in a pause to check the page after a unit of time goes past, I just feel that is hacky.
The $ for jQuery is being overridden by another library in the project that is why I called jQuery instead of the '$'.
Can someone point me in the right direction please? Thank you in advance!
RR
Depending content you are targeting but as a simple fix, you should wait all content to be loaded:
jQuery(window).on('load',function () {
jQuery('#resrcTypesTree').height(jQuery('.secondColumn').innerHeight() - 10);
});
This ended up being an ajax issue. I had to write a mediator function since there are more than one ajax call being ran. 95% of the time the re-size works once put into the ajax script, however the 5% of the time, the secondary ajax call would get done first, causing the page not to re-size the gradient correctly.

Problem with two scripts interfering

I'm trying to bring some images from a Tumblr account and to show them using a slider. To bring the images I modified and used a script called tubmlrBadge (http://robertnyman.com/2008/09/19/tumblrbadge-a-tumblr-badge-script/), and to show the images I am using this slider > http://www.meadmiracle.com/SlidingGallery.aspx
If I check using Firebug I can see that the photos are shown okay, but I can't see them in with the slider. I can't figure out what's the problem, I suppose that a problem appears because the slider script must work with content generated by the tubmlr script. I tried placing the slider script after the tumblr one the slider still doesn't works.
You can see a demo of the this at http://www.mctest2.com.ar. If anyone has an idea please help me I tried everything!!
Thanks!
If the script you use to fetch the images was the image-fetcher itself (not a script that calls another script to get a JSON with the image data) you would have used $.getScript with a callback method.
However, your script can't use it, because no matter if the script file is loaded, it will also call another one, that might take longer to be loaded.
I think the only possibility you have is to set an "timer" in your page and wait until the gallery is loaded:
function setSlider() {
var jqelement = $('.gallery img');
if(jqelement.length>0) {
jqelement.slidingGallery();
} else {
setTimeout(setSlider, 200);
}
}
setSlider();
Working example:
http://jsfiddle.net/marcosfromero/5dSgd/

Where to put all that jQuery JavaScript code?

From the documentation I've found this example:
We can animate any element, such as a simple image:
<div id="clickme">
Click here
</div>
<img id="book" src="book.png" alt="" width="100" height="123" />
With the element initially shown, we can hide it slowly:
$('#clickme').click(function() {
$('#book').fadeOut('slow', function() {
// Animation complete.
});
});
I remember from 5 years ago, that you should NEVER ever refer to any element until it was defined. Does this rule still apply? So I would have to put all that code in the footer of my web page? Or can I put it in a separate file and import it in the footer? What's best practice?
The recommended way of doing this is putting all initialization code into $(document).ready, like so:
$(document).ready(function() {
$('#foobar').click(function(event) { alert("You Clicked Me!"); });
});
You are correct; you cannot interact with a DOM element before it exists.
You have two options:
Put the code below the HTML, as you suggested.
Put the code anywhere, but wrap it in $(function() { ... }).
This construct will execute the function in the page load event, after the DOM exists.
The best practice is to place all SCRIPT elements at the bottom of the HTML document (right before the </body> tag. The reasons are:
loading of external JS files blocks loading of other resources (like images)
since JS code is executed immediately, it is better to parse the HTML code of the page first, and then execute the JS code afterwards
You can see an HTML5 template that demonstrates this practice here: http://vidasp.net/HTML5-template.html
Many people put it in the bottom of the page so other code can execute first. That becomes a bit of a moot point with the document ready syntax that waits until other content loads to the dom. So, using that logic, in theory it could go anywhere.
Scripts go best in the foot of the page, to provide for the speediest rendering of the DOM. The following idiom executes only once the DOM is ready:
$(function() { /* ... your code goes here ... */ }
If you have a lot of code, or code that is shared between multiple pages, you should link it in a separate file which can then be minified, should you need to optimize your download speed.
I asked this question, albeit in a different way a little while back. You might want to look at the answers I got too - they're quite ... philosophical:
JQuery - Best way of wiring GUI objects to events?

jQuery load() method memory leak?

I have hunted around for answer to this one, and though have found related quesions, I couldn't quite find an exact match for this.
I have a fairly large app which is supposed to load pages into divs in another page using the jQuery.load() method. The problem I have is that when loading the same page over and over again into the same div, I see the memory of the browser increase substantially (memory leak). If I call $("*").unbind, I of course do not see a leak, but then everything has been reset, so this isn't reallya fix. The following code example reproduces this problem:
Test1.htm
<head>
<title></title>
<script type="text/javascript" language="javascript" src="Scripts/jquery-1.3.2.js"></script>
<script type="text/javascript" language="javascript">
<!--
var i = 0;
$(document).ready(function() {
$("#btn").click(
function() {
i++;
$("#Test1").load("Test2.htm", null, function() {
//$(document).trigger("test");
})
$("#count").html(i);
});
});
//-->
</script>
</head>
<body>
<img id="btn" src="someimage.png" />
<h3>We are loading Test2.htm into below div</h3>
<div>
Count loads =<span id="count">0</span>
</div>
<div id="Test1" style="border-style:solid">EMPTY</div>
</body>
Test2.htm = any old html page..
If you load Test1.htm and click the button mutliple times, you'll notice the browser memory steadily increasing. I believe the problem is that the loaded js and DOM elements are never set for garbage collection. In my real world system I have tried removing (elem.remove() or .empty()) the loaded elements, but this doens't really fix the problem. I also have many js files loaded using "src", which I replaced with $.getScript, this seems to have had made a small improvement. These are all workarounds thought, and I wanted to find a real solution for this problem. Any ideas?
Edit: update due to more info provided about test2.htm (the page being loaded)
Original answer (for historical purposes): I don't actually see any leaks in the code/markup you have provided - is it possible the leak is in Test2.htm (which you haven't provided the code/markup for)?
New answer:
I would suggest that it it probably due to either multiple loads of jQuery, or other scripts you have in test2.htm.
Assuming jQuery does not leak by simply instantiating and then nullifying jQuery and $, loading multiple times will keep at least 2 copies of jQuery in memory. When loaded, jQuery keeps a backup of any previous versions of $ and jQuery in _$ and _jQuery - so you are going to have at least 2 copies of jQuery loaded when you use load() multiple times.
The above assumption is most likely not correct however - there is every chance that jQuery has leaks even if you "unload" it by setting $,jQuery,_$ and _jQuery to null - it's not really intended to be loaded multiple times like that (however I'm sure that they allow it intentionally, so you can use noConflict() to load and use two different versions of jQuery if necessary).
You can add a "selector" to a load URL. For example:
$("#Test1").load("Test2.htm body", null, function() {
//callback does nothing
});
//or
$("#Test1").load("Test2.htm div#the_Div_I_Want", null, function() {
//callback does nothing
});
I would suggest doing this if you are not interested in any scripts in the ajax result, or alternatively if you do want scripts, you'd need to choose a selector to disable only certain elements/scripts, e.g.
/* load with selector "all elements except scripts whose
src attribute ends in 'jquery.js'" */
$("#Test1").load("Test2.htm :not(script[src$='jquery.js'])", null, function() {
//callback does nothing
});
Also of note is that if you leave out the "data" argument (you have it as null), and provide a function as the second argument, jQuery will correctly determine that the second argument is the callback, so
$("#Test1").load("Test2.htm :not(script[src$='jquery.js'])", function() {
//callback does nothing
});
is acceptible
Hmm perhaps it's just something really basic, but if i set $.ajaxSetup({ cache: false }); before the load calls, I don't seem to get the problem. Now, of course my "real" code has this call, so why might I see a problem? I believe the Tabs UI extension is causing caching to be switched on (I don't actually believe this, but invoking the false cache call before each load seems to fix it!!)
Ok so I finally found the problem and it's not a leak at all (which I suspected), it's simply the result of attaching multiple very complex handlers to the same trigger/event. I raised this question relating to that:
JQuery event model and preventing duplicate handlers

Categories

Resources