Change CSS of element within elements and classes - javascript

I am trying to set the height of an image to be 50% of the width, but the image scales with the page. The current CSS I am targeting looks like this:
.img-quiz p span img { width: 100%; }
Here's what I've tried in js, but isn't working:
var imgQuiz = document.getElementByClassName('img-quiz').getElementsByTagName('img');
var elementStyle = window.getComputedStyle(imgQuiz);
var pixHeight = elementStyle.getPropertyValue('height');
imgQuiz.style.height = pixHeight * .5;
Also, I'm new to javascript, do I need to wrap this in a function (i.e. window.onload = function())?

Check out this JS Fiddle for help...
https://jsfiddle.net/Lm60v949/6/
var image = document.getElementsByClassName('img-quiz')[0].getElementsByTagName('img')[0];
// console.log( image ); // test to make sure the image was captured
/*
var image = document.getElementById('imgQuiz'); // much cleaner way to select
*/
image.height = image.width / 2;
// console.log( image.height, image.width ); // check the results
.img-quiz p span img { width: 100%; }
<div class="img-quiz">
<p>
<span>
<img id="imgQuiz" src="https://image.shutterstock.com/z/stock-photo--week-old-cocker-spaniel-puppy-630877553.jpg">
</span>
</p>
</div>
A couple of hiccups here:
.getElementsByClassName and .getElementsByTagName both return a HTMLCollection -- to use these, you will have to select the index of the collection that matches your image ([0], [1], [2], ... )
If you can, an ID on the targeted image would be ideal. Just easier to write and read code.
var image = document.getElementsByClassName('img-quiz')[0].getElementsByTagName('img')[0];
If you want brownie points, you can do something like:
image.onload = function(){
image.height = image.width / 2;
};
(assuming you have the image already captured and saved to the variable "image")
This is a nice sanity check to make sure the image exists (and has a height & a width) before trying to manipulate it.
You may be overthinking the problem a bit -- once an image is loaded, you can just look up the width and set the height property of the image.
There's a couple of extras that you can do here:
Check to make sure that the image width is not 0 (zero) ... this is a nice double-check that the image has loaded
if( image.width > 0 ){ ... }
Round the number down to a whole number (there's nothing wrong with .5 size increments, just nice to work with whole numbers)
image.height = Math.floor( image.width/2 );

Summary of your question:
My understanding of your situation is, your trying to make an image have the height of 50% of the webpage but its not doing so, you have looked into different methods including JavaScript but struggling, also you asked about onload methods.
If so this is my proposed solution
Solution
In this example we are using pure JavaScript (no library or framework)
The html has pre-set the src for the image, if you want to dynamically set the src then use the following imgEl.src = "path/to/file.jpg";
The method or trigger used is a DOMContentLoaded, which ensures all the HTML elements of the page have loaded before it begins trying to read and manipulate the DOM Elements.
The function we trigger is called funStart (Short for function Start), I always encourage people to use abreviations that define the object type so that it is easier to read such as fun for function, str for string, bl for boolean, obj for object, int for integer so on.
inside funStart we are assigning an DOM element as imgEl which is an image obj and we are saying set the width to be innerWidth which is the document width
We are then saying set the height to be 50% of the document height (innerHeight), by dividing the value into 2.
function funStart(){
var imgEl = document.getElementById("targetImg");
imgEl.height = innerHeight / 2;
imgEl.width = innerWidth;
}
document.addEventListener("DOMContentLoaded", funStart, false);
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Test</title>
</head>
<body>
<img id="targetImg" src="https://static.pexels.com/photos/257360/pexels-photo-257360.jpeg" alt="background image" title="background">
</body>
</html>

Here's a simple example (you can learn more in here):
var image = document.getElementsByClassName('img-quiz')[0];
image.height = image.width / 2;
<img src="https://dummyimage.com/100x100">
<img class="img-quiz" src="https://dummyimage.com/100x100">
The HTML file would be like this:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<img src="https://dummyimage.com/100x100">
<img class="img-quiz" src="https://dummyimage.com/100x100">
<script>
// you could also move the script tag to the head and add an event handler to the event load (window.onload = function() {...};
var image = document.getElementsByClassName('img-quiz')[0];
image.height = image.width / 2;
</script>
</body>
</html>

Related

Getting the width and height of a div or image after it finished loading

I'm creating an image gallery and I need to know the size of the div containing the image or the image itself after it loads. How can I get that? I've tried everything but it gives me the size of the DIV before it loads, which is 1px X 1px.
Basically everything is hidden, you click a link and the image displays, so the div goes from 1px by 1px to for example, say 419px by 1000px. How do I get that final size after the DIV or Image loads? the size can change depending on the device used and the image loaded. Is there anyway to get this information using just JavaScript?
Here's the function. If possible I would like to get the height of the image or the DIV after the image loads in the same function.
here's the function that i am testing
function ShowArt(nam,imgs,)
{
var currentPosition = parseInt(movingDivObj.style.top);
var scrollPos = window.scrollY || window.scrollTop || document.getElementsByTagName("html")[0].scrollTop;
movingDivObj.style.top = currentPosition + scrollPos + "px";
movingDivObj.style.display = "block";
document.getElementById("close").style.display = "block";
document.getElementById("selectedart").style.display = "block";
document.getElementById("artname").style.display = "block";
document.getElementById("background").style.display = "block";
display.src = imgs;
document.getElementById("artname").textContent= nam;
scrollPosition = window.pageYOffset;
document.body.style.position = "fixed";
document.body.style.top = `-${scrollPosition}px`;
}
Thanks!
Try using this DOM event listener, in the callback function you can write the necessary code to get your value I presume:here
In the same way that the "load" event works for the body, it works for images. So you could attach an "load" event on the image and when it triggers, measure the width/height.
const img = document.querySelector('#img')
img.addEventListener('load', (event) => {
console.log('width', event.target.width)
console.log('height', event.target.height)
})
img.src = 'https://via.placeholder.com/900x1000'
Have you tried:
<script>
var myImg = document.getElementById('image');
var realWidth = myImg.naturalWidth;
var realHeight = myImg.naturalHeight;
console.log(realWidth);
</script>
Solution 1:
Use this Solution in your JS file
JavaScript:
window.onload = () => {};//enter the code that gets the image or divs width and height in the {} brackets`
The window.onload function waits till the DOM is loaded and then executes a function. It is used mostly when you need to get default values from a predefined and static element.
Further Readings: https://www.w3schools.com/jsref/event_onload.asp
Solution 2:
NOTE: Use this only if you are using a 'script' tag to use the JS code in your HTML.
Use the script tag at the end of your HTML document
HTML:
<!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>
<!--Your code goes here-->
<script src="myScript.js"></script>
</body>
</html>
Thanks guys I appreciate all the help. I finally found an answer that worked though I got some great ideas. The answer was to have the images preload and when I did that it gave me the height of the image I needed for the next steps. Again thanks very much! I appreciate it. The code I used for this is below. After the images are preloaded I am able to get the width / height of the images so they work in the gallery as planned. It worked like a charm.
var images = new Array()
function preload() {
for (i = 0; i < preload.arguments.length; i++) {
images[i] = new Image()
images[i].src = preload.arguments[i]
}
}
preload(
"Photos/AloneInTheStorm.jpg",
"Photos/deepinthought.jpg",
"Photos/68degrees.jpg",
"Photos/forgotten.jpg",
"Photos/babylycan2.jpg",
"Photos/americancoot.jpg"
)

onload triggering too early for ajax content in IE

I have a page where the images are supplied dynamically and are scaled with javascript to fit within the appropriate dimensions. This was initially being done with an onload attribute in the img tag, but then I noticed that in IE, the height being returned for the image was much less in some cases than the actual height, which ended up distorting the image. I solved this by finding and resizing all the images after $(window).load() was done, which worked fine for the initial page load, but I also have the page set up to add more content with an ajax call. For the ajax content, I tried some code I found on here that improved the problem, but didn't completely solve it. Here is an example of one of my image tags
<img id="img<?php echo $prodModObj->rolloverID; ?>" class="mbImg unsized" src="<?php echo $prodModObj->img; ?>" alt="<?php echo $prodModObj->name; ?>" onerror="swapImage(<?php echo $prodModObj->rolloverID; ?>)" />
The swapImage function just swaps out the image with a placeholder if there is an error while loading. Here is my JS
function swapImage(thisImgID) {
var imgID = 'img#img' + thisImgID;
$(imgID).attr('src', '/images/NoImageAvail.jpg');
}
function checkImage(thisImgID, fitDimension, spaceDimension) {
var imgID = 'img#img' + thisImgID;
var imgHeight = $(imgID).height();
var imgWidth = $(imgID).width();
var displayHeight, displayWidth, newMargin;
if (imgHeight > imgWidth) {
displayHeight = fitDimension;
displayWidth = imgWidth*(displayHeight/imgHeight);
} else if (imgHeight < imgWidth) {
displayWidth = fitDimension;
displayHeight = imgHeight*(displayWidth/imgWidth);
} else {
displayWidth = fitDimension;
displayHeight = fitDimension;
}
$(imgID).css('height', displayHeight);
$(imgID).css('width', displayWidth);
newMargin = ((spaceDimension - displayHeight)/2);
$(imgID).css('margin-top', newMargin);
$(imgID).removeClass('mbImg unsized').addClass('mbImg sized');
}
And then on the page I have
$(window).load(function(){
// Resize product images
$('.mbImg.unsized').each( function() {
var rolloverID = $(this).attr('id').substr(3);
checkImage(rolloverID,250,270);
});
});
And then in the success portion of the ajax call, I have
$('.mbImg.unsized').each( function() {
var rolloverID = $(this).attr('id').substr(3);
if (this.complete) {
checkImage(rolloverID,250,270);
} else {
$(this).on('load', function(){
checkImage(rolloverID,250,270);
});
}
});
Images that have been cached by the browser work fine, and the images in the initial page load work fine, but about 1 in 5 of new ajax images come out distorted. Is there another method I can use to size all the ajax images correctly in IE?
Thanks for your help,
Maybe come at it another way?
I've tried to move away from html4 style tag syntax, to using simple html5 tags and a combination of JavaScript and CSS to control the "view".
Check out this fiddle:
http://jsfiddle.net/zacwolf/s1haq3mz/
A question becomes how you want your images to flow, as using this approach all of the images are technically the same size (as demonstrated by the border). Also note that the .src for the second image I tweeked the url a bit so that it was a 404 for the image file, which triggered the one error image instead.
<img id="one" class="myclass" />
<img id="two" class="myclass" />
<style>
.myclass{
height:270px;
width:250px;
background-position:center,center;
background-repeat:no-repeat;
background-size:contain;
}
</style>
<script>
var one = new Image();
one.onerror=
function(){
this.src='http://leomarketingep.com/wp-content/uploads/Sign-Error-icon.png'
}
one.onload=
function(){
$('#one').css('background-image','url('+one.src+')')
}
one.src='https://cjjulian.files.wordpress.com/2009/04/blah_blah_blah-703369.jpg';
var two = new Image();
two.onerror=
function(){
this.src='http://leomarketingep.com/wp-content/uploads/Sign-Error-icon.png';
}
two.onload=
function(){
$('#two').css('background-image','url('+two.src+')')
}
two.src='https://cjjulian.files.wordpress.com/2019/04/blah_blah_blah-703369.jpg';
</script>
If you have a lot of images, you can populate an array of Image objects, for better referencing, etc.

Why can't I get the naturalHeight/naturalWidth of an image in javascript/JQuery?

So I'm trying to do some very basic div re-sizing based on the properties of the image contained within it. I know I can do something really basic like set the background an padding around the image and achieve the same effect, but this is sort of a personal challenge.
The problem I am having is that when I try to fetch the naturalHeight or naturalWidth values of the image, I get a value of 0. However, when I try to fetch these values using the console, they return the correct values. Also, my resizeDiv() function is coming up as undefined in console.
Here's the code:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>kitten_resize - WesGilleland.com</title>
<script src="http://code.jquery.com/jquery-latest.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function() {
var kittens = new Array("100x100_kitten.jpeg","150x150_kitten.jpeg","200x150_kitten.jpeg");
$('#kittens').attr('src', kittens[0]); //set the image
function resizeDiv() {
var img = document.getElementById('kittens');
var imgH = img.naturalHeight;
var imgW = img.naturalWidth;
$('div').width(imgW);
$('div').height(imgH);
console.log('Current imgH: '+imgH);
console.log('Current imgW: '+imgW);
};
resizeDiv();
});
</script>
<style>
div {
background-color: black;
padding: 10px;
margin: auto;
}
</style>
</head>
<body>
<div>
<img id="kittens" src='' />
</div>
</body>
</html>
You can also find a working copy here: http://www.wesgilleland.com/projects/kitten_resize/
I feel like it's something very basic that I'm missing; I haven't fiddled with this stuff since my associate's degree a year ago. Thanks to anyone who can help!
That's because your image isn't yet loaded when you read the original dimensions.
You should read the dimensions when the image is loaded :
var img = $('#kittens')[0];
img.onload = resizeDiv;
img.src = kittens[0];

