all,
I'm working on a project with the great bigvideo.js. Nothing fancy: I just have a few short videos playing in the background. No need for navigation, captions, etc. Here is the simple code I'm using:
var BV = new $.BigVideo();
BV.init();
if (Modernizr.touch) {
BV.show ('/images/backgrounds/bg-bob-test.jpg');
} else {
BV.show(['/videos/bob_video_test_color.mp4', '/videos/bob_video_test_one.mp4'],{ambient:true});
}
});
It even works with Firefox/ogg files...until I try to add multiple files as per the website's instructions:
$(function() {
var BV = new $.BigVideo({useFlashForFirefox:false});
BV.init();
BV.show('vids/river.mp4', {altSource:'vids/river.ogv'});
});
My question is this: how do I combine the two, correctly? In other words, how do I call the 'altSource' for each mp4 video so that multiple videos loop in Firefox? I tried:
var BV = new $.BigVideo({useFlashForFirefox:false});
BV.init();
if (Modernizr.touch) {
BV.show ('/images/backgrounds/bg-bob-test.jpg';
} else {
BV.show(['/videos/bob_video_test_one.mp4', {altSource:'/videos/bob_video_test_one.ogg'},'/videos/bob_video_test_two.mp4', {altSource:'/videos/bob_video_test_two.ogg'}],{ambient:true});
}
});
To no avail. I'm sure this is a super-simple answer for someone more in the know! Many thanks in advance.
I had the same problem and solved it by simply checking for Firefox instead of using altSource:
$(function() {
var BV = new $.BigVideo({useFlashForFirefox:false});
BV.init();
if ($.browser.msie || $.browser.opera || Modernizr.touch) {
BV.show('video-poster.jpg');
} else if ($.browser.mozilla) {
BV.show('video.ogv', {ambient:true});
} else {
BV.show('video.mp4', {ambient:true});
}
});
Here is a simple way of looking at which browser and if its a touch device (if you are using a recent jquery library you may need to use jquery migrate):
$(function() {
var BV = new $.BigVideo({useFlashForFirefox:false});
if($.browser.msie||$.browser.opera){
BV.init();
} else {
var vids = [
'/assets/vids/1.mp4',
'/assets/vids/2.mp4',
'/assets/vids/3.mp4'
];
vids.sort(function() { return 0.5 - Math.random() });
var vidsFF = [
'/assets/vids/1.ogv',
'/assets/vids/2.ogv',
'/assets/vids/3.ogv'
];
vidsFF.sort(function() { return 0.5 - Math.random() });
BV.init();
if (Modernizr.touch) {
BV.show('assets/vids/fallback.jpg');
} else {
if($.browser.mozilla){
BV.show([vidsFF[0], vidsFF[1], vidsFF[2]], {ambient:true});
} else {
BV.show([vids[0], vids[1], vids[2]], {ambient:true});
}
}
}
});
You need to then set a background image cover for fallback (basically rubbish IE):
div {
background: url(../images/feature-background.jpg) no-repeat center center;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/feature-background.jpg', sizingMethod='scale');
-ms-filter: "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='../images/feature-background.jpg', sizingMethod='scale')";
}
After looking at the big video source code it seems like you cannot add a list for altSource, nor can you supply an object that has a source and an altSource as the first argument to show.
I think what you should do is listen to the bigvideo play events, manager your playlist outside of bigvideo and simply call show when the current video stops.
Maybe something like:
var playlist = [{source: '/videos/bob_video_test_one.mp4', altSource:'/videos/bob_video_test_one.ogg'},{source: '/videos/bob_video_test_two.mp4', altSource:'/videos/bob_video_test_two.ogg'}];
function playNext() {
var next = playlist.shift();
BV.show(next.source, next.altSource);
}
var player = BV.getPlayer();
player.on('ended', playNext);
playNext();
Related
My issue is I am trying to get a background image to change every second within the first div of a travel blog I have been working on using JS. I am also having text display on top of the image. There are couple tutorials on YouTube but they just arent working for me.
my css is:
#title{
background-image: url("../images/Nature5.jpg");
background-size: cover;
padding-top: 350px;
padding-bottom: 350px;
}
And my Javascript is:
var changingImages = document.querySelector('title');
var images = [
"url('../images/Nature1.jpg')",
"url('../images/Nature2.jpg')",
"url('../images/Nature3.jpg')",
"url('../images/Nature4.jpg')",
"url('../images/Nature5.jpg')",
"url('../images/Nature6.jpg')"
]
setInterval( function () {
var bg = images[Math.floor(Math.random() * images.length)]
title.style.backgroundImage = bg;
},1000)
Perhaps the images are too large or maybe I'm just too new to JS.
Any help is appreciated!
I tried placing the variabule "changingImages" within the function also changing the "title.style.backgroundImage = bg;" to be more spacific.
please try this one
add class selector in query selector argument '.title'
var changingImages = document.querySelector('.title'); // the change
var images = [
"url('../images/Nature1.jpg')",
"url('../images/Nature2.jpg')",
"url('../images/Nature3.jpg')",
"url('../images/Nature4.jpg')",
"url('../images/Nature5.jpg')",
"url('../images/Nature6.jpg')"
]
setInterval( function () {
var bg = images[Math.floor(Math.random() * images.length) + 1] // the change
changingImages.style.backgroundImage = bg; // the change
},1000)
hope this work
I'm currently working on a private dashboard. This dashboard should have changing background images that changes every minute (should be no problem to switch it to an hour or 20 seconds if I got it working then).
In order to do so, I registered for the [Pixabay API][1] and created the following API request
https://pixabay.com/api/?key=[my_key]f&q=nature&image_type=photo&orientation=horizontal&min_width=1920&min_height=1080&page=1&per_page=100
With that request, I get an array of 100 elements, each one containing the following information:
comments: 639
downloads: 785498
favorites: 3020
id: 736885
imageHeight: 1195
imageSize: 186303
imageWidth: 1920
largeImageURL: "https://pixabay.com/get/51e3d34b4257b108f5d0846096293076123ddee2504c704c7c2879d79048c05a_1280.jpg"
likes: 3966
pageURL: "https://pixabay.com/photos/tree-sunset-amazing-beautiful-736885/"
previewHeight: 93
previewURL: "https://cdn.pixabay.com/photo/2015/04/23/22/00/tree-736885_150.jpg"
previewWidth: 150
tags: "tree, sunset, amazing"
type: "photo"
user: "Bessi"
userImageURL: "https://cdn.pixabay.com/user/2019/04/11/22-45-05-994_250x250.jpg"
user_id: 909086
views: 2042402
webformatHeight: 398
webformatURL: "https://pixabay.com/get/51e3d34b4257b10ff3d8992cc62f3f79173fd9e64e507440722d78d39248c7_640.jpg"
webformatWidth: 640
From these 100 elements, I then randomly select one, take the largeImageURL and set it as background, together with a semi-transparent dark overlay to be able to read the text on top of it better. All this is done within a setInterval, so it happens every x milliseconds.
This is the code for it:
setInterval(function(){
$.post('getBackgroundImages.php', { }, function(data) {
var imageCollection = JSON.parse(data);
var imageNumber = Math.floor(Math.random() * 100);
var imageLink = imageCollection.hits[imageNumber].largeImageURL;
$('body').css("background","linear-gradient(rgba(0,0,0,.3), rgba(0,0,0,.3)),url('"+imageLink+"')");
});
},60000);
`getBackgroundImages.php' does nothing more then printing the content of the API-request.
The question now is the following: In the implemented solution, everything works, the new photo is displayed as background and switching works. However, the background is always set to a grey background for about half a second, before the image is displayed, which looks really not good, especially when often switching images.
What I'd like to get is a switching of the background without this grey background for a short time, propably even with a transition, so the change is not so abrupt...
I found a solution to first display a blured preview of the image before display the full resolution one. However, I think that this shouldn't be needed, as basically, the image has enough time to load and the background should change AFTER the image has loaded.. I do not care, if the change happens every 62 seconds, even though I set it to 60 seconds, because the image needs to load first.
Can anybody give me a hint on how to get this working better?
Thanks in advance!
[1]: https://pixabay.com/api/docs/
Maybe the most simple would be to alternate between two containers that works like backgrounds :
HTML :
<body>
<div class='bg' id='firstBg'></div>
<div class='bg' id='secondBg'></div>
<...Your Stuff...>
</body>
CSS :
body {
background: transparent;
}
.bg {
position: fixed;
left: 0;
top: 0;
width: 100vw;
height: 100vh;
background-position: center;
z-index: -1;
background-size: cover;
transition: 3s ease-in;
}
#secondBg {
display: none;
}
JS :
setInterval(function(){
$.post('getBackgroundImages.php', { }, function(data) {
var imageCollection = JSON.parse(data);
var imageNumber = Math.floor(Math.random() * 100);
var imageLink = imageCollection.hits[imageNumber].largeImageURL;
if ($('#firstBg').css('display') == 'none') {
$('#firstBg').css("background-image","url('"+imageLink+"')");
$('#firstBg').fadeIn();
$('#secondBg').fadeOut();
}
else {
$('#secondBg').css("background-image","url('"+imageLink+"')");
$('#secondBg').fadeIn();
$('#firstBg').fadeOut();
}
});
},60000);
I did the following solution now, thanks to the hint of #zero298.
<script>
function loadImages (images) {
// each image will be loaded by this function.
// it returns a Promise that will resolve once
// the image has finished loading
let loader = function (src) {
return new Promise(function (resolve, reject) {
let img = new Image();
img.onload = function () {
// resolve the promise with our url so it is
// returned in the result of Promise.all
resolve(src);
};
img.onerror = function (err) {
reject(err);
};
img.src = src;
});
};
// create an image loader for each url
let loaders = [];
images.forEach(function (image) {
loaders.push(loader(image));
});
// Promise.all will return a promise that will resolve once all of of our
// image loader promises resolve
return Promise.all(loaders);
}
function cycleImages (images) {
let index = 0;
setInterval(function() {
// since we need an array of the image names to preload them anyway,
// just load them via JS instead of class switching so you can cut them
// out of the CSS and save some space by not being redundant
$('body').css("background","linear-gradient(rgba(0,0,0,.3), rgba(0,0,0,.3)),url('"+images[index]+"')");
// increment, roll over to 0 if at length after increment
index = (index + 1) % images.length;
}, 28800000);
}
$(function(){
$.post('getBackgroundImages.php', { }, function(data) {
var imageCollection = JSON.parse(data);
var imageNumber = Math.floor(Math.random() * 100);
var imageLink = imageCollection.hits[imageNumber].largeImageURL;
$('body').css("background","linear-gradient(rgba(0,0,0,.3), rgba(0,0,0,.3)),url('"+imageLink+"')");
});
$.ajax('getBackgroundImages.php',{
success:function(data) {
var parsed = JSON.parse(data);
var images = parsed.hits;
var imageUrls = [];
images.forEach(function(item,index){
imageUrls.push(item.largeImageURL);
})
loadImages(imageUrls).then(cycleImages).catch(function (err) {
console.error(err);
});
}
});
});
</script>
This first puts all imageUrls into an array, then loads all images with Promise to then display then without a big delay.. I didn't really manage to get a nice transition between switching the images, as jQuerys fade-to method lets the content of the page fade out as well, rather then only the background image...
Adding more div's / changing the structure of the page is not too easy by the way, as there is a lot of floating and other css rules to make the elements appear on various positions on the page. Adding a div around all content in order to try to give that div the background-image destroyed the hole layout...
All in all, I'm confident with this solution, however, if anybody has a good idea to make the switch more smooth, feel free to tell me :)
i am wanting to have my webpage display a different background every minute or there abouts, the image is also quite large so it would have to fit using cover. The background is a background-image on the body here is my css code
#body {
background-image: url("home.jpg");
background-position: top;
background-size: cover;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
margin: 0px;
}
and i want to have the script change the url (or source img) to a differrent one every minute. I tryed this with setInteval and onLoad in html but i cant crack it!
Thanks very much
An easiest solution is to use jQuery backstretch plugin.
$.backstretch([
"http://dl.dropbox.com/u/515046/www/outside.jpg",
"http://dl.dropbox.com/u/515046/www/garfield-interior.jpg",
"http://dl.dropbox.com/u/515046/www/cheers.jpg"
], {duration: 3000, fade: 750});
Here is a jQuery only solution.
$(function() {
var body = $('body');
var backgrounds = new Array(
'url(https://dl.dropbox.com/u/515046/www/outside.jpg)',
'url(https://dl.dropbox.com/u/515046/www/garfield-interior.jpg)'
);
var current = 0;
function nextBackground() {
body.css(
'background',
backgrounds[current = ++current % backgrounds.length]
);
setTimeout(nextBackground, 10000);
}
setTimeout(nextBackground, 10000);
body.css('background', backgrounds[0]);
});
Reference
IMHO this code snippet will get you started.
// get reference to body
var main = document.body;
// next two lines of code allow toggle between colors to demonstrate this example.
var color = function() {
var col = "red";
return function() {
col = (col === "red" ? "blue" : "red");
return col;
};
};
var nextColor = color();
// using setTimeout instead of setInterval
function loop() {
var timeoutId = setTimeout(function() {
console.log('clearing', timeoutId)
clearTimeout(timeoutId);
main.style.background = nextColor();
loop();
}, 1000);
}
https://jsfiddle.net/4L4bww5r/
I have conversation screen to be developed i have planned to change the background images for every millisecond so that it looks like a animation. I tried using jquery settimeout and setinterval but both the ways stack of images changing in small interval hangs the browser, any ideas of how to accomplish my task.
function change_background(new_image_source) {
var myimage = $( '#spriteanim' );
myimage.attr('src','style/images/Sprites/Screen1/'+new_image_source+'.png');
console.log(myimage.attr('src'));
timer = setTimeout( function () {
new_image_source = new_image_source+1;
change_background(new_image_source);
}, 50);
if(new_image_source>=10899){
change_background(new_image_source);
clearTimeout(timer);
}
}
Changing the src attribute will never work as you want. That's because the browser needs time to load the image. Even it is cached it is still too slow for animating. I'll suggest to combine your images into sprite and change the background-position. You can even do that with pure css transition.
For example -> http://jsfiddle.net/krasimir/uzZqg/
HTML
<div class="image"></div>
CSS
.image {
background: url('...');
width: 200px;
height: 200px;
transition: all 4000ms;
-webkit-transition: all 4000ms;
}
.image:hover {
background-position: -500px 0;
}
You can even use keyframes.
Here is how you can preload your images http://jsfiddle.net/krasimir/DfWJm/1/
HTML
<div id="preloader"></div>
JS
var images = [
'http://www.australia.com/contentimages/about-landscapes-nature.jpg',
'http://www.australia.com/contentimages/about-landscapes-nature.jpg',
'http://www.australia.com/contentimages/about-landscapes-nature.jpg',
'http://www.australia.com/contentimages/about-landscapes-nature.jpg',
'http://www.australia.com/contentimages/about-landscapes-nature.jpg',
'http://www.australia.com/contentimages/about-landscapes-nature.jpg'
];
var preloader = document.getElementById("preloader");
var preloadImages = function(callback) {
if(images.length == 0) {
callback();
return;
}
var image = images.shift();
var img = document.createElement("IMG");
img.setAttribute("src", image);
preloader.appendChild(img);
img.addEventListener("load", function() {
console.log("image loaded");
preloadImages(callback);
});
}
preloadImages(function() {
// your animation starts here
alert("Images loaded");
});
Of course you may hide the #preloader div with display: none;
Checkout http://spritely.net/
It'll handle the details of animating a spritesheet. Let's you set FPS and control playback.
I think 'every millisecond' is a bit too fast.
Image load takes some time. I think, you should load all the images once, before starting the animation. It will take some time, since number of images you are using seems to be 10899. And just hide all but one every few milliseconds. 'Few milliseconds', instead of 'every millisecond', should do your job.
UPDATE:
Name your images spriteanim0, spriteanim1... like this. After all the images have been loaded, and all have been assigned display: none, call this js function:
var new_image_source1;
function change_background(prev_image_source, new_image_source) {
document.getElementById('spriteanim' + prev_image_source).style.display = 'none';
document.getElementById('spriteanim' + new_image_source).style.display = 'block';
if (new_image_source >= 10899)
new_image_source1 = 0;
else
new_image_source1 = new_image_source + 1;
window.setTimeout(
function () {
change_background(new_image_source, new_image_source1);
},
50);
}
You can try this and change the setTimeout interval value accordingly, as needed.
As many of you know it is widely used to lazy load images.
Now i want to use this as lazy load div background images.
How can i do that ?
I am currently able to use http://www.appelsiini.net/projects/lazyload that plugin
So i need to modify it in a way that it will work with div backgrounds
Need help. Thank you.
The below part i suppose lazy loads images
$self.one("appear", function() {
if (!this.loaded) {
if (settings.appear) {
var elements_left = elements.length;
settings.appear.call(self, elements_left, settings);
}
$("<img />")
.bind("load", function() {
$self
.hide()
.attr("src", $self.data(settings.data_attribute))
[settings.effect](settings.effect_speed);
self.loaded = true;
/* Remove image from array so it is not looped next time. */
var temp = $.grep(elements, function(element) {
return !element.loaded;
});
elements = $(temp);
if (settings.load) {
var elements_left = elements.length;
settings.load.call(self, elements_left, settings);
}
})
.attr("src", $self.data(settings.data_attribute));
}
});
Jquery plugin lazy load
First you need to think off when you want to swap. For example you could switch everytime when its a div tag thats loaded. In my example i just used a extra data field "background" and whenever its set the image is applied as a background image.
Then you just have to load the Data with the created image tag. And not overwrite the img tag instead apply a css background image.
Here is a example of the code change:
if (settings.appear) {
var elements_left = elements.length;
settings.appear.call(self, elements_left, settings);
}
var loadImgUri;
if($self.data("background"))
loadImgUri = $self.data("background");
else
loadImgUri = $self.data(settings.data_attribute);
$("<img />")
.bind("load", function() {
$self
.hide();
if($self.data("background")){
$self.css('backgroundImage', 'url('+$self.data("background")+')');
}else
$self.attr("src", $self.data(settings.data_attribute))
$self[settings.effect](settings.effect_speed);
self.loaded = true;
/* Remove image from array so it is not looped next time. */
var temp = $.grep(elements, function(element) {
return !element.loaded;
});
elements = $(temp);
if (settings.load) {
var elements_left = elements.length;
settings.load.call(self, elements_left, settings);
}
})
.attr("src", loadImgUri );
}
the loading stays the same
$("#divToLoad").lazyload();
and in this example you need to modify the html code like this:
<div data-background="http://apod.nasa.gov/apod/image/9712/orionfull_jcc_big.jpg" id="divToLoad" />
but it would also work if you change the switch to div tags and then you you could work with the "data-original" attribute.
Here's an fiddle example: http://jsfiddle.net/dtm3k/1/
EDIT: the post from below is from 2012 and absolete by now!
I do it like this:
<div class="lazyload" style="width: 1000px; height: 600px" data-src="%s">
<img class="spinner" src="spinner.gif"/>
</div>
and load with
$(window).load(function(){
$('.lazyload').each(function() {
var lazy = $(this);
var src = lazy.attr('data-src');
$('<img>').attr('src', src).load(function(){
lazy.find('img.spinner').remove();
lazy.css('background-image', 'url("'+src+'")');
});
});
});
Mid last year 2020 web.dev posted an article that shared some new ways to do this with the the new IntersectionObserver which at the time of writing this answer is supported in all major browsers. This will allow you to use a very light weight background image, or background color placeholder while you wait for the image to come to the edge of the viewport and then it is loaded.
CSS
.lazy-background {
background-image: url("hero-placeholder.jpg"); /* Placeholder image */
}
.lazy-background.visible {
background-image: url("hero.jpg"); /* The final image */
}
Javascript
document.addEventListener("DOMContentLoaded", function() {
var lazyBackgrounds = [].slice.call(document.querySelectorAll(".lazy-background"));
if ("IntersectionObserver" in window) {
let lazyBackgroundObserver = new IntersectionObserver(function(entries, observer) {
entries.forEach(function(entry) {
if (entry.isIntersecting) {
entry.target.classList.add("visible");
lazyBackgroundObserver.unobserve(entry.target);
}
});
});
lazyBackgrounds.forEach(function(lazyBackground) {
lazyBackgroundObserver.observe(lazyBackground);
});
}
});
I've found this on the plugin's official site:
<div class="lazy" data-original="img/bmw_m1_hood.jpg" style="background-image: url('img/grey.gif'); width: 765px; height: 574px;"></div>
$("div.lazy").lazyload({
effect : "fadeIn"
});
Source: http://www.appelsiini.net/projects/lazyload/enabled_background.html
I've created a "lazy load" plugin which might help. Here is the a possible way to get the job done with it in your case:
$('img').lazyloadanything({
'onLoad': function(e, LLobj) {
var $img = LLobj.$element;
var src = $img.attr('data-src');
$img.css('background-image', 'url("'+src+'")');
}
});
It is simple like maosmurf's example but still gives you the "lazy load" functionality of event firing when the element comes into view.
https://github.com/shrimpwagon/jquery-lazyloadanything
It's been a moment that this question is asked, but this doesn't mean that we can't share other answers in 2020. Here is an awesome plugin with jquery:jQuery Lazy
The basic usage of Lazy:
HTML
<!-- load background images of other element types -->
<div class="lazy" data-src="path/to/image.jpg"></div>
enter code here
JS
$('.lazy').Lazy({
// your configuration goes here
scrollDirection: 'vertical',
effect: 'fadeIn',
visibleOnly: true,
onError: function(element) {
console.log('error loading ' + element.data('src'));
}
});
and your background images are lazy loading. That's all!
To see real examples and more details check this link lazy-doc.
Without jQuery
HTML
background-image: url('default-loading-image');
data-src="image-you-want-to-load"
<div class="ajustedBackground" style="background-image: url('default-loading-image');" data-src="image-you-want-to-load"><div>
var tablinks = document.getElementsByClassName("ajustedBackground");
for (i = 0; i < tablinks.length; i++) {
var lazy = tablinks[i];
var src = lazy.dataset.src;
lazy.style.backgroundImage = 'url("'+src+'")';
}
.ajustedBackground{
width: 100%;
height: 300px;
background-size: 100%;
border-radius: 5px;
background-size: cover;
background-position: center;
position: relative;
}
<div class="ajustedBackground" style="background-image: url('https://monyo.az/resources/img/ezgif-6-b10ea37ef846.gif');" data-src="https://monyo.az/resources-qrcode/img/Fathir_7%201.png"><div>
Finds all ajustedBackground classname in html and load image from data-src
function lazyloadImages(){
var tablinks = document.getElementsByClassName("ajustedBackground");
for (i = 0; i < tablinks.length; i++) {
var lazy = tablinks[i];
var src = lazy.dataset.src;
lazy.style.background = 'url("'+src+'")';
}
}
Lazy loading images using above mentioned plugins uses conventional way of attaching listener to scroll events or by making use of setInterval and is highly non-performant as each call to getBoundingClientRect() forces the browser to re-layout the entire page and will introduce considerable jank to your website.
Use Lozad.js (just 569 bytes with no dependencies), which uses InteractionObserver to lazy load images performantly.
I had to deal with this for my responsive website. I have many different backgrounds for the same elements to deal with different screen widths. My solution is very simple, keep all your images scoped to a css selector, like "zoinked".
The logic:
If user scrolls, then load in styles with background images associated with them.
Done!
Here's what I wrote in a library I call "zoinked" I dunno why. It just happened ok?
(function(window, document, undefined) { var Z = function() {
this.hasScrolled = false;
if (window.addEventListener) {
window.addEventListener("scroll", this, false);
} else {
this.load();
} };
Z.prototype.handleEvent = function(e) {
if ($(window).scrollTop() > 2) {
this.hasScrolled = true;
window.removeEventListener("scroll", this);
this.load();
} };
Z.prototype.load = function() {
$(document.body).addClass("zoinked"); };
window.Zoink = Z;
})(window, document);
For the CSS I'll have all my styles like this:
.zoinked #graphic {background-image: url(large.jpg);}
#media(max-width: 480px) {.zoinked #graphic {background-image: url(small.jpg);}}
My technique with this is to load all the images after the top ones as soon as the user starts to scroll. If you wanted more control you could make the "zoinking" more intelligent.
Using jQuery I could load image with the check on it's existence. Added src to a plane base64 hash string with original image height width and then replaced it with the required url.
$('[data-src]').each(function() {
var $image_place_holder_element = $(this);
var image_url = $(this).data('src');
$("<div class='hidden-class' />").load(image_url, function(response, status, xhr) {
if (!(status == "error")) {
$image_place_holder_element.removeClass('image-placeholder');
$image_place_holder_element.attr('src', image_url);
}
}).remove();
});
Of course I used and modified few stack answers. Hope it helps someone.
This is an AngularJS Directive that will do this. Hope it helps someone
Usage:
<div background-image="{{thumbnailUrl}}"></div>
Code:
import * as angular from "angular";
export class BackgroundImageDirective implements angular.IDirective {
restrict = 'A';
link(scope: angular.IScope, element: angular.IAugmentedJQuery, attrs: angular.IAttributes) {
var backgroundImage = attrs["backgroundImage"];
let observerOptions = {
root: null,
rootMargin: "0px",
threshold: []
};
var intersectionCallback: IntersectionObserverCallback = (entries, self) => {
entries.forEach((entry) => {
let box = entry.target as HTMLElement;
if (entry.isIntersecting && !box.style.backgroundImage) {
box.style.backgroundImage = `url(${backgroundImage})`;
self.disconnect();
}
});
}
var observer = new IntersectionObserver(intersectionCallback, observerOptions);
observer.observe(element[0]);
}
static factory(): angular.IDirectiveFactory {
return () => new BackgroundImageDirective();
}
}
<div class="lazy" data-bg="img/bmw_m1_hood.jpg" style="width: 765px; height: 574px;"></div>
var lazyLoadInstance = new LazyLoad({
load_delay: 100,
effect : "fadeIn"
});
using the vanilla lazyload
https://www.npmjs.com/package/vanilla-lazyload
I know it's not related to the image load but here what I did in one of the job interview test.
HTML
<div id="news-feed">Scroll to see News (Newest First)</div>
CSS
article {
margin-top: 500px;
opacity: 0;
border: 2px solid #864488;
padding: 5px 10px 10px 5px;
background-image: -webkit-gradient(
linear,
left top,
left bottom,
color-stop(0, #DCD3E8),
color-stop(1, #BCA3CC)
);
background-image: -o-linear-gradient(bottom, #DCD3E8 0%, #BCA3CC 100%);
background-image: -moz-linear-gradient(bottom, #DCD3E8 0%, #BCA3CC 100%);
background-image: -webkit-linear-gradient(bottom, #DCD3E8 0%, #BCA3CC 100%);
background-image: -ms-linear-gradient(bottom, #DCD3E8 0%, #BCA3CC 100%);
background-image: linear-gradient(to bottom, #DCD3E8 0%, #BCA3CC 100%);
color: gray;
font-family: arial;
}
article h4 {
font-family: "Times New Roman";
margin: 5px 1px;
}
.main-news {
border: 5px double gray;
padding: 15px;
}
JavaScript
var newsData,
SortData = '',
i = 1;
$.getJSON("http://www.stellarbiotechnologies.com/media/press-releases/json", function(data) {
newsData = data.news;
function SortByDate(x,y) {
return ((x.published == y.published) ? 0 : ((x.published < y.published) ? 1 : -1 ));
}
var sortedNewsData = newsData.sort(SortByDate);
$.each( sortedNewsData, function( key, val ) {
SortData += '<article id="article' + i + '"><h4>Published on: ' + val.published + '</h4><div class="main-news">' + val.title + '</div></article>';
i++;
});
$('#news-feed').append(SortData);
});
$(window).scroll(function() {
var $window = $(window),
wH = $window.height(),
wS = $window.scrollTop() + 1
for (var j=0; j<$('article').length;j++) {
var eT = $('#article' + j ).offset().top,
eH = $('#article' + j ).outerHeight();
if (wS > ((eT + eH) - (wH))) {
$('#article' + j ).animate({'opacity': '1'}, 500);
}
}
});
I am sorting the data by Date and then doing lazy load on window scroll function.
I hope it helps :)
Demo