set download attribute on dynamically displayed image - javascript

I'm displaying a long list of images from a site on a page with the below code. Id like to be able to use the download HTML5 attribute so that click each image will download it.
Here's what I've tried:
for (var i = 0; i<arlnData.d.length;i++) {
var img = document.createElement('img');
img.src = "https://images.website.com/airvendors/airlines_"+arlnData.d[i].Code+".gif";
img.download ="my image";
//also tried:
//img.src = "https://images.website.com/airvendors/airlines_"+arlnData.d[i].Code+".gif";
document.body.appendChild(img);
var imageCellspace=document.createElement('br');
document.body.appendChild(imageCellspace);
}
Images are displayed fine but clicking to download doesnt work.
What is the proper syntax here?

Try with this:
for (var i = 0; i<arlnData.d.length;i++) {
var img = document.createElement('img');
img.src = "https://images.website.com/airvendors/airlines_"+arlnData.d[i].Code+".gif";
var a = document.createElement('a');
a.href = img.src;
a.download = 'image.gif';
a.appendChild(img);
document.body.appendChild(a);
var imageCellspace=document.createElement('br');
document.body.appendChild(imageCellspace);
}
The download attribute is for a, not for img. Check the documentation.

You have to wrap your <img> on a <a>, as the download attribute is only for anchors.
var img = document.createElement('img');
img.src = "https://images.website.com/airvendors/airlines_"+arlnData.d[i].Code+".gif";
var a = document.createElement('a');
a.href = img.src;
a.download = "My image name";
a.appendChild(img);
document.body.appendChild(a);
See MDN for reference !

Related

Console-download of images from a webpage

Surely there are better options, but I was trying this:
images = document.getElementsByTagName("img")
links = []
for (let img of images){
const alt = img.getAttribute("alt")
if( alt && alt.substring("code")){
var save = document.createElement('a');
save.href = img.src
save.download = `${img.src}`
save.click()
break//test with one for now
}
}
from the console. Now instead of automatically downloading it just opens it in a different page and I'd need to manually download.
Any ideas what am I missing?

How do I make a button that will download a file

I'm attempting to make a button that will download an image file upon pressing, but what I've made will only take me to the file itself.
Html:
<button onclick="file()">Click me, i'll download an image</button>
Javascript:
function file() {
const anchor = document.createElement("a");
anchor.href = "dingus.png";
anchor.download = "dingus.png";
document.body.appendChild(anchor);
anchor.click();
}
Here it is, don't forget to remove the appended element.
function download(url) {
const anchor = document.createElement('a')
anchor.href = url
anchor.download = url.split('/').pop()
document.body.appendChild(anchor)
anchor.click()
document.body.removeChild(anchor)
}
download path should be in HTTP path then only it will work. local that will not work
Example
function file() {
const anchor = document.createElement("a");
anchor.href = "http://www.exampleApiPath.com/dingus.png";
anchor.download = "http://www.exampleApiPath.com/dingus.png";
document.body.appendChild(anchor);
anchor.click(); }

post image on a blog with this script

I have a webpage in PHP in which there is an image.
Post this image on a blog with this script.
<div id="x"></div>
<script>
let div = document.getElementById("x");
let aTag = document.createElement("a");
aTag.href = 'http://www.meteoarachova.com/ws';
aTag.title = 'Εικόνα Κάμερας Μετεωρολογικού Σταθμού Αράχωβας';
aTag.target = '_blank';
aTag.outline = 'none';
let img = document.createElement("img");
img.src = "http://www.meteoarachova.com/webcam/arachova1.jpg";
img.style.width = '100%';
img.style.height = '80%';
aTag.append(img)
div.append(aTag);
console.log(document.getElementsByTagName('a')[0])
</script>
But I also want to post a second images at a different point on the same blog.
The two images to be in completely different places on the page and not next to each other.
I put the same code but it does not work.
How can I customize it to work?
Id's are unique to the page, hence you can only have a single div with the id "x".
That is why it probably won't work, or you're appending to the same place on the page.

Is there is any way to save images url using dynamic anchor tag?

