JS and CSS changing image on interval - javascript

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/

Related

How to convert this jquery code into javascript DOM code?

Hi everyone I was just wondering if anyone know how to convert this css/jquery code into javascript DOM code?
I started coding my entire code using javascript DOM for a project but then I found this code which will make the background image move upwards in an infinite loop.
I just need some help in figuring out how to convert the code since I know nothing about jquery.
$(function(){
var x = 0;
setInterval(function(){
$('body').css('background-position','0'+--x + 'px');
}, 10);
})
html,body { height: 100%; overflow: hidden;}
body {
background-image: url('http://lorempixel.com/1900/1200/');
background-repeat: repeat-y;
background-size: 100% 100%;
}
html,body { height: 100%; overflow: hidden;}
body {
background-image: url('http://lorempixel.com/1900/1200/');
background-repeat: repeat-y;
background-size: 100% 100%;
}
$(function(){
var x = 0;
setInterval(function(){
$('body').css('background-position','0'+--x + 'px');
}, 10);
})
$('body') selects the body element; .css(prop, value) sets the CSS property prop to value. With the plain DOM API, you can get the body using document.body and assign styles by assigning to properties on the element’s style, noting that hyphenated-names become camelCase.
var x = 0;
setInterval(function () {
document.body.style.backgroundPosition = '0 ' + --x + 'px';
}, 10);

Potential function overloading in javascript: naming issue

I am new to Javascript but I was able to piece together something to create a random background image on page load. This was successfully used for a Div object on the page.
Since this worked well, I wanted to use this command again for a second Div object on the same page. Both Divs had separate CSS style names so I thought this would be fine. However as soon as I use both commands together, only one will work.
I assumed it was an overloading problem, but I tried renaming everything I could and it still hasn't solved it. Is there something else I need to rename that I'm missing or do I need to frame the two separate commands differently?
Below is the JS code, CSS and HTML:
Thanks in advance!
/*! random background image 2*/
window.onload = function frontimage() {
var thediv2 = document.getElementById("topimg");
var imgarray2 = new Array("f1.svg", "f2.svg");
var spot2 = Math.floor(Math.random()* imgarray2.length);
thediv2.style.background = "url(img/f-img/"+imgarray2[spot2]+")";
thediv2.style.backgroundSize = "70%";
thediv2.style.backgroundAttachment = "fixed";
thediv2.style.backgroundRepeat = "no-repeat";
thediv2.style.zIndex = "2";
thediv2.style.backgroundColor = "rgba(255,204,255,0.5)";
}
/*! random background image 1*/
window.onload = function backimage() {
var thediv = document.getElementById("imgmain");
var imgarray = new Array("b1.jpg", "b2.jpg", "b3.jpg", "b4.jpg", "b5.jpg");
var spot = Math.floor(Math.random()* imgarray.length);
thediv.style.background = "url(img/b-img/"+imgarray[spot]+")";
thediv.style.backgroundSize = "100%";
thediv.style.backgroundAttachment = "fixed";
thediv.style.backgroundRepeat = "no-repeat";
thediv.style.zIndex = "1";
}
#bigimg {
clear: both;
float: left;
margin-left: 0;
width: 100%;
display: block;
}
#imgmain {
background: 50% 0 no-repeat fixed;
z-index: 1;
width: 100%;
}
#topimg {
z-index: 2;
position: absolute;
background-image: url(../img/f-img/f2.svg);
background-repeat: no-repeat;
background-position: 50% -25%;
background-size:contain;
width: 100%;
margin: auto;
padding: 0;
}
<div id="bigimg">
<section id="imgmain"></section>
<section id="topimg"></section>
</div>
With addEventListener, you can add as many event handlers as you want.
window.addEventListener('load', function frontimage() {
// ...
});
window.addEventListener('load', function backimage() {
// ...
});
You are overriding your first window.onload by reassigning the callback function.
Try this:
window.onload = function() {
frontimage();
backimage();
}

Multiple Videos Using bigvideo.js AND Firefox Compatible

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();

How to Lazy Load div background images

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

Fading Banner Using `background:url()`

I have a banner enclosed in a div tag that contains my banner. I would like to get the banner to fade to the next image but unsure how to achieve the fading effect. I have tried using jQuery fadeIn() but it failed.
The reason why I need to use the background: url() is because I want this banner image to resize pleasantly when the browser gets resized. I am not sure if this is the best way of approaching my problem.
EDIT - My current code does swap the images in the banner, but does not apply the fadeIn() effect. The console does not report any errors.
CSS:
header div#banner {
background: url(../image/banner/00.jpg) no-repeat center;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;
background-size: cover;
height: 300px;
}
JavaScript:
var bannerImages = new Array();
var bannerCounter = 0;
function run() {
loadBannerImages();
runBannerTimer();
}
function loadBannerImages() {
var filePath = "image/banner/";
bannerImages[0] = filePath + "00.jpg";
bannerImages[1] = filePath + "01.jpg";
bannerImages[2] = filePath + "02.jpg";
bannerImages[3] = filePath + "03.jpg";
bannerImages[4] = filePath + "04.jpg";
}
function runBannerTimer() {
var t=setTimeout("swapBannerImage()",2000);
}
function swapBannerImage() {
$('#banner').fadeIn(1000, function() {
$('#banner').css('background', 'url(' + bannerImages[bannerCounter] + ') no-repeat center');
});
bannerCounter++;
if (bannerCounter >= bannerImages.length) {
bannerCounter = 0;
}
runBannerTimer();
}
Your setTimeout isn't correct; try the following instead:
function runBannerTimer() {
var t=setTimeout(function(){
swapBannerImage()
},2000);
}
EDIT
Here is the updated Banner Swap function:
function swapBannerImage() {
$('#banner').fadeOut('slow', function(){
$('#banner').css('background', 'url(' + bannerImages[bannerCounter] + ') no-repeat center').fadeIn('slow');
});
bannerCounter++;
if (bannerCounter >= bannerImages.length) {
bannerCounter = 0;
}
runBannerTimer();
}
Updated Demo Here
You could use multiple divs -- one per image -- and fade them in/out. The divs could still use the css background like you want, you'll just need to absolutely position them, so that they appear one on top of another. However, to get absolutely positioned divs to resize with the parent div (ie to get the "pleasant" resizing effect), you have to set up the css like so:
header div#banner {
... /* your background stuff here */
position: absolute;
left: 0;
right: 0;
height: 300px;
}
Note that you'll assign both left and right, which would make it take up the entire width of the parent. And, make sure that the parent has position:relative.

Categories