jQuery: fade out, change background image, then fade in - javascript

I'm trying to fade the container div around this target div, then change the background, then fade it back in. The problem is that all the functions in this block are called instantaneously, which means the background is swapped out immediately, then the div fades out and in. Not sure how to implement this as a stepped operation.
For now, don't worry about the "myType" part. I have a dropdown menu on the page that you select which changes the background image in the div to a different image based on the selection. I've removed that functionality from this code, since it isn't actually relevant.
HTML:
<div id="itemCustomize">
<div id="itemBaseImg"></div>
</div>
jQuery:
$(myType).change(function() {
$("#itemCustomize").fadeOut(500);
$("#itemBaseImg").css('background-image', 'url(myimage.jpg)';
$("#itemCustomize").fadeIn(500);
}
Update:
The true implementation is actually different. I should have considered that. I have an array of images which I generate an image URL from by parsing the base URL with the variable "url", then add the base image part of the URL by calling on an index. This worked before it was wrapped in a callback function, but now that I want to fade in and out the wrapper div, it doesn't work.
$(myType).change(function() {
$("#itemCustomize").fadeOut(500, function() {
$("#itemBaseImg").css('background-image', url + itemBaseImg[myType.selectedIndex] + ")");
});
$("#itemCustomize").fadeIn(500);
});

You can use the complete callback on jQuery fadeOut function to make them run one after another.
$(select).change(function() {
$("#containerdiv").fadeOut(500, function() {
$("#targetdiv").css('background-image', 'url(myimage.jpg)';
$("#containerdiv").fadeIn(500);
});
}
See: http://api.jquery.com/fadeout/

I figured it out. I needed to create a variable to pass into the index. Thanks for everyone's help!
$(myType).change(function() {
var myIndex = this.selectedIndex;
$("#itemCustomize").fadeOut(50, function() {
$("#itemBaseImg").css('background-image', url + itemBaseImg[myIndex] + ")");
$("#itemCustomize").fadeIn(200);
});
});

Related

div onclick function to change body background image

I want a small picture that acts like a button, to be click-able with a function to change the body background-image. I am a total newbie and I'm trying to learn. The most simple way, I thought, would be to have a div with a background-image.
I have to use unsemantic grid, also.
So I pretty much only have the div with a background image. How do I write this function? I'm sure it's really easy and I've read like 20 threads here but none of them were useful for me
Edit: added my code
#knapp {
height:50px;
width:50px;
background-image:url(http://ingridwu.dmmdmcfatter.com/wp-content/uploads/2015/01/placeholder.png);
background-repeat:no-repeat;
background-size:contain;
position:absolute;
top:90vh;
right:3vw;
}
<div id="knapp" class="grid-10 prefix-90"></div>
Add cursor on the div to appear clickable
#knapp {
cursor: pointer;
}
You could put the new background-image in a new css rule
body.newbg {
background-image:url(path-to-new-background.png);
}
This is body with the old background-image
body {
background-image:url(path-to-old-background.png);
}
and with jquery just add/toggle the class by doing something like that (in $(document).ready()):
$('#knapp').on('click', function(){
$('body').addClass('newbg');
// you could instead do toggleClass if you want for each click to have background switch between old background and new background
});
This is a cleaner approach compared to all the other answers as it separates presentation (css), structure (html) and behavior (javascript).
This is because it doesn't use JavaScript to change style directly. Also it doesn't pollute html with onclick which is also a bad practice.
Here is a plunkr: https://plnkr.co/edit/aiGZmvvi6WWGFs7E9xTp
and here is one with a circular collection of backgrounds (thanks to Kai's idea)
https://plnkr.co/edit/0djmmNM9OOTdfYyvLvUH?p=preview
Create a button with onclick attribute with a function name like replace.
Defined the function in your script like:
function replace() {
document.body.style.backgroundImage = 'url(https://lh6.ggpht.com/8mgTDZXaLMS1JsnF28Tjh6dahHwN1FqcXCVnifkfppmNLqnD-mPBuf9C1sEWhlEbA4s=w300)';
}
Explanation:
You set the style property of the body (using document.body object) to other background-image.
If something is not clear, I will happy to explain.
Working example:
function replace() {
document.body.style.backgroundImage = 'url(https://lh6.ggpht.com/8mgTDZXaLMS1JsnF28Tjh6dahHwN1FqcXCVnifkfppmNLqnD-mPBuf9C1sEWhlEbA4s=w300)';
}
body {
background-image: url(http://www.julienlevesque.net/preview/google-smile-preview.jpg);
}
div {
background:blue;
color:#fff;
float:left;
}
<div onclick="replace()">Replace background-image</div>
This may help you...
$('.yourClassofDiv').click({
$(this).css("background-image",'url("' + URLofIMAGE+ '")')
});
Try using onclick at div#knapp element , set document.body.style.background to url of image file
#knapp {
height:50px;
width:50px;
background-image:url(http://lorempixel.com/50/50);
background-repeat:no-repeat;
background-size:contain;
position:absolute;
top:90vh;
right:3vw;
}
<div id="knapp" class="grid-10 prefix-90" onclick="document.body.style.background = 'url(http://lorempixel.com/'+ window.innerWidth + '/'+ window.innerHeight +') no-repeat'"></div>
here is a simple way in jquery
$(document).ready(function() {
$("body").css('background-image', 'url(http://julienlevesque.net/Requiem/images/detail-requiem.jpg)').css('background-repeat', 'no-repeat');
$('div').css('cursor', 'pointer').click(function() {
$("body").css('background-image', 'url(http://julienlevesque.net/Requiem/images/Requiem-Julien-Levesque.jpg)');
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<body>
<div style="background-color:yellow">Click Here to change background Image</div>
</body>
Here i will explain the code.
The jQuery syntax is tailor made for selecting HTML elements and performing some action on the element(s).
Basic syntax is: $(selector).action()
A $ sign to define/access jQuery
A (selector) to "query (or find)" HTML elements
A jQuery action() to be performed on the element(s)
$(this).hide() - hides the current element.
$("p").hide() - hides all <p> elements.
$(".test").hide() - hides all elements with class="test".
$("#test").hide() - hides the element with id="test".
Here is what happen in the code.
1.
$(document).ready(function(){
// jQuery methods go here...
});
This is to prevent any jQuery code from running before the document is finished loading (is ready).It is good practice to wait for the document to be fully loaded and ready before working with it. This also allows you to have your JavaScript code before the body of your document, in the head section.
2
$("body").css('background-image', 'url(http://julienlevesque.net/Requiem/images/detail-requiem.jpg)').css('background-repeat', 'no-repeat');
getting the body element of your html and set its background-image with .css() action. which i gave it more one action
3
$('div').css('cursor', 'pointer').click(function() {
$("body").css('background-image', 'url(http://julienlevesque.net/Requiem/images/Requiem-Julien-Levesque.jpg)');
});
this is where the change takes place. i got the div to be clicked by $('div') and first gave it an action of changing the mouse to cursor to indicate its clickable and then gave it the click function, where our background-image get changed on click
If I understand the question, you should be able to create a variable in jQuery which is an array of all the string versions of your image urls that you want to use:
var images = ['../images/####','../images/$$$$', 'http://some.other/url.here];
// do this for as many images as you want to cycle through
Like that.
Then you can make a counter variable:
var counter = 0;
and set it to zero.
Next, add the event listener on() to your div like this:
$('#knapp').on('click', function(){
});
Finally, inside your event listener, change the CSS background-image property of the div to one of your images in the array:
// do this inside a document.ready() function
$('#knapp').on('click', function(){
$(this).css('background-image','url("' + images[counter] + '")');
counter++;
});
I hope this helped! Also, remember to increment counter
EDIT ----------------------------------------------------------------
OK, so I totally jumped over something obvious which is the fact that the counter might go too high and access something out of scope. To prevent this add the following inside of your on() listener:
if(counter >= images.length - 1){
counter = 0;
}
EDIT 2 --------------------------------------------------------------
Ok, so I didn't know what exactly you were asking at first, so here is my second answer. Since it seems like what you are actually trying to do is only switch the background image once on click, then you could use something like this:
$(document).ready(function(){
$('#knapp').on('click', function(){
$(this).css('background-image','url("YOUR_NEW_URL_HERE")');
});
});
or you could have it toggle between two images by making two identical classes in CSS (except for the background image) and replacing one with the other using .addClass and .removeClass.
EDIT 3---------------------------------------------------------------
I never thought I would edit this post this many times, but apparently I missed that the body background image should be changed (thanks to comments). My bad and thanks for pointing it out (even if you were talking to someone else).

jquery, time out another jquery function if a user clicks a div?

I have the following script which fades in multiple divs called 'noti_box'. If a user closes these divs then another div 'advert' fades in in its place.
<script>
$(document).ready(function(){
var animations = [];
$('.noti_box').each(function(i) {
animations.push(
$(this).hide().delay(i * 1000).fadeIn(1500).promise()
);
});
$.when.apply($, animations).done(function () {
time=setInterval(function(){
if ( $('.noti_box:visible').length === 0 ) {
$(".advert").fadeIn("slow");
} },200);
});
});
</script>
this works fine, basically what happens here is my last function is stuck on a loop, where the 'advert' div fades in when 'noti_box' is not visible on the page.
However, now I want a user to click a div called 'icons' and if they do, then this should re-fade in the 'noti_box' divs and fade out the 'advert' div using this code:
<script>
$('.icons').click(function(){
$('.advert').fadeOut('fast');
$('.noti_box).fadeIn('fast');
});
</script>
The problem I have here is the 'advert' div fades in and out again in the blink of an eye, without fading in my 'noti_box' div. This is because my first javascript function is still on a loop and preventing my second script from executing.
So what I need to do, I think is set a time out interval for my first script when a user clicks my div 'icon' and then clear the time out interval once the script has executed and the 'noti_box' divs are once again showing.
Can someone please show me how I would be able to do this as I am brand new to jquery. Thanks
function notiBox(ele){
this.ele=ele;
this.ele.hide().fadeIn('slow');
console.log("I have been born! "+ele);
}
notiBox.prototype={
constructor:notiBox,
advert:function(){
var ele=this.ele;
this.ele.fadeOut('fast',function(){ele.next('.advert').fadeIn('slow');});
},
fadeBack:function(){
var ele=this.ele;
this.ele.next('.advert').fadeOut('slow',function(){ele.fadeIn('slow');});
},
}
$(document).ready(function(){
var timeIn=1;
$('.noti-box').each(function(){
var self=this;
this.timer=setInterval(function(){self.notiBox=new notiBox($(self));clearInterval(self.timer);},1000*timeIn);
timeIn++;
});
$('.icon').click(function(){
$('.noti-box').notiBox.fadeBack();
});
});
Right the above is a 'OOP' based approach to your problem. The only problem you might have with this is that your advert divs are not next to the box div. Sorry I guess your DOM elements and layout. Also my methods my not be correct because it's been so long since I've written something like that. I'll do some tests. In the mean time, could you put up some HTML? So that I can adjust my code :d

jQuery UI Slide - Move content during animation

I'm building a website which relies on jQuery effects and I have a problem with the jQuery Slide effect.
I'm using that through a toggle function for the moment, but that will change in a later stage.
The fact is that I'm hinding an element when a certain action is executed. When you use the function slide the content beneath those elements moves when the animation is completed to take up the free space which was created with the effect.
The problem is that the content is only moved as soon as the animation is completed. Is there any way to move the content when the animation is still running. With other words, I want to move the content together with the animation, but I don't want to call the slide function on my element that should move with it.
I've created a JSFiddle to demonstrate the problem: http://jsfiddle.net/6Lg9vL8m/6/
Edit: Question update and fiddle
Here's an update to the question, and please see my original updated fiddle.
When you execute the slide effect in jQuery UI, see the bottom example on my fiddle, the box is moved up, and is somewhere placed behind an invisible screen (tough to explain).
With the animate function, see the top example in my fiddle, the area is shrinked, and that's something which I want to avoid. I want to achieve the effect such as 'Slide' does, but the content under the box must move up immediately with the animation, and not after the animation has been completed.
Edit: Reworked the correct answer in a plugin.
Thanks to the answers I've received here, I found the correct code, modified a bit, and created a plugin from it which I'll place here.
The plugin is called 'Curtain' and can be described as rising the requested element as a curtain and thus move it out of the way.
Here's the source code:
(function($) {
$.fn.curtain = function(options, callback) {
var settings = $.extend( {}, $.fn.curtain.defaults, options);
var tabContentsHeight = $(this).height();
$(this).animate({height:0}, settings.duration);
$(this).children().animate({'margin-top':'-' + tabContentsHeight + 'px'}, settings.duration, function() {
$(this).css({"margin-top":0});
if ($.isFunction(callback)) {
callback(this);
}
});
return this; // Allows chaining.
};
$.fn.curtain.defaults = {
duration: 250
};
}(jQuery));
The plugin can be called like this:
element.curtain({ duration: 250 }, function() {
// Callback function goes here.
});
If someone has remarks or a better way to solve this problem, please share it in the comments.
You can do it by using the animate function like this:
$('#square').on('mousedown', function(e) {
$(this).animate({height:-200},2500);
});
Demo
Updated code to create a "curtain raising" like animation:-
$('#square').on('mousedown', function(e) {
$(this).animate({height:-200},2500);
$(this).children().animate({"margin-top":"-400px"},2500, function() {
$(this).css({"margin-top":0})
});
});
CSS:
`#square{
overflow:hidden;
}`
Demo 2
This is the effect you wanted?
$('#square').on('click', function(e) {
$(this).animate({height :0},2500 );
});

mCustomScrollbar scrollbar display on hidden div

I've seen answers on here on how to do this, but I just can't get it to work. Maybe another set of eyes will help. I'm trying to get the scrollbar to appear in a div that popups when an image is clicked. Here's the code for that:
('modalcs' is the name of the div that pops up)
And the function:
function update_scroll(theID)
{
document.getElementById(theID).style.display = 'block';
$(".scrollable").mCustomScrollbar("update");
}
In my $(document).ready(function() I have:
$(".scrollable").mCustomScrollbar({
theme:"dark-thick",
scrollButtons:{
enable:true,
advanced:{
updateOnBrowserResize:true,
updateOnContentResize:true
}
}
});
and I understand that on page load since the hidden div isn't seen, the scrollbar is unable to see its content.
TIA for any help!
The problem is that the "update" command does not operate on a collection, so if $(".scrollable") returns more than one element, it will update only the first one. Use $.each
$(".scrollable").each(function(){
$(this).mCustomScrollbar("update");
});
On the other hand, since you are operating on 1 element, you can just change your function:
function update_scroll(theID)
{
$('#' + theID).show().mCustomScrollbar("update");
}

How to show a spinner while loading an image via JavaScript

I'm currently working on a web application which has a page which displays a single chart (a .png image). On another part of this page there are a set of links which, when clicked, the entire page reloads and looks exactly the same as before except for the chart in the middle of the page.
What I want to do is when a link is clicked on a page just the chart on the page is changed. This will speed things up tremendously as the page is roughly 100kb large, and don't really want to reload the entire page just to display this.
I've been doing this via JavaScript, which works so far, using the following code
document.getElementById('chart').src = '/charts/10.png';
The problem is that when the user clicks on the link, it may take a couple of seconds before the chart changes. This makes the user think that their click hasn't done anything, or that the system is slow to respond.
What I want to happen is display a spinner / throbber / status indicator, in place of where the image is while it is loading, so when the user clicks the link they know at least the system has taken their input and is doing something about it.
I've tried a few suggestions, even using a psudo time out to show a spinner, and then flick back to the image.
A good suggestion I've had is to use the following
<img src="/charts/10.png" lowsrc="/spinner.gif"/>
Which would be ideal, except the spinner is significantly smaller than the chart which is being displayed.
Any other ideas?
I've used something like this to preload an image and then automatically call back to my javascript when the image is finished loading. You want to check complete before you setup the callback because the image may already be cached and it may not call your callback.
function PreloadImage(imgSrc, callback){
var objImagePreloader = new Image();
objImagePreloader.src = imgSrc;
if(objImagePreloader.complete){
callback();
objImagePreloader.onload=function(){};
}
else{
objImagePreloader.onload = function() {
callback();
// clear onLoad, IE behaves irratically with animated gifs otherwise
objImagePreloader.onload=function(){};
}
}
}
You could show a static image that gives the optical illusion of a spinny-wheel, like these.
Using the load() method of jQuery, it is easily possible to do something as soon as an image is loaded:
$('img.example').load(function() {
$('#spinner').fadeOut();
});
See: http://api.jquery.com/load-event/
Use the power of the setTimeout() function (More info) - this allows you set a timer to trigger a function call in the future, and calling it won't block execution of the current / other functions (async.).
Position a div containing the spinner above the chart image, with it's css display attribute set to none:
<div> <img src="spinner.gif" id="spinnerImg" style="display: none;" /></div>
The nbsp stop the div collapsing when the spinner is hidden. Without it, when you toggle display of the spinner, your layout will "twitch"
function chartOnClick() {
//How long to show the spinner for in ms (eg 3 seconds)
var spinnerShowTime = 3000
//Show the spinner
document.getElementById('spinnerImg').style.display = "";
//Change the chart src
document.getElementById('chart').src = '/charts/10.png';
//Set the timeout on the spinner
setTimeout("hideSpinner()", spinnerShowTime);
}
function hideSpinner() {
document.getElementById('spinnerImg').style.display = "none";
}
Use CSS to set the loading animation as a centered background-image for the image's container.
Then when loading the new large image, first set the src to a preloaded transparent 1 pixel gif.
e.g.
document.getElementById('mainimg').src = '/images/1pix.gif';
document.getElementById('mainimg').src = '/images/large_image.jpg';
While the large_image.jpg is loading, the background will show through the 1pix transparent gif.
Building on Ed's answer, I would prefer to see something like:
function PreLoadImage( srcURL, callback, errorCallback ) {
var thePic = new Image();
thePic.onload = function() {
callback();
thePic.onload = function(){};
}
thePic.onerror = function() {
errorCallback();
}
thePic.src = srcURL;
}
Your callback can display the image in its proper place and dispose/hide of a spinner, and the errorCallback prevents your page from "beachballing". All event driven, no timers or polling, plus you don't have to add the additional if statements to check if the image completed loading while you where setting up your events - since they're set up beforehand they'll trigger regardless of how quickly the images loads.
Some time ago I have written a jQuery plugin which handles displaying a spinner automatically http://denysonique.github.com/imgPreload/
Looking in to its source code should help you with detecting when to display the spinner and with displaying it in the centre of the loaded image.
I like #duddle's jquery method but find that load() isn't always called (such as when the image is retrieved from cache in IE). I use this version instead:
$('img.example').one('load', function() {
$('#spinner').remove();
}).each(function() {
if(this.complete) {
$(this).trigger('load');
}
});
This calls load at most one time and immediately if it's already completed loading.
put the spinner in a div the same size as the chart, you know the height and width so you can use relative positioning to center it correctly.
Aside from the lowsrc option, I've also used a background-image on the img's container.
Be aware that the callback function is also called if the image src doesn't exist (http 404 error). To avoid this you can check the width of the image, like:
if(this.width == 0) return false;
#iAn's solution looks good to me. The only thing I'd change is instead of using setTimeout, I'd try and hook into the images 'Load' event. This way, if the image takes longer than 3 seconds to download, you'll still get the spinner.
On the other hand, if it takes less time to download, you'll get the spinner for less than 3 seconds.
I would add some random digits to avoid the browser cache.

Categories