I have a service which takes a screenshot and return a promise which is parse using .toDataURL then that URL is split into proper url.
Now I want to dynamically download the image using the anchor tag
i tried URL.createObjectURL(imageAsBase64String) but it is giving an error
var snapotPromise = SomeApiService.TotakeScreenshot(param); // it return promise
snapotPromise.then(function onSuccess(iResult) {
var imageAsBase64String = iResult.toDataURL("image/png", 1.0);
var splittedImage = imageAsBase64String.substr(imageAsBase64String.indexOf(',') + 1)
var a = document.createElement("a");
a.href = URL.createObjectURL(imageAsBase64String);
a.download = "saveScreenShot.png";
a.click();
});
Download image with name saveScreenShot.png

When is it safe to call URL.revokeObjectURL?

If I understand correctly URL.createObjectURL creates a URL that represents a file or a blob. Because the URL is just a string the browser has no way to know when you're finished with the resource that URL represents so there's a provided URL.revokeObjectURL function.
MDN shows this example:
var canvas = document.getElementById("canvas");
canvas.toBlob(function(blob) {
var newImg = document.createElement("img");
var url = URL.createObjectURL(blob);
newImg.onload = function() {
// no longer need to read the blob so it's revoked
URL.revokeObjectURL(url);
};
newImg.src = url;
document.body.appendChild(newImg);
});
So some questions
Would it be safe to change the code to revoke the URL immediately after assigning newImg.src?
var canvas = document.getElementById("canvas");
canvas.toBlob(function(blob) {
var newImg = document.createElement("img");
var url = URL.createObjectURL(blob);
newImg.src = url;
// no longer need to read the blob as it's assigned to newImg.src
URL.revokeObjectURL(url);
document.body.appendChild(newImg);
});
I'm guessing the answer is "no" because potentially nothing has started on newImg.src = url;. It's still just a string at that point and will remain so until the current JavaScript event exits. Or is it?
Would it be valid/legal/correct to revoke the URL but still use it knowing it's referenced by other objects?
var canvas = document.getElementById("canvas");
canvas.toBlob(function(blob) {
var newImg = document.createElement("img");
var url = URL.createObjectURL(blob);
newImg.onload = function() {
// no longer need to read the blob so it's revoked
URL.revokeObjectURL(url);
// Use the URL again even though it's revoked
var newImg2 = new Image():
newImg2.src = url;
};
newImg.src = url;
document.body.appendChild(newImg);
});
In this case I'm assigning newImg2.src = url even though I've already revoked the URL. The idea being that newImg is still referencing the blob URL so it would seem valid to be able to say
someImage.src = someOtherImage.src
at any time. Is it?
Okay, well, following #adeneo's advice I tested this
$('#test').on('change', function(e) {
var newImg = document.createElement("img");
var url = URL.createObjectURL( e.target.files[0] )
console.log(url);
newImg.src = url;
URL.revokeObjectURL(url);
document.body.appendChild(newImg);
console.log(url);
});
$('#test3').on('change', function(e) {
var newImg = document.createElement("img");
var url = URL.createObjectURL( e.target.files[0] )
console.log(url);
newImg.src = url;
newImg.onload = function() {
URL.revokeObjectURL(url);
document.body.appendChild(newImg);
var i = new Image();
i.src= newImg.src;
document.body.appendChild(i);
setTimeout(function() {
var g = new Image();
g.src = newImg.src;
document.body.appendChild(g);
}, 3000);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>test revoke before use</p>
<input type="file" id="test"/>
<br />
<br />
<br />
<p>test use revoke use</p>
<input type="file" id="test3" />
At least in Firefox, once URL.revokeObjectURL is called the URL can no longer be used, even though other things are accessing it.
So both #1 and #2 in the question fail and, even though in #2 newImg.src still has the URL that URL won't work anywhere else once URL.revokeObjectURL has been called.
In React, there is a hook called useEffect, and one of the things that it does, is what action would you like to take right before you're leaving the component(function), and there you release the existing object URL which was previously created by calling URL.createObjectURL().
Releasing an existing object URL using URL.revokeObjectURL:
useEffect(() => () => URL.revokeObjectURL(file as string), [file])
const onChangeFile = (e: React.ChangeEvent<HTMLInputElement>) => {
if (e.target.files[0]) {
setFile(URL.createObjectURL(e.target.files[0]))
}
}

Categories