Why is clientWidth equal to 0? - javascript

I'm a beginner, writing a website and trying to add an image carousel into my homepage. I have 6 images displayed on screen next to each other. What I'm trying to do is move my images 1 to the left when the website is loaded so that slide1 is the first one to be displayed. Here is part of my index.html:
<div class="cover-art-carousel">
<div class="slide">
<img src="./covers/slide6.jpg" id="lastClone">
<img src="./covers/slide1.png">
<img src="./covers/slide2.png">
<img src="./covers/slide3.jpg">
<img src="./covers/slide4.jpg">
<img src="./covers/slide5.jpg">
<img src="./covers/slide6.jpg">
<img src="./covers/slide1.png" id="firstClone">
</div>
</div>
<button id="prevBtn">Prev</button>
<button id="nextBtn">Next</button>
<script src="app.js"></script>`
And this is my js:
const carouselSlide = document.querySelector('.slide');
const carouselImages = document.querySelectorAll('.slide img');
//Buttons
const prevButton = document.querySelector('#prevBtn');
const nextButton = document.querySelector('#nextBtn');
//Counter
let counter = 1;
const size = carouselImages[0].clientWidth;
carouselSlide.style.transform = 'translateX(' + (-size * counter) + 'px)';
When I load the site, clientWidth is equal to 0 even though I know it should be 300. The weirdest thing is that if I add an alert into my JS, it works fine. I'm sure I'm missing something super obvious but if anyone could help that would be great. Hope this makes sense. Thanks!

wrap your js script like this:
window.onload = function(){ the rest of your js.....
}
it would seem that you may be trying to get the width before the images are loaded in.

Related

Preset amount of degree an image rotates per scroll

Is it possbile to set a preset amount an image rotates per scroll?
I created a rotate function with js, which rotates an image (gears in my case) by scrolling up and down the website. In my opinion it needs to rotate more degrees per scroll and Im trying to increase the degrees the image is rotating
JS
function rotate(e) {
e.preventDefault();
rot += e.deltaY * 0.5;
leftGear.style.transform = `rotate(${rot}deg)`;
rightGear.style.transform = `rotate(${rot}deg)`;
}
let rot = 0;
const leftGear = document.querySelector(".leftGear");
document.body.onwheel = leftGear.onwheel = rotate;
const rightGear = document.querySelector(".rightGear");
document.body.onwheel = rightGear.onwheel = rotate;
html
<div class="gearBox">
<!--<img src="img/proxcopAIO.png" height="60">-->
<img src="img/gearProxBlue.png" id="gearText" height="100">
<div class="rightGear" id="rightgear">
<img src="img/gear.png" height="50">
</div>
<div class="leftGear" id="leftgear">
<img src="img/gear.png" height="50">
</div>
</div>
I tried changing '0.5' as factor but somehow it doesnt change anything, or maybe its a false thought of mine
it's because your rotate the whole div which width is 100% of your browser.
Add a width to your div, it will solve your problem
.rightGear{
width:100px;
}

Basic Image Viewer with javaScript

I am new with JavaScript and I am trying to learn by coding. I want to make a basic image viewer with a "next" and a "previous" that you can click to move forwards and back through a gallery of ten pictures. So I have my html, my css and my javaScript files and 10 random pictures to try it out.
The files are pretty straight forward:
HTML:
<body>
<div id="wrap">
<div class="firstColumn">
<p>PHOTOGRAPHY</p>
<div class="firstColumnSub">
<p class="photo">SOME TITLE</p>
</div>
</div>
<div class="back">
<p>BACK</p>
</div>
<div id="container">
<div id="controllers">
<div class="buttons" id="previous">
<p onclick="change(-1);">PREVIOUS</p>
</div>
<div class="buttons" id="next">
<p onclick="change(1);">NEXT</p>
</div>
</div>
<div><img height="100%" id="front" src="Image1.jpg"></div>
<div>
<p id="footer">Footer</p>
</div>
</div>
</div>
</body>
Just a few divs with the image in the center and a previous and a next clickable tags. This is what it loos like:
The JavaScript file contains a function that loads the different pitures and -and this is my problem- centers them in the middle of the page by grabbing their width and updating the css:
JavaScript:
window.onload = function setUp() {
var b = document.getElementById("front").width;
document.getElementById("container").style.width = b + "px"
}
var imageCount = 1;
function change(x) {
imageCount = imageCount + x;
var image = document.getElementById('front');
var str1 = "Image";
var str2 = imageCount;
var str3 = ".jpg"
var sum = str1.concat(str2, str3);
image.src = sum;
var a = document.getElementById("front").width;
document.getElementById("container").style.width = a + "px"
}
I an not posting the css unless required, but you get the idea.
As you press "next" or "previous", you are supposed to get this result:
etc... but instead I get all sort of random displays:
And here is the thing that is puzzling me: if you keep clicking "back" and "next", the same pictures appear OK the second time round, so it is working but not immediately. Any help appreciated!
Thanks, P.
This is most likely a CSS positioning issue. The following CSS may do the job for you. If you need further help, then I suggest that you reconsider posting your CSS to get help.
#container #front
{
position: relative;
/* width: 0px; */ /* set via JS for each element in this use case */
left: 0;
right: 0;
margin: 0 auto;
}
Here is a popular Q & A on this subject which contains a lot of resources.

Reload a DIV on click of another DIV

I have a div called masterdiv, inside this div there are 3 other div div1, div2, and div3,
This is the html for these html:
<div id="masterdiv" class="masterdivclass">
<div id="div1"><img class="div1class" src="image1.jpg" id="div1id" /></div>
<div id="div2"><img class="div2class" src="image2.jpg" id="div2id" /></div>
<div id="div3"><img class="div3class" src="image3.jpg" id="div3id" /></div>
</div>
I also have another div:
<div id=”reload”><img src="reload.png" width="200" height="70" onclick=loadDIV();></div>
What I’m trying to do is to reload the masterdiv div whenever the reload div is clicked on. Hiding and then showing the div isn’t enough as I need the content to be reloaded when the refresh div is clicked on. I don’t want to reload the entire page, just the masterdiv which contains the 3 other div. But I’m not certain this is possible.
I’m trying to do it with this Javascript function:
<script type="text/javascript">
function loadDiv(){
$("<div id="masterdiv" class="masterdivclass">
<div id="div1"><img class="div1class" src="image1.jpg" id="div1id" /></div>
<div id="div2"><img class="div2class" src="image2.jpg" id="div2id" /></div>
<div id="div3"><img class="div3class" src="image3.jpg" id="div3id" /></div>
</div>").appendTo("body");
}
</script>
This isn’t working, I think maybe I'm going about this in the wrong way? Maybe I’m missing something very simple here? I’d really appreciate any help with this, thank you in advance!
UPDATE
After reconsidering my project's requirements, I need to change part of my question, I now need to randomise the images displayed in the divs, and have a new random image load every time the reload div is clicked on. I also need to remove each class that’s currently in each of the three divs and then reattach the same classes to the divs (if I don’t remove and reattach the classes then the divs just display the plain images without any class/effect applied to them, it seems like I need to reload the class every time I load an image into a div in order for the class/effect to be applied successfully).
I have 5 images, and I’m using each div’s id tag to attach a random image to each div.
First I’m assigning the 5 different images to 5 different ids:
<script>
document.getElementById('sample1').src="images/00001.jpg";
document.getElementById('sample2').src="images/00002.jpg";
document.getElementById('sample3').src="images/00003.jpg";
document.getElementById('sample4').src="images/00004.jpg";
document.getElementById('sample5').src="images/00005.jpg";
</script>
And then I’m trying to use the following Javascript to load a randomised id (and its assigned image) to each of the 3 divs when the reload div is clicked:
<script>
$(function() {
$('#reload').on('click',function(){
$("#masterdiv").find("div[id^='div']").each(function(index){
//First, remove and reattach classes “div1class”, “div2class” and “div3class”
//from “easyDIV”, “mediumDIV” and “hardDIV” respectively:
$(“#easyDIV”).removeClass('div1class');
$(“#easyDIV”).addClass('div1class');
$(“#mediumDIV”).removeClass('div2class');
$(“#mediumDIV”).addClass('div2class');
$(“#hardDIV”).removeClass('div3class');
$(“#hardDIV”).addClass('div3class');
//Get a random number between 1 and 5, then attach it to “sample”,
//so that the result will be either “sample1”, “sample2”, “sample3”, “sample4” or “sample5”,
//call this variable “variablesample”:
var num = Math.floor(Math.random() * 5 + 1);
variablesample = "sample" +num;
//Attach this randomised id to all three divs using “variablesample”:
jQuery(this).prev("easyDIV").attr("id",variablesample);
jQuery(this).prev("mediumDIV").attr("id",variablesample);
jQuery(this).prev("hardDIV").attr("id",variablesample);
});
var p = $("#masterdiv").parent();
var el = $("#masterdiv").detach();
p.append(el);
});
});
</script>
I’m trying to make it so that all 3 divs will show the same randomised picture (that’s why they’re all sharing the variable “variablesample”), and each div will reload its own class/effect (div1class, div2class and div3class) but it’s not working. I’m not sure if it’s correct to use jQuery inside a Javascript function, or if my syntax for updating the ids of the divs is incorrect.
Perhaps my logic to solving this problem is all wrong? I’d really appreciate any more help with this problem. Thanks again in advance!
Original question was edited many times, so here is the correct answer for the latest edit. Answer to the question; "How to use random image, but same image on all 3, and 3 class on/off switching":
$(function() {
var imageArray = [
'https://via.placeholder.com/40x40',
'https://via.placeholder.com/80x40',
'https://via.placeholder.com/120x40',
'https://via.placeholder.com/160x40',
'https://via.placeholder.com/200x40'];
reloadImages(imageArray);
$('#reload').on('click',function(){
$( "#masterdiv img[id^='div']" ).each(function(index){
$(this).removeClass("div"+(index+1)+"class");
$(this).fadeOut( "slow", function() {
if(index==0) {
reloadImages(imageArray);
}
$(this).addClass("div"+(index+1)+"class");
$(this).fadeIn();
});
});
});
});
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
function reloadImages(array){
shuffleArray(array);
for(var i=0;i<3;i++){
// places the first image into all divs, change 0 to i if you want different images in each div
document.getElementById('div'+(i+1)+'id').src=array[0];
}
}
.div1class {
border:2px dashed #0F0;
}
.div2class {
border:2px dashed yellow;
}
.div3class {
border:2px dashed red;
}
#reload {
background-color:blue;
color:white;
width:100px;
height:30px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id='reload'>Click here</div>
<div id="masterdiv" class="masterdivclass">
<div id="div1">
<img src="https://via.placeholder.com/20x40" class="div1class" id="div1id" />
</div>
<div id="div2">
<img src="https://via.placeholder.com/20x40" class="div2class" id="div2id" />
</div>
<div id="div3">
<img src="https://via.placeholder.com/20x40" class="div3class" id="div3id" />
</div>
</div>
Line breaks and un-escaped quotes are why the functions is not working.
function loadDiv(){
$('#masterdiv').remove();
$("<div id='masterdiv' class='masterdivclass'><div id='div1'><img class='div1class' src='image1.jpg' id='div1id' /></div><div id='div2'><img class='div2class' src='image2.jpg' id='div2id' /></div><div id='div3'><img class='div3class' src='image3.jpg' id='div3id' /></div></div>").appendTo("body");
}
try:
function loadDiv(){
$("#masterdiv").load(location.href + " #masterdiv");
}
Here's the code pen demo:
http://codepen.io/anon/pen/xwgRWm
If content of container is not being changed dynamically then there is no point reloading it. appendTo wiil append DOM in existing DOM structure, you will need html() here which will replace the content inside container. Also note you had typo here onclick=loadDiv();
HTML:
<div id="masterdiv" class="masterdivclass">
<div id="div1"><img class="div1class" src="image1.jpg" id="div1id"/></div>
<div id="div2"><img class="div2class" src="image2.jpg" id="div2id"/></div>
<div id="div3"><img class="div3class" src="image3.jpg" id="div3id"/></div>
</div>
<div id="reload"><img src="reload.png" width="200" height="70" onclick=loadDiv();></div>
JS:
function loadDiv() {
$("#masterdiv").html('<div id="div1"><img class="div1class" src="image1.jpg" id="div1id" /></div>\
<div id="div2"><img class="div2class" src="image2.jpg" id="div2id" /></div>\
<div id="div3"><img class="div3class" src="image3.jpg" id="div3id" /></div>');
}

Slider - How would you make a simple slider?

EDIT: I WANT MY SLIDER TO BE EASY TO YOU AND ONCE A LINK IS CLICKED THE IMAGE THAT CORRELATES WITH LINK SHOWS.
I'm looking to make a really simple "slider" that if you click a link, the img shows that correlates with it. I've been trying to find something for a bit now and things are either too flash or don't suit my needs. This came close: http://jsfiddle.net/bretmorris/ULNa2/7/
I would something a little simpler that can be applied easily to multiple images for different divs.
This is what my code looks like with just a plain img tag to it:
<div id="adobe_content" class="hdiv"><button class="x">X</button>
<img src="images/adobefront.png"><br>
<img src="images/adobeinside.png"><br>
<img src="images/adobeback.png"><br>
<h5>Adobe Brochure</h5>
<p>
I wanted to make something functional and out the box that Adobe might consider giving out. It's clean like their work and sparks interest in opening the brochure with the cut out in the center. The front flap is able to slide into a slot on the right side for a neat logo. They're now more interested in their cloud, but the information is inside is still relevant!
</p>
<b>Programs used: Adobe Illustrator, InDesign and Photoshop.</b>
</div>
The code doesn't work for me because, well I partially don't understand it, and I'm not sure how to make it suit my needs (especially if I got up to multiple images) like correlating with an image.
Perhaps understanding what is going on would maybe get you on the right track, so here is an explanation:
$('a.prev').click(function() {
prevSlide($(this).parents('.slideshow').find('.slides'));
});
//clicking image goes to next slide
$('a.next, .slideshow img').click(function() {
nextSlide($(this).parents('.slideshow').find('.slides'));
});
This part is relatively straightforward, when you click on the previous or next links, call the prevSlide or nextSlide function, passing the collection of slides as an argument.
//initialize show
iniShow();
function iniShow() {
//show first image
$('.slideshow').each(function() {
$(this).find('img:first').fadeIn(500);
})
}
Initialize the slideshow by finding each slideshow on the page and fading in the first image. $(this) refers to the <div class="slideshow"> parent, find all child image tags and take the first, fade that element in (and do it in 500 milliseconds).
function prevSlide($slides) {
$slides.find('img:last').prependTo($slides);
showSlide($slides);
}
function nextSlide($slides) {
$slides.find('img:first').appendTo($slides);
showSlide($slides);
}
The prevSlide and nextSlide functions both rearrange the order of images, this line in particular:
$slides.find('img:first').appendTo($slides);
Is moving the first image to the end of the images, so:
<img src="http://placekitten.com/300/500" width="300" height="500" />
<img src="http://placekitten.com/200/400" width="200" height="400" />
<img src="http://placekitten.com/400/400" width="500" height="400" />
becomes:
<img src="http://placekitten.com/200/400" width="200" height="400" />
<img src="http://placekitten.com/400/400" width="500" height="400" />
<img src="http://placekitten.com/300/500" width="300" height="500" />
$slides.find('img:last').prependTo($slides); does the inverse and moves the last image to the beginning.
function showSlide($slides) {
//hide (reset) all slides
$slides.find('img').hide();
//fade in next slide
$slides.find('img:first').fadeIn(500);
}
Finally, showSlide accepts the collection of images, hides all of them and then fades in the first image (since the collection is reordered each time, the first is a different image).
Now, if you want a link for each image that will display a corresponding image, you could do something as simple as:
<a class="image" data-src="http://placekitten.com/300/500">Kitten 1</a>
<a class="image" data-src="http://placekitten.com/200/400">Kitten 2</a>
<a class="image" data-src="http://placekitten.com/400/500">Kitten 3</a>
<div id="image-container">
<img src="http://placekitten.com/300/500" />
</div>
and something like the following:
$('.image').on('click', function() {
var imageSrc = $(this).data('src');
$('#image-container img').prop('src', imageSrc);
});
Which will update the child image tag of <div id="image-container"> with the data-src attribute value in the clicked link.
http://jsfiddle.net/9sxt6n0t/
Hope this helps.
just a quick function to slide
function slideIt(images , prev , next){
$('.slideshow img:nth-child(1)').show();
var imagesLength = $(images).length;
var i = 1;
$(prev).click(function() {
$(images).hide();
if(i !== 1){
$(images + ':nth-child('+ (i - 1) +')').show();
i--;
}else{
$(images +':nth-child('+imagesLength +')').show();
i = imagesLength;
}
});
//clicking image goes to next slide
$(''+next+','+images+'').on('click',function() {
$(images).hide();
if(i !== imagesLength){
$(images + ':nth-child('+ (i + 1) +')').show();
i++;
}else{
$(images + ':nth-child(1)').show();
i = 1;
}
});
}
and use like that slideIt(Images , prevArrow , nextArrow)
slideIt('.slideshow img','a.prev' , 'a.next');
DEMO HERE

Html in-page hidden text that isn't shown until link is clicked

sort of new to html. I'm looking to create animation that when am image is clicked, it plays an animation that splits open a half page of text and in stuff. Something like this: http://sketchtoy.com/62368639
If you want to do things like that, you should really have a look at a javascript framework like jquery (www.jquery.com)
I find this one particularly easy to learn.
For what you want to do:
<div style="display: none;" id="mytext">Your text</div>
<a onclick="$('#mytext').show()"></a>
The basic process is
Add the click handler for the images
Find the last image in the row that the clicked image is in
set the contents of the expanding element
insert the expanding element after the image from step 2
show the expanding element (in this case a slideDown animation)
This is using jQuery library, which you did not tag, but it makes doing this a lot easier. If you need a vanilla javascript approach one can be added.
HTML
<div id="container">
<img src="http://placehold.it/128x128" />
<img src="http://placehold.it/128x128" />
<img src="http://placehold.it/128x128" />
<img src="http://placehold.it/128x64" />
<img src="http://placehold.it/128x64" />
<img src="http://placehold.it/128x64" />
<div id="expander">
<img src="" />
<div id="info">
some info
</div>
</div>
</div>
JS
//Just making the expander half the height of the viewport
var winheight = $(window).height();
$("#expander").css("height",winheight/2);
$("img").click(function(){
var img = $(this);
var src = img.attr("src");
var afterImg = findLastImgInRow(img);
var expander = $("#expander");
//Hide the expander if previously open
expander.hide(0);
//just setting the insides
expander.find("img").attr("src",src);
expander.find("#info").html("This is a test");
//Put the expander after the last image in the row
//so it will appear between its row and the next
expander.insertAfter(afterImg);
expander.slideDown(600);
//This scrolls the page so that it will make the
//expander appear in the middle of the page
$('html, body').animate({
scrollTop: expander.offset().top-(winheight/4)
}, 600);
});
//Function to find the last image
//in a row by comparing their offset top values
function findLastImgInRow(img){
var imgTop = img.offset().top;
var img2 = img;
do{
if( img2.offset().top != imgTop ){
img2 = img2.prev();
break;
}
}while(img2=img2.next());
return img2;
}
JSFiddle Demo

Categories