Getting dynamic Image width - javascript

While i am trying to get the size of image so, that i can append same size of div to explain the image. Images are coming dynamically so how can i get the image size that appear on browser not the real size of image. I have tried following code but does not work when parent class is smaller the image.
$('img').each(function(i) {
$currentImg = $(this);
imgTextshow = $currentImg.attr('imgtext');
var img = new Image();
img.onload = function() {
$currentImg.after("<div class='img-fscreen' style='width:" + this.width + "px; max-width:" + $currentImgParent + "'>" + imgTextshow + "</div>");
}
img.src = $(this).attr('src');
});

If you use the following lines of code inside of the onload handler, they should give you the correct dimensions:
$currentImg.width();
$currentImg.height();
simply because those methods return the width/height of the img DOM element.

Just use below line
img.onload = function() {
$currentImg.after("<div class='img-fscreen' style='width:" + $currentImg.width() + "px; max-width:" + $currentImgParent + "'>" + imgTextshow + "</div>");
}

Related

What's causing Intersection Observer API to respond differently when replacing synchronous logic with asynchronous logic?

Context
I've used the "Intersection Observer API" to build an infinite scroll image gallery. Basically this API allows me to load more items when a certain dummy DOM element enters the viewport.
Prototype
Currently the prototype is implemented for an “iPhone X” (375x812) mobile device only. See: http://urbexco-acceptance.droppages.com/min_rep_ex_working (use Chrome DevTools 'inspect' device toolbar to select the right resolution). The image gallery is generated based on 57 items in the "database". When scrolling down, first 15 elements are loaded, then 15 more elements are loaded, then another 15 elements are loaded into the DOM, then another 10 elements are loaded, and finally 2 elements are loaded. When there are still more than 15 items left to be loaded, they are added using the following logic:
function addItems(n){
// Append new items to .items-wrapper
var items = document.querySelector('.items-wrapper');
for (var i = 0; i < n; i++) {
var url = 'https://img01.ztat.net/article/spp-media-p1/09742e38c25b3e1d9716e02f8e76e87d/89fc0bda6a2c446a8e9e0d8adbc9a4fe.jpg';
width = 170.5;
height = 246;
var newDiv = document.createElement('div');
newDiv.classList.add('item');
items.appendChild(newDiv);
newDiv.innerHTML = "<img src=" + '"' + url + '"' + "width=" + '"' + width + '"' + "height=" + height + "/>";
}
}
Minimal Working Example (no mobile view possible)
https://jsfiddle.net/9jqgzymo/
Objective
Since image width and height are currently hardcoded, I am now trying to assign width and height dynamically based on the image url. I try to achieve this using the getMeta() function:
function addItems(n){
// Append new items to .items-wrapper
var items = document.querySelector('.items-wrapper');
for (var i = 0; i < n; i++) {
var url = 'https://img01.ztat.net/article/spp-media-p1/09742e38c25b3e1d9716e02f8e76e87d/89fc0bda6a2c446a8e9e0d8adbc9a4fe.jpg';
getMeta(url);
}
}
function getMeta(url){
var img = new Image();
img.onload = function(){
res = calculateAspectRatioFit(this.width, this.height, 170.5, 246)
var newDiv = document.createElement('div');
newDiv.classList.add('item');
var items = document.querySelector('.items-wrapper');
items.appendChild(newDiv);
newDiv.innerHTML = "<img src=" + '"' + url + '"' + "width=" + '"' + res.width + '"' + "height=" + res.height + "/>";
};
img.src = url;
}
function calculateAspectRatioFit(srcWidth, srcHeight, maxWidth, maxHeight) {
var ratio = Math.min(maxWidth / srcWidth, maxHeight / srcHeight);
return { width: srcWidth*ratio, height: srcHeight*ratio };
}
Challenge
When implementing it this way, I see that - on initiation - already 30 items from the "database" where added to the DOM. Sometimes even all of them? Currently the non-working prototype is implemented for an “iPhone X” (375x812) mobile device only. See: http://urbexco-acceptance.droppages.com/min_rep_ex_not_working (use Chrome DevTools 'inspect' device toolbar to select the right resolution). For a minimal working example, see: https://jsfiddle.net/k3p20qno/
Key question
What is the reason that with my new implementation, on initiation, already 30 or more items are added to the DOM? How can I fix it?
Well the problem lies in here :
function getMeta(url){
var img = new Image();
img.onload = function(){
res = calculateAspectRatioFit(this.width, this.height, 170.5, 246)
var newDiv = document.createElement('div');
newDiv.classList.add('item');
var items = document.querySelector('.items-wrapper');
items.appendChild(newDiv);
newDiv.innerHTML = "<img src=" + '"' + url + '"' + "width=" + '"' + res.width + '"' + "height=" + res.height + "/>";
};
img.src = url;
}
Above code does an async operation with onload event. So it doesn't wait to image to be loaded.
If you turn this into a function that returns a promise you will get the result that you expect. And you should await where you call the function. That way when you add the intersection element it will add it as the last element of the items wrapper. If you don't await it will be added as the first element because the loading of the images will be async and will happen later.
function getMeta(url){
var img = new Image();
const p = new Promise(resolve =>{
img.onload = function(){
console.log( this.width+' '+ this.height );
res = calculateAspectRatioFit(this.width, this.height, 170.5, 246)
var newDiv = document.createElement('div');
newDiv.classList.add('item');
var items = document.querySelector('.items-wrapper');
items.appendChild(newDiv);
newDiv.innerHTML = "<img src=" + '"' + url + '"' + "width=" + '"' + res.width + '"' + "height=" + res.height + "/>";
resolve()
};
})
img.src = url;
return p;
}
Fiddle
Edit: Put the resolve() in the right position which is inside the load function

