Getting width from hidden image with JavaScript - javascript

I have in my HTML an image (id=”stone”) which I hide. From this image I make later several copies (id=”stone_xxx) in JS with cloneNode, put them in the DOM and remove the hidden-class. Everything works all right. I need the width initially at program start (before I make the first copy) so I take it from the hidden image (id=”stone”). But I always get the naturalHeight (90px) and not the actual height (45px).
I even tried it in the console to exclude that perhaps CSS is executed after JS but this didn`t change anything, so I had to use window.onload like in Get image width height javascript.
let stone = document.getElementById( "stone" );
let newStone = stone.cloneNode( false );
newStone.classList.remove( 'hidden' );
let i = 1;
newStone.id = "stone_" + i;
let el = document.getElementById( 'position_' + i);
el.prepend(newStone);
console.log(stone.naturalWidth); // => 272
console.log(stone.width); // => 272 Should be : 45
.hidden { display: none;}
.stone { width: 45px;}
<img id="stone" class="stone hidden" src=https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png />
<div id="position_1"></div>

I solved it: The browser doesn’t calculate the new dimensions of stone because of display none so the value of width isn´t recalculated. If I remove the class hidden everything is ok.
So I have 2 possibilities:
• Starting without class hidden and setting it afterwards.
• Get the width of one of the clones stones_xxx:
let newStone = document.getElementById( "stone_xxx" );
let width = newStone.width;
console.log(width); // => 45

Try this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<img id="image" src="http://www.fillmurray.com/200/200" alt="image" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script>
const width = $('#image').width();
console.log(width); // 200
</script>
</body>
</html>

Related

How do you add an eventListener to a htmlCollection that will change the display of another element?

Aim : to click box(x) and it opens pop-up(x);
This is my first javascript project, i've done loads of research but i'm still struggling.
The reason I'm using a getElementByClassList is because it returns an array. I would then take the array and get the corresponding pop-up box and change its display settings in css.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="box1 boxes"></div>
<div>
<div class="box2 boxes"></div>
<div class="box3 boxes"></div>
</div>
<div class="popup1"></div>
<div class="popup2"></div>
<div class="popup3"></div>
<script>
const boxes = document.getElementsByClassName('boxes');
// i would like to add an eventlistener for each object in the array
//
</script>
</body>
</html>
document.addEventListener("DOMContentLoaded", () => { // wait till all the DOM is Loaded, since querying objects at this point they are not there yet.
const boxes = document.querySelectorAll(".boxes"); // or use getElementsBy...
boxes.forEach(box => { // we are adding a click event listener to each box
box.addEventListener('click', (e) => {
const boxNumber = e.target.className.match(/box(\d)/)[1]; // through a regex we get the box number of the className
const popup = document.querySelector(`.popup${boxNumber}`);
console.log(popup)
// do whatever you want with the popup, add a className or whatever to open it :)
});
});
});
.boxes {
height: 20px;
width: 50px;
background: red;
margin: 10px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="box1 boxes"></div>
<div>
<div class="box2 boxes"></div>
<div class="box3 boxes"></div>
</div>
<div class="popup1"></div>
<div class="popup2"></div>
<div class="popup3"></div>
<script>
const boxes = document.getElementsByClassName('boxes');
// i would like to add an eventlistener for each object in the array
//
</script>
</body>
</html>
The method getElementsByClassName() indicats that return an array of html objects, in case there exists elements with passed css class.
The first step you have to iterate trough the array object:
for (int index = 0; index < boxes.length; index++)
{
}
Within for loop access to each element and assign the eventent handle
boxes[index].addEventListnener('click', function()
{
});
Within the body of declared anonymous function add your code.
You can try :
const boxes = document.getElementsByClassName('boxes');
const popups = document.querySelectorAll(".popups");
boxes.forEach((box,index)=>box.addEventListener("click",()=>{
const popup = popups[index]; // This gets the popup based on the box index so you will have to setup the html so that the popup for box1 is the first then popup for box2 second etc.
// Add styles to popup to display it
// Example
popup.style.opacity = "1";
})
Visit the 'mdn docs' or 'youtube' to learn how the array methods like forEach work

Change image onclick using javascript

Here's my problem:
I am new to Javascript and I am trying to make my image change on click.
It's a simple counter game that does a 2 frame animation of squidward hitting the dab.
So far I have got the counter to work but I cannot get the image to change on click as well. Also, it's going to have to change back to the original image so that it can be clicked and counted again.
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link rel="stylesheet" href="./style.css">
<title>Document</title>
</head>
<body>
<div class="container">
<button onclick="dabMan()"><img src="./squid-dab1.gif"> .
</button>
<br><br>
How many dabs??
<input type="text" id="text">
</div>
<script src="./script.js"></script>
</body>
</html>
var dabcount = 0;
function dabMan() {
dabcount = dabcount + 1
document.getElementById('text').value = dabcount;
console.log("dabMan", dabMan)
document.getElementById("./squid-dab1.gif") .src = "./squid-dab2.gif";
console.log("changeimage", dabMan)
}
instead of using the "onclick(){}" attribute in your html, write an event listener in js. Assuming your image tag is like this:
<img src='./squid-dab1.gif' id='myImage'>
Note: Javascript needs to know how to find your image... Hence the ID
Your javascript code should look like this:
<script>
var image = document.getElementById('myImage');
image.addEventListener('click', function(){
changeImage();
});
function changeImage(){
image.src = './squid-dab2.gif';
}
</script>
That will make it so that when you click the image, it will change. If you wanted a button to do that, simply create a button with the id "myImage" instead like so:
<button id='myImage'>Click me to change the picture</button>

Positioning element relative to another not working

I'm trying to position an element relative to another using the jQuery offset() method and I am trying to figure out why the $(window).resize function is not working.
JSBIN:http://jsbin.com/lanako/7/edit?html,js,output
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<style>
div{
display:inline-block;
position:relative;
height:200px;
width:200px;
border:solid black;
}
#somepara{
border: solid blue;
position:relative;
left:20%;
}
</style>
<body>
<div id ="first"> FIRST</div>
<div id = 'somepara'> </div>
</body>
</html>
JavaScript:
var p = $( "#somepara" );
var pf = $('#first');
var offset = p.offset();
p.html( "left: " + offset.left);
function offcss(){
pf.css({'left': offset.left + 6 + "px"});
}
$(document).ready(function(){
offcss();
$(window).resize(function(){
offcss();
});
});
I am essentially grabbing the offset().left of the second element ('#somepara') and trying to set the css of ('#first') right 6 pixels from (#somepara).Note: (#somepara) is has a fluid measurement (%), so the left position changes.
The equation initially works, but I want to upon resizing the browser, for the equation pf.css(), which calculates the css left property of (#first) to execute. Unfortunately the $(window).resize function I have set is not working, and thus the left property of (#first) is unchanged. The end goal I want is regardless the browser size, the elements will be separated by 6 pixels (#first right 6 pixels from #somepara).
Any help would be greatly appreciated!
The position of #somepara changes when you resize, so you need to take the value of p.offset() every time you call the offcss() function (and not only on first load).
function offcss() {
pf.css({'left': p.offset().left + 6 + "px"});
}
Regarding the resize it seems like it does exactly what you want.
Check this example:
http://jsbin.com/dewazuyuqo/1/edit?html,js,output

Styling elements created dynamically

i am a newbee so sorry if my question is basic.
i have written a code (with the help of the forum offcourse) where by clicking on an image another one appears and when you click on the new one, again another one appears and so on.
the problem is i can not add an style to the code and make the images appear in different positions to make a layout.
can anyone here help me?
thank you so much
<meta charset="utf-8">
<title> COOPER BLACK </title>
<link rel="stylesheet" type="text/javascript" href="style.css" media="screen">
</head>
<div class="container">
<script type="text/javaSCRIPT">
var i = 1
function imageClick() {
if (! this.alreadyClicked)
{
addimage();
counter();
this.alreadyClicked = true;
}
}
function addimage() {
var img = document.createElement("img");
img.src = "images/d"+i+".jpg";
img.onclick = imageClick;
document.body.appendChild(img);
}
function counter() {
i = i + 1
}
</script>
<div class="first">
<input class="first" type="image" src="images/d0.jpg" onclick="imageClick();">
</div>
</div>
Try setting the class attribute this way
img.setAttribute("class", "YourClassName");
Then apply the style to YourClassName in a CSS file/style tag. (Might also want to call the script after you load the CSS) Like so
.YourClassName { /* style here */ }
Edit:
You can also check if the elements are rendered well (the HTML tags have the class names and onClick methods) using the console (press F12 on the page)

Scroll content automatically in an overflow:none element (jQuery)

I have mixed content (images, text) in an overflow:none element. Now, I'd like to automatically scroll that content in x/y axis based on the location of the mouse pointer. Overflow:auto wouldn't be an option, as I wouldn't like to show/use the scrollbars in that element.
I've found a script which does something similar, but only with the background image. Is there a way to have a similar effect but with moving the whole content of the div? Thank you for your answers in advance!
<?xml version="1.0"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Test jQuery Move Background with Mouse Move</title>
<link rev="made" href="mailto:covertlinks [ at ] gmail [ dot ] com" />
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" />
<meta name="generator" content="NoteTab Pro 5.5" />
<meta name="author" content="Perry Wolf" />
<meta name="description" content="" />
<meta name="keywords" content="" />
<script type="text/javascript" src="jquery.1.3.2.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var vH=$('#viewer').height();
var vW=$('#viewer').width();
var vT=$('#viewer').offset().top;
var vL=$('#viewer').offset().left;
$('#viewer').mousemove(function(e){
var ypos=e.pageY-vT;
var xpos=e.pageX-vL;
var y=Math.round(ypos/vW*100);
var x=Math.round(xpos/vH*100);
$('#test').val(x+' , '+y);
$('#viewer').css({backgroundPosition: x+'% '+y+'%'});
});
});
</script>
</head>
<body style="color:#FFFFFF;background:#102030;text-align:center;">
<h1 style="text-align:center;">Test Move Background on Mousemove:</h1>
<div id="viewer" style="border:solid 1px #FFFFFF;margin:50px auto 0px auto;width:400px;height:400px;background:url(ironhide1024x768.jpg) 0% 0% no-repeat;cursor:url(target_cursor.gif), crosshair;text-align:center;line-height:300px;">
</div>
<input type="text" id="test" size="30" style="display:block;margin:10px auto;width:150px;" />
</body>
</html>
This was a fun one! Change it so you move the scrollTop and scrollLeft instead of background position. Since you have a percentage you could calculate the of scrollTop and scrollLeft like so. Check out the fiddle.
$(document).ready(function(){
var viewer = $('#viewer'),
vH = viewer.height(),
vW = viewer.width(),
vT = viewer.offset().top,
vL = viewer.offset().left,
sTop = viewer.find(':first').height() + 18 - vH,
sLeft = viewer.find(':first').width() + 18 - vW;
// the sTop and sLeft could be calculated differently. In this case
// I am assuming that the viewer has a single child that is larger than itself.
// realistically this should check total possible scrollTop and scrollLeft
$('#viewer').mousemove(function(e){
var $this = $(this),
y = (e.pageY-vT)/vH,
x = (e.pageX-vL)/vW;
$this.scrollTop(Math.round(sTop * y))
.scrollLeft(Math.round(sLeft * x));
});
});

Categories