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 ";
Related
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
I'm not well know about javascripts, got this code from a website.
Using javascript to display random images from array in div
javascript working fine.
But loaded images displays in random sizes
tried using css style and all css html image attributes to resize them but nothing works, as they are displayed directly through javascript
want something to resize them directly in javascript
code main :
<script>
var arrayImg = new Array();
arrayImg[0] = "a11.jpg";
arrayImg[1] = "a12.jpg";
getRandomImage(arrayImg, "");
function getRandomImage(imgAr, path) {
path = path || 'images/'; // default path here
var num = Math.floor( Math.random() * imgAr.length );
var img = imgAr[ num ];
var imgStr = '<img src="' + path + img + alt = "" >';
document.writein(imgStr);
document.close();
}
</script>
code I used to resize image : (but didn't work) :
<script>
var arrayImg = new Array();
arrayImg[0] = "a11.jpg";
arrayImg[1] = "a12.jpg";
getRandomImage(arrayImg, "");
function getRandomImage(imgAr, path) {
path = path || 'images/'; // default path here
var num = Math.floor( Math.random() * imgAr.length );
var img = imgAr[ num ];
var img.height = 4vw;
var img.width = 20%;
var imgStr = '<img src="' + path + img + img.height + img.width + alt = "" >';
document.writein(imgStr);
document.close();
}
</script>
even tried using : (but still didn't work)
document.writeln('<td' + '><imgstr"' + height="180" width="160" border="0" ><' + '/td>');
You have a few syntax error in getRandomImage function.
function getRandomImage(imgAr, path) {
path = path || 'images/'; // default path here
var num = Math.floor( Math.random() * imgAr.length );
var img = imgAr[ num ];
/*
1. variable name should not contain .
2. the width and height value should be quoted and placed in "style" attribute
*/
//var img.height = 4vw;
//var img.width = 20%;
var imgHeight = '4vw';
var imgWidth = '20%';
/* closed string quotations and placed data in the right attribute */
var imgStr = '<img src="' + path + img + '"'
+ ' style="height:' + imgHeight + ';width:' + imgWidth + ';'
+ ' alt="">';
document.writein(imgStr);
document.close();
}
You have several places where you didn't close quotation marks.
In code main:
var imgStr = '<img src="' + path + img + '"' + ' alt = "" >';
In resize code
var imgStr = '<img src="' + path + img + '" height="' + img.height + '" width="' + img.width + '" alt = "" >';
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/>");
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>");
}
So like i wrote in the title, i have multiple elements with same class i fetch that class and try to check for the child image's width/height/src of that image.
i only manage to get the height // width of the first image however i get the src of all images.
here is the html:
<a class="test">
<img src="http://www.kitchenspro.com/files/Testimonials/Large/1502046700250312a71707.jpg">
</a>
<a class="test">
<img src="http://www.kitchenspro.com/files/Testimonials/Large/40183.9461166782.jpg">
</a>
<a class="test">
<img src="http://sphotos-a.xx.fbcdn.net/hphotos-ash4/s480x480/391362_365319466870994_1543740404_n.jpg">
</a>
here is the jquery
var imagesrc= "";
var imageheight = "";
var imagewidth = "";
var i=0;
$(".test > img").each(function() {
i++;
imagesrc = $(this).attr("src");
imageheight = $(this).width();
imagewidth = $(this).height();
document.write("<br>This is image's src: " + imagesrc + " This is img height: " + imageheight + " this is width: " + imagewidth + "<br>");
});
I apologize if i didnt present the code the right way.
Any help would be highly appreciated.
Thanks in advanced.
The first call to document.write destroys the rest of elements so that's why you only get information from one of them, use .append() or something else to show your results.
Exactly what #Musa said.
To help clean up your code and give a lesson on efficiency and native javascript, I have supplied a snippet.
// Document Fragments are lightweight DOM containers. Append elements to this in loops and then attach the fragment to the actual DOM afterwards to increase efficiency.
var frag = document.createDocumentFragment();
// i, or index, comes out of box in most loops.
$(".test img").each(function(i, el) {
// Local variables specific to each image
var imagesrc = $(this).attr("src");
var imageheight = $(this).width();
var imagewidth = $(this).height();
var message = "This is image's src: " + imagesrc + " This is img height: " + imageheight + " this is width: " + imagewidth;
// Appending the node to the frag with native js
var p = document.createElement("p");
p.innerText = message;
frag.appendChild(p);
// Viewing the console message for fun
console.log(message);
});
document.body.appendChild(frag);