Image Lazy loading images "jumping" - javascript

Hey i wanna lazy load the images on my page, so i created a data-src tag on my images tags and then i load it.
I know there ar many libs etc. but i have to learn js and css so i tired to to it whitout any help.
Now the problem is, the images hav no initial height so when the load the whole page is "jumping around"
here my js code:
var smuLazyLoad = (function (self) {
var body = document.getElementsByTagName('body')[0];
var defaultSetup = {
classSelector: "lazy",
loadDelay: 100,
fadeTime: 0.5
};
self.setup = {};
self.init = function (options) {
options = options || {};
self.setup.loadDelay = options.loadDelay || defaultSetup.loadDelay;
self.setup.classSelector = options.classSelector || defaultSetup.classSelector;
self.setup.fadeTime = options.fadeTime || defaultSetup.fadeTime;
self.appendHelperStyles();
self.addEvent('load',window,self.selectImages)
};
self.selectImages = function () {
var tags = document.getElementsByClassName(self.setup.classSelector);
for (var i = 0; i < tags.length; i++) {
self.loadImage(tags[i]);
}
self.appendShowCss();
};
self.appendShowCss = function () {
setTimeout(function () {
var style = document.createElement('style');
style.innerText = "." + self.setup.classSelector + "{opacity:1 !important;}";
body.appendChild(style);
}, self.setup.loadDelay);
};
self.loadImage = function (tag) {
var imageUrl = tag.getAttribute('data-src');
tag.setAttribute('src', imageUrl);
};
self.appendHelperStyles = function () {
var style = document.createElement('style');
style.innerText = "." + self.setup.classSelector + "{transition:all ease-in " + self.setup.fadeTime + "s;}";
body.appendChild(style);
};
self.addEvent = function (ev,ele,func) {
if (ele.addEventListener)
ele.addEventListener(ev,func,false);
else if (elem.attachEvent) {
ele.attachEvent("on"+ev, func);
}
else {
ele[ev] = func;
}
};
return self;
}(smuLazyLoad || {}));
and my image tags ... (twig/craftcms)
<img src="/onePxImage.jpg"
alt="{{ image.title }}"
data-src="/{{ image.getUrl('teaserImage') }}"
style="opacity: 0;"
class="lazy"
width="{{ image.getHeight('teaserImage') }}"
height="{{ image.getWidth('teaserImage') }}"
>

Related

Iframe Url Decoding confused

It's used in some site.. to hide iframe src url
String.prototype.edoceD = function () {
var x = this.length;
var edoceD = "";
while (x>=0) {
edoceD = edoceD + this.charAt(x);
x--;
}
return edoceD;
}
var OLID = 'a66793a78396b6d6a6d6c6b61746'
OLID = OLID.edoceD()
Result of this OLID ?

Ease transition between images in JavaScript slideshow

I'm using JavaScript to randomly display an array of images with timed intervals.
This is the script:
var NumberOfImages = 5
var img = new Array(NumberOfImages)
img[0] = "[image here]"
img[1] = "[image here]"
img[2] = "[image here]"
img[3] = "[image here]"
img[4] = "[image here]"
Array.prototype.shuffle = function () {
var len = this.length;
var i = len;
while (i--) {
var p = parseInt(Math.random()*len);
var t = this[i];
this[i] = this[p];
this[p] = t;
}
};
img.shuffle ();
var imgNumber = 0
function NextImage() {
document.images["VCRImage"].src = img[imgNumber++]
if (imgNumber == img.length) {
img.shuffle ();
imgNumber = 0;
}
}
window.setInterval (NextImage, 3000);
and the html:
<div class="item">
<script type="text/javascript">document.writeln('<img src="'+img[0]+'" name="VCRImage">');</script>
</div>
A working example can be found here: https://jsfiddle.net/admiringtheorchid/esm3u0xg/
I would like to ease the transition between each image. How can this be accomplished?
Try this method with jQuery: https://jsfiddle.net/joe_young/qxf69hsL/
//create a jQuery object of the image
var $image = $(document.images["VCRImage"]);
//fade out the image, and once it has finished fading out...
$image.fadeOut(function() {
//change the image source
$image.attr("src", img[imgNumber++]);
});
//fade the image back in
$image.fadeIn();

prettyPhoto change title on hover over thumbnail