How do you resize an image in javascript

I have a HTML editor that inserts items from predefined buttons using javascript and would like add a button to be able to post a thumbnail of a downloaded image with a link to view it full size. I have created the following code but it doesn't work and always inserts a 100X100 size image. Can anyone suggest a better way that does work?
// insert HTML code
insertHtml: function (url, title) {
var imgHeight;
var imgWidth;
function setHTMLImageSize() {
imgHeight = this.height;
imgWidth = this.width;
var ImageRatio = (imgHeight / imgWidth);
if (imgWidth > 100) {
imgWidth = 100;
imgHeight = (imgWidth * ImageRatio);
}
return true;
}
var myImage = new Image();
myImage.name = url;
myImage.onload = setHTMLImageSize;
myImage.src = url;
if (imgWidth = 0) {
imgWidth = 100;
}
if (imgHeight = 0) {
imgHeight = 100;
}
this.get_designPanel().insertHTML("<a href=\"" + url + "\" target=\"" + "_blank" + "\" style=\"" + "text-decoration: none" + "\" ><img src=\"" + url + "\" title=\"" + title + "\" width=\"" + imgWidth + "\" height=\"" + imgHeight + "\" /></a><br/>click image to View full size<br/>");
}
You are setting width and height to 100 before the onload function has fired. The onload will happen asynchronously so you should do a check for zero height or width inside the callback.
Edit:-
As observed by enhzflep in the comment below you have also used equal as assignment rather than to check conditions. I'd change them to triple equals === as a rule when you know the type you are expecting.
Is it not going to be simpler to control a thumbnail through CSS anyway? You could set max-height and max-width properties to maintain aspect ratio.
Thanks to everyone ... from the CSS suggestion I have resolved the issue by removing all the code to determine the image size and instead including a style attribute setting the width to 100 and the height to auto into the HTML image code being added to the editor ... see below
this.get_designPanel().insertHTML("<br/>Thumbnail view<br/><a href=\"" + url + "\" target=\"" + "_blank" + "\" style=\"" + "text-decoration: none;" + "\" ><img style=\"" + "width: 100px; height: auto" + "\" src=\"" + url + "\" alt=\"" + title + "\" title=\"" + title + "\" /></a><br/>Click image to view in seperate window<br/>");

Replace image with error image by image name with onChange="swapImage()"

