I want to change the background image of my app on button click. I put the images in an array and selecting the background image randomly. Below is the code.
const background = [
"image/2.png",
"image/4.png",
"image/9.png",
"image/14.png",
"image/12.png",
"image/17.png",
];
function changeColor() {
const getimage = `${
background[Math.floor(Math.random() * background.length)]
}`;
document.querySelector("body").style.backgroundImage = 'url("getimage")';
console.log(getimage);
}
The Console log shows that 'on button click' the getimage variable is changing randomly. But in the browser, the background is not changing! Not getting what am I missing?
When you set the style you are setting the url to getimage as a string instead of the element. To fix your problem, you just need to put it as the element, either as
document.querySelector("body").style.backgroundImage = `url("${getimage}")`;
// uses `` to include a variable using ${}
or:
document.querySelector("body").style.backgroundImage = 'url("' + getimage + '")'; // adds the variable in the middle of the string
Try interpolate getimage
document.querySelector("body").style.background = `url(${getimage})`;
Related
I am new to Javascript and am wanting to create a slider that changes its background image according to a src of another element in pure JS.
Here is a snippet of code:
x = 1;
function image2() {
var x = document.getElementById("imagecounter").textContent;
var image2 = document.getElementById("image2").src;
var slider = document.getElementById("slider");
if (x == 2){
slider.style.imageBackground = "url('image2');"}
}
The purpose of the code is to establish a number that controls the slides and when the number changes, the image with a src element is exchanged with the backgroun-image of the div #slider.
full code: https://codepen.io/lucaslg20/pen/BeNGzv/
It looks like you messed up the assignment of the backgroundImage style:
It should be:
if (x == 2){
slider.style.backgroundImage = "url('" + image2 + "')";
}
You need to concatenate the value of image2 properly.
In addition, I checked out your codepen HTML. You are looking for:
document.getElementsByClassName("slider")[0]
not
document.getElementById("slider")
for the variable "slider".
Two main issues here:
1 - Your slider element has a class of slider instead of an ID, so getElementbyId("slider") cannot find it and returns null.
2 - This line:
slider.style.imageBackground = "url('image2');"
There is no property called imageBackground, it is backgroundImage, or simply background (both work).
"url('image2')" will return the string "image2", not the variable's value. You can replace this by:
.
"url('" + image2 + "')"
Or by
`url('${image2}')`.
I am using Materialize CSS and have the "Material Box" which is a lightbox plugin. I want all of the thumbnails to be the same size. When clicked I want the full photo to load.
I am using onclick to change the src. How do I change it back to the thumbnail when the large photo closes (either with a click or the escape key)?
<div class="col s6 m3">
<img class="materialboxed responsive-img" src="images/thumb1.jpg" onclick='this.src="images/photo1"'>
</div>
Material Box Javascript
document.addEventListener('DOMContentLoaded', function() {
var elems = document.querySelectorAll('.materialboxed');
var options = {}
var instances = M.Materialbox.init(elems, options);
});
// Or with jQuery
$(document).ready(function(){
$('.materialboxed').materialbox();
});
Materializecss.com - https://materializecss.com/media.html
I haven't found an easy other way of achieving the lightbox effect with cropped square thumbnails. Any advice would be greatly appreciated!
Here is one implementation of what you want, keeping track of the image click state.
$(document).ready(function(){
$('.materialboxed').materialbox();
// Image sources
const srcThumb = '/images/thumb1.jpg'
const srcPhoto = '/images/photo1.jpg'
// Click state
var clicked = false
// Get image element and bind click event
const img = $('.materialboxed')
img.on('click', function() {
img.attr('src', clicked ? srcPhoto : srcThumb)
clicked = !clicked
})
});
No need to rely on onclick in this case.
Materialize is already binding onclick for those images.
And it provides the following native methods we can use for doing exactly what you want using pure JS (no jQuery):
onOpenStart Function null Callback function called before materialbox is opened.
onCloseEnd Function null Callback function called after materialbox is closed.
In this example below, we assume there is a normal materialboxed photo gallery containing thumbnails named thumb_whatever.jpg, for example. But we're also serving the original sized photo named whatever.jpg in the same directory.
Then we're changing src attribute dynamically removing the thumb_ prefix to get the original image, which in this case will be imediately lightboxed by materialize.
And after closing the lightbox, the src attribute is being set back again without the thumb_ prefix.
We do that while initializing Materialbox:
// Initializing Materialbox
const mb = document.querySelectorAll('.materialboxed')
M.Materialbox.init(mb, {
onOpenStart: (el) => {
var src = el.getAttribute('src') // get the src
var path = src.substring(0,src.lastIndexOf('/')) // get the path from the src
var fileName = src.substring(src.lastIndexOf('/')).replace('thumb_','') // get the filename and removes 'thumb_' prefix
var newSrc = path+fileName // re-assemble without the 'thumb_' prefix
el.setAttribute('src', newSrc)
},
onCloseEnd: (el) => {
var src = el.getAttribute('src') // get the src
var path = src.substring(0,src.lastIndexOf('/')) // get the path from the src
var fileName = src.substring(src.lastIndexOf('/')).replace('/', '/thumb_') // get the filename and adds 'thumb_' prefix
var newSrc = path+fileName // re-assemble with the 'thumb_' prefix
el.setAttribute('src', newSrc)
}
})
This solution is also working like a charm for me, crossplatform.
I created a random quote generator and I'm trying to set up the background image in a way that when a person click on "New Quote" button, the background image changes. I have created a function and added images array in it and animated the effect and tried to call it but it's not working...
Here's my code below. You can also see my full code at http://codepen.io/kikibres/pen/RKeNQg
function getImage() {
var backImages = ['https://s6.postimg.org/pk900j3a9/quoteimg1.jpg', 'https://s6.postimg.org/pyac04ndt/quoteimg2.jpg', 'https://s6.postimg.org/kbdz2nkv5/quoteimg3.jpg', 'https://s6.postimg.org/suxd0et7l/quoteimg4.jpg', 'https://s6.postimg.org/z9wdx2zxd/quoteimg5.jpg', 'https://s6.postimg.org/56hv54wo1/quoteimg6.jpg', 'https://s6.postimg.org/s98e4ay5d/quoteimg7.jpg', 'https://s6.postimg.org/8fwablkrl/quoteimg8.jpg', 'https://s6.postimg.org/rm9hes19d/quoteimg9.jpg', 'https://s6.postimg.org/85td5zvj5/quoteimg10.jpg'];
var randomImg = Math.floor(Math.random() * backImages.length);
var quoteImg = backImages[randomImg];
$(".wrapper").animate({opacity: 0}, speed, function() {
$(".wrapper").animate({opacity: 1}, speed);
$(".wrapper").css(
'background-image', 'url(' + quoteImg + ')');
});
};
$("#new-quote").text(getQuote);
$("#new-quote").on("click", getQuote);
$("#new-quote").on("click", getImage);
How do I get the background image to work every time I click "New Quote" button?
All you need is to define variable speed somewhere at start of script:
$(document).ready(function() {
var speed = 1000;
...
You just have to change the jQuery method, and the whole code at your link http://codepen.io/kikibres/pen/RKeNQg is fine
$("#new-quote").onload(getImage); //Wrong
$("#new-quote").on("load",getImage); //Use this
I have a code that works perfectly when the number of thumbnails to rotate is 16 and the location is the same for all (only changes the name of the file due to the thumbnail number). Example: http: //www.urltoimage1.jpg....http: //www.urltoimage16.jpg
This is the html:
<img width="189" height="142" src="http: //www.urltoimage8.jpg" class="someclass" id="latest-499" onmouseover="thumbStart('latest-499', 16, 'http: //www.urltoimage');" onmouseout="thumbStop('latest-499','http: //www.urltoimage8.jpg');">
Here is the javascript:
// JavaScript Document
//rotating thumb functions
var rotateThumbs = new Array();
function changeThumb( index, i, num_thumbs, path)
{
if (rotateThumbs[index])
{
if(i<=num_thumbs){
document.getElementById(index).src = path + i + ".jpg";
i++;
setTimeout("changeThumb('"+ index +"'," + i + ", " + num_thumbs + ", '" + path + "')", 600);
}else{
changeThumb( index, 1, num_thumbs, path);
}
}
}
function thumbStart(index, num_thumbs, path)
{
rotateThumbs[index] = true;
changeThumb( index, 1, num_thumbs, path);
}
function thumbStop(index, srco)
{
rotateThumbs[index] = false;
document.getElementById(index).src = srco;
}
Now, the problem is for some articles the thumbnails are not in the same location. Example: http: //www.urltoimage1.jpg....http: //www.urltoimageksks16.jpg
I think that, in the existence of this discrepancy, it is better to copy all the urls of the thumbnails to the class of the image, leaving the html in this way:
<img width="189" height="142" src="http: //www.urltoimage8.jpg" class="http: //www.urltoimage1.jpg,http: //www.urltoimage2.jpg,...,http: //www.urltoimageksks16.jpg" id="latest-499" onmouseover="thumbStart" onmouseout="thumbStop('latest-499','http: //www.urltoimage8.jpg');">
Now that I have all the urls in the class of the img tag, how can achieve that the thumbnail rotate?
Thanks
don't store the urls in the class attributes, use Data Attributes instead. (or Data Attributes from jQuery)
something like
<img .. data-thumbnail-url="http: //www.urltoimageksks16.jpg" .. />
if you're using jQuery (you've added it to your tags), you could use directly
var thumbnailSrc = jQuery('img').data('thumbnail');
if you're not using it (since I don't see any jQuery at all in your code) you have to use this instead
var thumbnailSrc = document.getElementById(index).dataset.thumbnail
using that, you could replace your src attribute. you'll probably want to store in data attributes the original src.
About rotating itself (It is not clear if it is part of your question or if you want to know if it is ok to store the urls in class attributes), there are answers for that using jquery, like jQuery animate image rotation You only need to adapt the functionality to be executed on hovering. You could use pure css as well Spin or rotate an image on hover
On a side note, use this
var rotateThumbs = [];
rather than
var rotateThumbs = new Array();
See In JavaScript, why is [ ] preferred over new Array();?
This is my first post here, I always found solutions on this page, so thank you for that.
I have a problem with .removeClass and .addClass in my last program.
I load multiple pictures into array Frames and I want change all (previous-image) to (current-image) in frames[0]. Here is my code, it is change class only on second image. Here is code:
function loadImage() {
// Creates a new <li>
var li = document.createElement("li");
// Generates the image file name using the incremented "loadedImages" variable
var imageName = "graphics/img/Dodge_Viper_SRT10_2010_360_720_50-" + (loadedImages + 1) + ".jpg";
var imageName1 = "graphics/img/Dodge_Viper_SRT10_2010_360_720_50-" + (loadedImages + 1) + ".jpg";
/*
Creates a new <img> and sets its src attribute to point to the file name we generated.
It also hides the image by applying the "previous-image" CSS class to it.
The image then is added to the <li>.
*/
var image = $('<img>').attr('src', imageName).addClass("previous-image").appendTo(li) && $('<img>').attr('src', imageName1).addClass("previous-image light-image").appendTo(li);
// We add the newly added image object (returned by jQuery) to the "frames" array.
frames.push(image);
// We add the <li> to the <ol>
$images.append(li);
/*
Adds the "load" event handler to the new image.
When the event triggers it calls the "imageLoaded" function.
*/
$(image).load(function() {
imageLoaded();
});
};
function imageLoaded() {
// Increments the value of the "loadedImages" variable
loadedImages++;
// Updates the preloader percentage text
$("#spinner span").text(Math.floor(loadedImages / totalFrames * 100) + "%");
// Checks if the currently loaded image is the last one in the sequence...
if (loadedImages == totalFrames) {
// ...if so, it makes the first image in the sequence to be visible by removing the "previous-image" class and applying the "current-image" on it
frames[0].removeClass("previous-image").addClass("current-image");
/*
Displays the image slider by using the jQuery "fadeOut" animation and its complete event handler.
When the preloader is completely faded, it stops the preloader rendering and calls the "showThreesixty" function to display the images.
*/
$("#spinner").fadeOut("slow", function() {
spinner.hide();
showThreesixty();
});
} else {
// ...if not, Loads the next image in the sequence
loadImage();
}
};
This is, how it looks in browser:
<ol><li><img src="graphics/img/Dodge_Viper_SRT10_2010_360_720_50-1.jpg" class="previous-image"><img src="graphics/img/Dodge_Viper_SRT10_2010_360_720_50-1.jpg" class="light-image current-image"></li></ol>
This is, what I want:
<ol><li><img src="graphics/img/Dodge_Viper_SRT10_2010_360_720_50-1.jpg" class="current-image"><img src="graphics/img/Dodge_Viper_SRT10_2010_360_720_50-1.jpg" class="light-image current-image"></li></ol>
When I change this
var image = $('<img>').attr('src', imageName).addClass("previous-image").appendTo(li) && $('<img>').attr('src', imageName1).addClass("previous-image light-image").appendTo(li);
to this
var image = $('<img>').attr('src', imageName1).addClass("previous-image light-image").appendTo(li) && $('<img>').attr('src', imageName).addClass("previous-image").appendTo(li);
it still change only second img. Any help?
var image = $('<img>').attr('src', imageName).addClass("previous-image").appendTo(li) && $('<img>').attr('src', imageName1).addClass("previous-image light-image").appendTo(li);
is not doing what you think it is. It's only using the second element you declare. They both get appended to the page (because the appendTo method runs), but && is a logical operator, it's not used for concatenation, so the variable "image" only contains the second image you declared.
This will work instead:
var image = $('<img>', { "src": imageName, "class": "previous-image" });
image = image.add($('<img>', { "src": imageName1, "class": "previous-image light-image" }));
image.appendTo(li);
If you are just trying to replace all the previous-image classes with current image then you can do this:
$('img.previous-image').each(function(){
$(this).addClass("current-image").removeClass("previous-image");
});