I use prettyPhoto version: 3.1.6 to display simple lightbox with thumbnail.
Normally title attribute appear inside the lightbox for the active/selected image.
My client ask for this change
http://i.stack.imgur.com/7932x.jpg
How I can accomplish this?
Here is a part of my code
<a rel="prettyPhoto[pp_gal]"href="1.jpg" title="Staring at the sun"><img src="2.jpg"></a>
try this jquery function. You may have to style it a little.
(function($)
{
$.fn.avia_activate_lightbox = function(variables)
{
var defaults =
{
autolinkElements: 'a[rel^="prettyPhoto"], a[rel^="lightbox"], a[href$=jpg], a[href$=png], a[href$=gif], a[href$=jpeg], a[href$=".mov"] , a[href$=".swf"], a[href$=".flv"] , a[href*="vimeo.com"] , a[href*="youtube.com"]'
};
var options = $.extend(defaults, variables);
var imagedefaults =
{
autolinkImages: 'img[title!=""]'
};
return this.each(function()
{
var elements = $(options.autolinkElements, this),
lastParent = "",
counter = 0;
var images = $(imagedefaults.autolinkImages, this),
imgcounter = 0;
var alltitlesalt = new Array();
var alltitles = new Array();
images.each(function()
{
if($(this).attr('alt') != undefined && $(this).attr('alt') !="")
{
alltitlesalt.push($(this).attr('alt'));
}
else
{
alltitlesalt.push("");
};
alltitles.push($(this).attr('title'));
});
elements.each(function()
{
var el = $(this),
parentPost = el.parents('.post-entry:eq(0)'),
group = 'auto_group';
if(parentPost.get(0) != lastParent)
{
lastParent = parentPost.get(0);
counter ++;
}
if((el.attr('rel') == undefined || el.attr('rel') == '') && !el.hasClass('noLightbox'))
{
el.attr('rel','lightbox');
el.attr('title',alltitles[imgcounter]);
el.attr('alt',alltitlesalt[imgcounter]);
imgcounter ++;
}
});
if($.fn.prettyPhoto)
elements.prettyPhoto({ "theme": 'premium_photo', 'slideshow': 5000 }); /* facebook /light_rounded / dark_rounded / light_square / dark_square */
});
};
})(jQuery);
Reference

How to filter images of specific size with jQuery?

I'm trying to find images larger than a specific size in an HTML page, but the following code does not work correctly:
function findImages(url)
{
$.ajax({
url: url,
dataType: "html",
success: function (data) {
var html = $.parseHTML( data ),
imgs = $(html).find("img").filter(function() {
return ($(this).width() > 50) && ($(this).height() > 50)
});
len = imgs.length;
if( len > 0 ){
$.each(imgs, function(index, img) {
console.log(img.width);
});
} else {
console.log("Image not found");
}
},
});
};
I expect the filter part to return images whose width and height is larger than 50, but it does not seem to work for me. What am I doing wrong here?
Suppose html response look like this
var imagesHTML = [
'<img src="http://" width="100" height="500">',
'<img src="http://" width="100" height="500">',
'<img src="http://" width="50" height="500">',
'<img src="http://" width="50" height="50">',
'<img src="http://" width="100" height="50">',
'<img src="http://" width="50" height="50" style="width: 100px">'
];
var html = $(images.join(''));
#1 - filter by html attributes
var imgs = html.find("img").filter(function() {
return ($(this).attr('width') > 50) && ($(this).attr('height') > 50);
});
// push to DOM
#2 Filter by width (inline styles)
var doc = document.createDocumentFragment(),
div = document.createElement('div');
var imgs = $(div).html(html).find('img').filter(function () {
return ($(this).width() > 50) && ($(this).height() > 50)
});
// push to DOM
#3 - example - if width and height attributes have not been setted for images
function loadImages(content, callback) {
var html = $(content),
urls = [];
function filter(width, height) {
return (width > 256 && height > 256);
}
function load(el) {
var def = new $.Deferred(),
img = new Image();
img.onload = function () {
if (filter(img.width, img.height)) {
return def.resolve(el.get(0));
}
def.resolve(null);
};
img.onerror = function () {
def.resolve();
};
img.src = el.attr('src');
return def;
}
urls = $('<div />').html(html).find('img').map(function () {
return load($(this));
}).get();
$.when.apply(null, urls).done(function () {
callback.call(this, [].slice.call(arguments, 0).filter(Boolean));
});
}
loadImages(images.join(''), function (images) {
var content = $('<div />');
images.forEach(function (el) {
content.append(el);
});
$('body').html(content.get(0));
});
In my opinion better send JSON which will contain all images (urls) :), because creating unnecessary HTTP queries it's not good solution.
If you want to get every image corresponding your needs, loop through every image in your page and check for it :
var img = document.getElementsByTagName('img');
for(var i = 0; i < imgs.length ; i++) {
if (img[i].width > 2) {
// Do your thing
}
}
And if you have a particular image target and know it's ID, it's even easier :
if (document.getElementById('#theone').width() > 2) {
// Do your thing
}
Note : this is plain javascript, if you use jQuery just change the bits of syntax that corresponds
var img = $('img');
for(var i = 0; i < imgs.length ; i++) {
if (img[i].width > 2) {
// Do your thing
}
}
and
if ($('#theone').width() > 2) {
// Do your thing
}