converting Div to Canvas options [duplicate]

It would be incredibly useful to be able to temporarily convert a regular element into a canvas. For example, say I have a styled div that I want to flip. I want to dynamically create a canvas, "render" the HTMLElement into the canvas, hide the original element and animate the canvas.
Can it be done?
There is a library that try to do what you say.
See this examples and get the code
http://hertzen.com/experiments/jsfeedback/
http://html2canvas.hertzen.com/
Reads the DOM, from the html and render it to a canvas, fail on some, but in general works.
Take a look at this tutorial on MDN: https://developer.mozilla.org/en/HTML/Canvas/Drawing_DOM_objects_into_a_canvas (archived)
Its key trick was:
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');
var data = '<svg xmlns="http://www.w3.org/2000/svg" width="200" height="200">' +
'<foreignObject width="100%" height="100%">' +
'<div xmlns="http://www.w3.org/1999/xhtml" style="font-size:40px">' +
'<em>I</em> like ' +
'<span style="color:white; text-shadow:0 0 2px blue;">' +
'cheese</span>' +
'</div>' +
'</foreignObject>' +
'</svg>';
var DOMURL = window.URL || window.webkitURL || window;
var img = new Image();
var svg = new Blob([data], {type: 'image/svg+xml;charset=utf-8'});
var url = DOMURL.createObjectURL(svg);
img.onload = function () {
ctx.drawImage(img, 0, 0);
DOMURL.revokeObjectURL(url);
}
img.src = url;
That is, it used a temporary SVG image to include the HTML content as a "foreign element", then renders said SVG image into a canvas element. There are significant restrictions on what you can include in an SVG image in this way, however. (See the "Security" section for details — basically it's a lot more limited than an iframe or AJAX due to privacy and cross-domain concerns.)
Sorry, the browser won't render HTML into a canvas.
It would be a potential security risk if you could, as HTML can include content (in particular images and iframes) from third-party sites. If canvas could turn HTML content into an image and then you read the image data, you could potentially extract privileged content from other sites.
To get a canvas from HTML, you'd have to basically write your own HTML renderer from scratch using drawImage and fillText, which is a potentially huge task. There's one such attempt here but it's a bit dodgy and a long way from complete. (It even attempts to parse the HTML/CSS from scratch, which I think is crazy! It'd be easier to start from a real DOM node with styles applied, and read the styling using getComputedStyle and relative positions of parts of it using offsetTop et al.)
You can use dom-to-image library (I'm the maintainer).
Here's how you could approach your problem:
var parent = document.getElementById('my-node-parent');
var node = document.getElementById('my-node');
var canvas = document.createElement('canvas');
canvas.width = node.scrollWidth;
canvas.height = node.scrollHeight;
domtoimage.toPng(node).then(function (pngDataUrl) {
var img = new Image();
img.onload = function () {
var context = canvas.getContext('2d');
context.translate(canvas.width, 0);
context.scale(-1, 1);
context.drawImage(img, 0, 0);
parent.removeChild(node);
parent.appendChild(canvas);
};
img.src = pngDataUrl;
});
And here is jsfiddle
Building on top of the Mozdev post that natevw references I've started a small project to render HTML to canvas in Firefox, Chrome & Safari. So for example you can simply do:
rasterizeHTML.drawHTML('<span class="color: green">This is HTML</span>'
+ '<img src="local_img.png"/>', canvas);
Source code and a more extensive example is here.
No such thing, sorry.
Though the spec states:
A future version of the 2D context API may provide a way to render fragments of documents, rendered using CSS, straight to the canvas.
Which may be as close as you'll get.
A lot of people want a ctx.drawArbitraryHTML/Element kind of deal but there's nothing built in like that.
The only exception is Mozilla's exclusive drawWindow, which draws a snapshot of the contents of a DOM window into the canvas. This feature is only available for code running with Chrome ("local only") privileges. It is not allowed in normal HTML pages. So you can use it for writing FireFox extensions like this one does but that's it.
You could spare yourself the transformations, you could use CSS3 Transitions to flip <div>'s and <ol>'s and any HTML tag you want. Here are some demos with source code explain to see and learn: http://www.webdesignerwall.com/trends/47-amazing-css3-animation-demos/
the next code can be used in 2 modes, mode 1 save the html code to a image, mode 2 save the html code to a canvas.
this code work with the library: https://github.com/tsayen/dom-to-image
*the "id_div" is the id of the element html that you want to transform.
**the "canvas_out" is the id of the div that will contain the canvas
so try this code.
:
function Guardardiv(id_div){
var mode = 2 // default 1 (save to image), mode 2 = save to canvas
console.log("Process start");
var node = document.getElementById(id_div);
// get the div that will contain the canvas
var canvas_out = document.getElementById('canvas_out');
var canvas = document.createElement('canvas');
canvas.width = node.scrollWidth;
canvas.height = node.scrollHeight;
domtoimage.toPng(node).then(function (pngDataUrl) {
var img = new Image();
img.onload = function () {
var context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
};
if (mode == 1){ // save to image
downloadURI(pngDataUrl, "salida.png");
}else if (mode == 2){ // save to canvas
img.src = pngDataUrl;
canvas_out.appendChild(img);
}
console.log("Process finish");
});
}
so, if you want to save to image just add this function:
function downloadURI(uri, name) {
var link = document.createElement("a");
link.download = name;
link.href = uri;
document.body.appendChild(link);
link.click();
}
Example of use:
<html>
<head>
</script src="/dom-to-image.js"></script>
</head>
<body>
<div id="container">
All content that want to transform
</div>
<button onclick="Guardardiv('container');">Convert<button>
<!-- if use mode 2 -->
<div id="canvas_out"></div>
</html>
Comment if that work.
Comenten si les sirvio :)
The easiest solution to animate the DOM elements is using CSS transitions/animations but I think you already know that and you try to use canvas to do stuff CSS doesn't let you to do. What about CSS custom filters? you can transform your elements in any imaginable way if you know how to write shaders. Some other link and don't forget to check the CSS filter lab.
Note: As you can probably imagine browser support is bad.
function convert() {
dom = document.getElementById('divname');
var script,
$this = this,
options = this.options,
runH2c = function(){
try {
var canvas = window.html2canvas([ document.getElementById('divname') ], {
onrendered: function( canvas ) {
window.open(canvas.toDataURL());
}
});
} catch( e ) {
$this.h2cDone = true;
log("Error in html2canvas: " + e.message);
}
};
if ( window.html2canvas === undefined && script === undefined ) {
} else {.
// html2canvas already loaded, just run it then
runH2c();
}
}