Pretty new to Javascipt.
Using a form with on top of the form a image. If they change an option in one of the eight dropdown boxes the image will change. However, if they make a configuration that doesn't exsist, the image is not found and the standard broken imagelink will be displayed.
Is there a way to check when I'm changing a value and trigger the onChange="swapImage()"from a dropdown to trigger an event to check if image exsists, and if not, replace it with an error image?
<script type="text/javascript">
function swapImage(){
var image = document.getElementById("imageToSwap");
var hoogte = document.getElementById("hoogte").value;
var bt = document.getElementById("bt").value;
var fase = document.getElementById("fase").value;
var aardlek = document.getElementById("aardlek").value;
var kook = document.getElementById("kook").value;
var groepen = document.getElementById("groepen").value;
var merk = document.getElementById("merk").value;
image.src = "http://www.groepenkasten.expert/images/" + merk + "/" + hoogte + "_" + bt + "_" + fase + "_" + aardlek + "_" + kook + "_" + groepen +".gif";
};
Because the image is Dynamic, there is no full page reload,. Therefore it will not detect the error that the broken image produce when the image doesn't exsist.
Link to the form: http://www.groepenkasten.expert/meld-uw-storing/kant-en-klare-groepenkasten

Javascript - window.open() popup size issue

I am trying to display preloaded images in a newly created popup window. Here is the code:
HTML
<div id="hiddenImages" style="display: none;"></div>
<img src="SmallImage1.gif" width="196" height="130" border="0">
<img src="SmallImage2.gif" width="196" height="130" border="0">
JS
<script type="text/javascript">
preloadImages('BigImage1.png','BigImage2.png');
</script>
// PreLoadImages:
function preloadImages() {
var hiddenDiv = document.getElementById('hiddenImages');
var i;
var img;
for(i = 0; i < arguments.length; i++) {
img = document.createElement('img');
img.src = arguments[i];
img.id = arguments[i];
img.alt = '';
hiddenDiv.appendChild(img);
}
}
// OpenImage:
function OpenImage(element,e)
{
e.preventDefault();
var big_image = element.getAttribute("href");
var img = document.getElementById(big_image);
var top = (screen.height/2)-(img.height/2);
var left = (screen.width/2)-(img.width/2);
var str = "\"" + "width=" + img.width + ",height=" + img.height + ",top=" + top + ",left=" + left + ",status=0, scrollbars=0, resizable=0" + "\"";
alert(str);
var myWindow = window.open(img.src , "win1", str);
}
When I output 'str' variable in OpenImage() function, this code gives perfect dimensions of the big image. However, the size of popup window is always different than size of the image. IE stretches the popup window horizontally while Google Chrome stretches it vertically. In spite of the fact that both browsers show exactly the same dimensions for the image. And these dimensions of the image are actually being set as size of the pop up window.
Regards.
Try this out, also try to rename your variable top, I think javascript read this as a keyword.
var str = "width=" + img.width + ",height=" + img.height + ",top=" + tops + ",left=" + left + ",status=0, scrollbars=0, resizable=0 ";

How to implement an onclick function to an array of divs

I'm using the Flickr API and I want to create a onlick popup div for each image which shows the image in a larger form like this http://fancybox.net/.
How can I implement this so that the onclick function will be applied to each div in the div container?
The project: http://jsfiddle.net/phippsy20/rtzp8/
jQuery: so this statement makes the divs
for (var i = 0; i < 210; i++) {
$('<div />').attr('id', 'photo-' + i).addClass('photo').appendTo('#photo-container');
}
This function loads the picture from flickr as the background image:
$.each(data.photos.photo, function(i, photo) {
var imgURL = 'http://farm' + photo.farm + '.staticflickr.com/' + photo.server + '/' + photo.id + '_' + photo.secret + '_n.jpg';
console.log(imgURL);
// Pre-cache image
$('<img />').attr({'src': imgURL, 'data-image-num': i}).load(function() {
console.log('image loaded');
var imageDataNum = $(this).attr('data-image-num');
$('#photo-' + imageDataNum).css('background-image', 'url(' + imgURL + ')').removeClass('fade-out').addClass('fade-in');
})
Ok, if i understand your question, this may help you:
$("#heading-name div").each(function(i){
$(this).attr("onclick","popup("+i+")");
});
Demo working: http://jsfiddle.net/k2h8p/1/ (test the code locally in your computer)

Categories

Resources