jQuery each not functioning correctly - javascript

I have a slider with 10 slider elements. However, only 7 out of 10 elements are rendered, given my data structure contains 20 sets. The site is hosted here
The code in question
function populateCarousell(cdata) {
var x = 0; //debug
jQuery(".wslide-slides .wslide-slide").each(function() {
var single = cdata.shift();
var jcurrSlide = jQuery(this);
jcurrSlide.find(".wslide-caption-text").text(single.title);
jcurrSlide.find("a").attr('href', "https://carousell.com/p/" +single.id);
jcurrSlide.css({'background-image':Base64.decode('dXJs')+'('+single.primary_photo_full_url+')'});
jcurrSlide.css({'background-image':'contain'});
jcurrSlide.css({'background-position':'50% 50%'});
jcurrSlide.css({'background-repeat': 'no-repeat'});
x++; //debug
jcurrSlide.find(".wslide-slide-inner2").removeAttr('style').find("img").css({'display':'none'});
});
alert(x); //Outputs 7
}
which is activated by (to ensure page fully loaded)
function caroDataCallback(data) {
if(document.readyState != "complete" ) {
setTimeout(function() { caroDataCallback(data); }, 2000);
}
else{
populateCarousell(data);
}
}
Upon examination in Chrome, the results is

That's because your page is not fully loaded when you call populateCarousell(cdata) function in your javascript file. Try instead of using $(document).ready(), use the $(document).load() to make sure all the images are loaded before you initiate your carousel.
Update: Use $(window).on('load', function() { .. }); instead.
Hope this helps.

Related

How to load all images after 2 seconds in lazysizes?

I am lazy loading images on the page, using the lazysizes library I call the script at the beginning of the page
<script> (function(){ window.lazySizesConfig = { lazyClass: 'lazy', loadMode: 2, hFac: 10, }; }); </script>
But the question arose, how to make it so that after loading the page, after a couple of seconds, all the pictures on lazy loaded without waiting for the page to scroll?
I couldn’t find a suitable parameter in the documentation, or I don’t understand something
You can manually run through all your elements and load them using unveil method
setTimeout(
function () {
$('.lazy').each(function () {
lazySizes.loader.unveil($(this)[0])
});
},
2000
);
in Plain JS:
setTimeout(function() {
var lazyObj = window.lazySizes;
// console.log(lazyObj);
// Safari returns the Object as undefined!
var isLazyObj = (typeof lazyObj !== 'undefined') ? true : false;
var imgs = document.querySelectorAll('img.lazy');
imgs.forEach(function(img) {
// console.log('unveil: ', img);
if (isLazyObj) lazyObj.loader.unveil(img);
})
}, 2000)
Update: I found out my Safari (16.2) returns the window.lazySizes Object as undefined so I adjusted the snippet to check for this

Waiting for multiple iFrames to load before executing function