Changing source of image with an image of different size, won't resize in IE

I'm trying to create a very simple gallery using javascript. There are thumbnails, and when they're clicked the big image's source gets updated. Everything works fine, except when I try it in IE the images' size stays the same as the inital image's size was. Let's say initial image is 200x200 and I click on a thumbnail of a 100x100 image, the image is displayed but it is streched to 200x200. I don't set any width or height values, so I guess the browser should use image's normal size, and so does for example FF.
here's some code:
function showBigImage(link)
{
var source = link.getAttribute("href");
var bigImage = document.getElementById("bigImage");
bigImage.setAttribute("src", source);
return false; /* prevent normal behaviour of <a> element when clicked */
}
and html looks like this:
<ul id="gallery">
<li>
<a href="images/gallery/1.jpg">
<img src="images/gallery/1thumb.jpg">
</a>
</li>
(more <li> elements ...)
</ul>
the big image is created dynamically:
function createBigImage()
{
var bigImage = document.createElement("img");
bigImage.setAttribute("id", "bigImage");
bigImage.setAttribute("src", "images/gallery/1.jpg");
var gal = document.getElementById("gallery");
var gal_parent = gal.parentNode;
gal_parent.insertBefore(bigImage, gal);
}
There's also some code setting the onclick events on the links, but I don't think it's relevant in this situaltion. As I said the problem is only with IE. Thanks in advance!
Sounds like IE is computing the width and height attributes for #bigImage when it is created and then not updating them when the src is changed. The other browsers are probably noting that they had to compute the image dimensions themselves so they recompute them when the src is changed. Both approaches are reasonable enough.
Do you know the proper size of the image inside showBigImage()? If you do, then set the width and height attributes explicitly when you change the src:
function showBigImage(link) {
var source = link.getAttribute("href");
var bigImage = document.getElementById("bigImage");
bigImage.setAttribute("src", source);
bigImage.setAttribute("width", the_proper_width);
bigImage.setAttribute("height", the_proper_height);
return false;
}
If you don't know the new dimensions then change showBigImage() to delete #bigImage and create a new one:
function createBigImage(src) {
var bigImage = document.createElement("img");
bigImage.setAttribute("id", "bigImage");
bigImage.setAttribute("src", src || "images/gallery/1.jpg");
var gal = document.getElementById("gallery");
gal.parentNode.insertBefore(bigImage, gal);
}
function showBigImage(link) {
var bigImage = document.getElementById("bigImage");
if(bigImage)
bigImage.parentNode.removeChild(bigImage);
createBigImage(link.getAttribute("href"););
return false;
}

Categories

Resources