jquery html(array) doesn't insert all items in array

When I run the javascript code below, it load specified amount of images from Flickr.
By var photos = photoGroup.getPhotos(10) code, I get 10 images from cache.
Then, I can see the object has exactly 10 items by checking console.log(photos);
But actual image appeared on the page is less than 10 items...
I have no idea why this work this way..
Thank you in advance.
<html>
<head>
<script src="http://code.jquery.com/jquery-2.1.0.min.js"></script>
<script>
var PhotoGroup = function(nativePhotos, callback) {
var _cache = new Array();
var numberOfPhotosLoaded = 0;
var containerWidth = $("#contents").css('max-width');
var containerHeight = $("#contents").css('max-height');
$(nativePhotos).each(function(key, photo) {
$("<img src='"+"http://farm" + photo["farm"] + ".staticflickr.com/" + photo["server"] + "/" + photo["id"] + "_" + photo["secret"] + "_b.jpg"+"'/>")
.attr("alt", photo['title'])
.attr("data-cycle-title", photo['ownername'])
.load(function() {
if(this.naturalWidth >= this.naturalHeight) {
$(this).attr("width", containerWidth);
} else {
$(this).attr("height", containerHeight);
}
_cache.push(this);
if(nativePhotos.length == ++numberOfPhotosLoaded)
callback();
})
});
var getRandom = function(max) {
return Math.floor((Math.random()*max)+1);
}
this.getPhotos = function(numberOfPhotos) {
var photoPool = new Array();
var maxRandomNumber = _cache.length-1;
while(photoPool.length != numberOfPhotos) {
var index = getRandom(maxRandomNumber);
if($.inArray(_cache[index], photoPool))
photoPool.push(_cache[index]);
}
return photoPool;
}
}
var Contents = function() {
var self = this;
var contentTypes = ["#slideShowWrapper", "#video"];
var switchTo = function(nameOfContent) {
$(contentTypes).each(function(contentType) {
$(contentType).hide();
});
switch(nameOfContent) {
case("EHTV") :
$("#video").show();
break;
case("slideShow") :
$("#slideShowWrapper").show();
break;
default :
break;
}
}
this.startEHTV = function() {
switchTo("EHTV");
document._video = document.getElementById("video");
document._video.addEventListener("loadstart", function() {
document._video.playbackRate = 0.3;
}, false);
document._video.addEventListener("ended", startSlideShow, false);
document._video.play();
}
this.startSlideShow = function() {
switchTo("slideShow");
var photos = photoGroup.getPhotos(10)
console.log(photos);
$('#slideShow').html(photos);
}
var api_key = '6242dcd053cd0ad8d791edd975217606';
var group_id = '2359176#N25';
var flickerAPI = 'http://api.flickr.com/services/rest/?jsoncallback=?';
var photoGroup;
$.getJSON(flickerAPI, {
api_key: api_key,
group_id: group_id,
format: "json",
method: "flickr.groups.pools.getPhotos",
}).done(function(data) {
photoGroup = new PhotoGroup(data['photos']['photo'], self.startSlideShow);
});
}
var contents = new Contents();
</script>
</head>
<body>
<div id="slideShow"></div>
</body>
</html>
I fix your method getRandom() according to this article, and completely re-write method getPhotos():
this.getPhotos = function(numberOfPhotos) {
var available = _cache.length;
if (numberOfPhotos >= available) {
// just clone existing array
return _cache.slice(0);
}
var result = [];
var indices = [];
while (result.length != numberOfPhotos) {
var r = getRandom(available);
if ($.inArray(r, indices) == -1) {
indices.push(r);
result.push(_cache[r]);
}
}
return result;
}
Check full solution here: http://jsfiddle.net/JtDzZ/
But this method still slow, because loop may be quite long to execute due to same random numbers occurred.
If you care about performance, you need to create other stable solution. For ex., randomize only first index of your images sequence.

Categories