Forgive my naivety, this probably is quite obvious, I just can't see it now.
Please tell me what is wrong with the following code:
$('#iframe1').load(function(){
$('#iframe2').load(function(){
alert('loaded!');
});
});
The idea is to wait until both iframes have fully loaded, then alert "loaded" - of course this is a simplified example for the sake of stack.
The script sits in script tags at the end of the body of the html doc.
#Quertiy answer is perfectly fine, but not very jQuery-ish. It is hard-coded for 2 iframes only.
The beauty of jQuery is that you can make it work for the most number of people, with as little friction as possible.
I've advised a very simplistic plugin that does nearly what is present on that answer, but in a more open way. It not only works on iframes, but also on images, audio, video and whatever has a onload event!
Without further due, here's the code:
(function($){
$.fn.extend({allLoaded: function(fn){
if(!(fn instanceof Function))
{
throw new TypeError('fn must be a function');
}
var $elems = this;
var waiting = this.length;
var handler = function(){
--waiting;
if(!waiting)
{
setTimeout(fn.bind(window), 4);
}
};
return $elems.one('load.allLoaded', handler);
}});
})(window.jQuery);
It works by adding a load handler to every element in that selection. Since it is a plugin, you can use in whatever way you decide to use it.
Here's an example, that loads 30 random images:
//plugin code
(function($){
$.fn.extend({allLoaded: function(fn){
if(!(fn instanceof Function))
{
throw new TypeError('fn must be a function');
}
var $elems = this;
var waiting = this.length;
var handler = function(){
--waiting;
if(!waiting)
{
setTimeout(fn.bind(window), 4);
}
};
return $elems.one('load.allLoaded', handler);
}});
})(window.jQuery);
$(function(){
//generates the code for the 30 images
for(var i = 0, html = ''; i < 30; i++)
html += '<img data-src="http://lorempixel.com/g/400/200/?_=' + Math.random() + '">';
//stuffs the code into the body
$('#imgs').html(html);
//we select all images now
$('img')
.allLoaded(function(){
//runs when done
alert('loaded all')
})
.each(function(){
//the image URL is on a `data` attribute, to delay the loading
this.src = this.getAttribute('data-src')
})
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min.js"></script>
<div id="imgs"></div>
Your problem, as said before many times, is that you have a load event attached to your iframe. That event is fired everytime the content change.
After that, you set a new event on #iframe2. When it's content changes, it will fire events left and right, above and beyound what you wish!
The best aproach is to keep track of which ones you loaded or not. After all have been loaded, you simply run the function.
The problem is that you're waiting until #iframe1 loads before you attach a handler for #iframe2 loading. So if #iframe2 loads first, you'll never get your callback.
Instead, watch the load event on both of them and track which ones you've seen:
var seen1 = false,
seen2 = false;
$('#iframe1, #iframe2').load(function(){
if (this.id == "iframe1") {
seen1 = true;
} else {
seen2 = true;
}
if (seen1 && seen2) {
alert('loaded!');
}
});
Why do you expect 2nd iframe to load after the first one?
~function () {
var loaded = 0;
$('#iframe1, #iframe2').load(function (){
if (++loaded === 2) {
alert('loaded!');
}
});
}()

jQuery, update content when necessary

I'm trying to update contents of a chat located in div (div1) but only when the contents of div1 change (a message was submitted into db and picked up in div1).
I tried the solution from here but my get fails to compare the data.
This solution works perfectly but without content comparison:
window.onload = startInterval;
function startInterval()
{
setInterval("startTime();",2000);
}
function startTime()
{
jQuery('#div1').load('index.php #div1 > *');
}
This is the modification based on this, which fails:
window.onload = startInterval;
function startInterval()
{
setInterval("startTime();",2000);
}
function startTime()
{
var $main = $('#div1');
$.get('chat.php #div1', function (data)
{
if ($main.html() !== data) $main.html(data);
});
}
I tried various modifications of this code but to no avail...
I can't reload the entire page and I don't want to do this if not necessary since it makes the chat harder to read if you have to scroll trough the messages.
How can this be fixed?
UPDATE
Based on #T.J's suggestions I modified the code which now works perfectly:
window.onload = startInterval;
function startInterval()
{
setInterval(startTime,3000);
scrolDown();
}
function startTime()
{
var $main = $('#div1');
$.get('#div1', function (data)
{
elements = $(data);
thisHTML = elements.find("#div1").html();
if ($main.html() !== thisHTML) {
$main.html(thisHTML);
scrolDown();
}
});
}
The other problem was that get required library:
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.pack.js"></script>
which apparently was not required by the load which I used previously.
You want to use get, but you want the fragment feature of load, so you'll have to do that work yourself. Then remember what you got last time, and only update if it's not the same:
var lastHTML;
function startTime()
{
var $main = $('#div1');
$.get('chat.php', function (data) // <== Or index.php, the question has both
{
var elements, html;
// Turn the HTML into elements
elements = $(data);
// Get the HTML of *only* the contents of #div1
html = elements.find("#div1").html();
// If that has changed, use it
if (lastHTML !== thisHTML) {
lastHTML = thisHTML;
$main.html(thisHTML);
}
});
}
Note that that's a fairly basic implementation of the fragment feature (it doesn't, for instance, strip out scripts the way load does). You may want to look at how load does its fragment stuff and replicate that (the joy of open source).

jQuery pre -loader ie-6/7 issue

I got this jQuery pre-loading script running on a index.html page loading about 10Mb before redirecting to a other page.
It works fine in IE8/9 FF3+ and Chrome.
But it does not seem to work in IE6/7, it seems to start and run but never fires the last part.
Working example: -removed-
Anyone knows why it gets stuck on 75/76 files loaded in ie6/7?
<script src="js/jquery-1.7.1.min.js"></script>
<script>
(function($) {
var imgList = [];
$.extend({
preload: function(imgArr, option) {
var setting = $.extend({
init: function(loaded, total) {},
loaded: function(img, loaded, total) {},
loaded_all: function(loaded, total) {}
}, option);
var total = imgArr.length;
var loaded = 0;
setting.init(0, total);
for (i = 0; i < imgArr.length; i++) {
imgList.push($("<img />")
.load(function() {
loaded++;
setting.loaded(this, loaded, total);
if(loaded == total) {
setting.loaded_all(loaded, total);
}
})
.attr("src", imgArr[i])
);
}
}
});
})(jQuery);
$(function() {
$.preload([
"http://www.erikderuiter.nl/images/300x300-transparent.png",
"http://www.erikderuiter.nl/images/300x300.png",
"http://www.erikderuiter.nl/images/300x600.png",
"http://www.erikderuiter.nl/images/600x300.png",
"http://www.erikderuiter.nl/images/600x600.png",
"http://www.erikderuiter.nl/images/900x300.png",
], {
init: function(loaded, total) {
$("#indicator").html("Files: "+loaded+"/"+total);
},
loaded: function(img, loaded, total) {
$("#indicator").html("Files: "+loaded+"/"+total);
$("#full-screen").append(img);
},
loaded_all: function(loaded, total) {
$("#indicator").html("Loading: Done!");
window.location.replace("http://www.erikderuiter.nl/somepage.html");
}
});
});
</script>
<div id="indicator"></div>
Any other tips or best practices to preload images on a page are welcome as well of course.
You need to also test if the image is already cached.
var img = new Image();
img.src = "foo.jpg";
if (img.complete || img.readyState === 4) {
// image is cached
}
else {
$(img).bind("load error onreadystatechange",function(e){
// image is loaded
});
}
If there is a 404 error on one of the images, you will need to catch that with a setTimeout and clearTimeout.
Edit: Just a note before i get bombarded for using .bind: I still use .bind in plugins for backwards compatibility.
Here's an example of the above method: https://github.com/tentonaxe/jQuery-preloadImages/blob/master/jquery.preloadimages.js
Edit again: After reading this over again, I'm not sure if caching is the problem you are having at the moment. It's definitely something that may come up later if you don't check for it, but it may not be related to the problem you are having.

How to know when all images from document did load in Javascript?

I'm realoading a <div> content with an ajax function with Ruby On Rails i'm realoading a partial into a div and i want to know hot to know when all images have loaded because now i have this:
$(document).ready(function(){
$("img").load(function(){
alert("ok?");
});
});
but with this i keep getting an alet for every image on this partial....
i don't know iuf there's a selector like $(allimgs) or something like that, what do i have to do to catch when all images are loaded?
Many Thanks.
If you wish to ensure that all images loaded without errors you have to roll your own. If not you can use .load like already shown which will fire when the browser is done loading assets.
To roll your own, do something like this:
$(document).ready(function(){
var imgs = $("img"), cnt = imgs.length;
imgs
.load(function(){
if(!--cnt) {
/* all images loaded */
}
})
.error(function() { /* whoops an image failed to load */});
});
Will do something like:
First we count how many imgs we have in our page, every img load will decrement count by 1, and when it is 0, means that all images are loaded.
$(document).ready(function(){
var allimgs = $("img");
var count = allimgs.length;
allimgs.load(function(){
if(--count == 0) {
alert("all images are loaded");
}
})
});
**EDITED**
If the browser is caching the images, try this instead:
$(document).ready(function(){
var allimgs = $("img");
var count = allimgs.length;
$("img").one('load', function() {
count--;
if(count == 0) {
alert("all images are loaded");
}
}).each(function() {
if(this.complete) $(this).load();
});
});
You might need to use the image loaded plugin, to ensure that your code deals with cached images etc. https://github.com/paulirish/jquery.imgloaded
and then your code
var total_number_of_images = $("img").length;
var loaded_images = 0;
$("img").load(function(){
loaded_images++;
if loaded_images = total_number_of_images {
// do something ...
} });

Categories

Resources