129

I want to create a simple bit of JS code that creates an image element in the background and doesn't display anything. The image element will call a tracking URL (such as Omniture) and needs to be simple and robust and work in IE 6 =< only. Here is the code I have:

var oImg = document.createElement("img");
oImg.setAttribute('src', 'http://www.testtrackinglink.com');
oImg.setAttribute('alt', 'na');
oImg.setAttribute('height', '1px');
oImg.setAttribute('width', '1px');
document.body.appendChild(oImg);

Is this the simplest but most robust (error free) way to do it?

I cannot use a framework like jQuery. It needs to be in plain JavaScript.

Devid Farinelli
  • 7,514
  • 9
  • 42
  • 73
Pete
  • 1,455
  • 2
  • 12
  • 9

11 Answers11

101
oImg.setAttribute('width', '1px');

px is for CSS only. Use either:

oImg.width = '1';

to set a width through HTML, or:

oImg.style.width = '1px';

to set it through CSS.

Note that old versions of IE don't create a proper image with document.createElement(), and old versions of KHTML don't create a proper DOM Node with new Image(), so if you want to be fully backwards compatible use something like:

// IEWIN boolean previously sniffed through eg. conditional comments

function img_create(src, alt, title) {
    var img = IEWIN ? new Image() : document.createElement('img');
    img.src = src;
    if ( alt != null ) img.alt = alt;
    if ( title != null ) img.title = title;
    return img;
}

Also be slightly wary of document.body.appendChild if the script may execute as the page is in the middle of loading. You can end up with the image in an unexpected place, or a weird JavaScript error on IE. If you need to be able to add it at load-time (but after the <body> element has started), you could try inserting it at the start of the body using body.insertBefore(body.firstChild).

To do this invisibly but still have the image actually load in all browsers, you could insert an absolutely-positioned-off-the-page <div> as the body's first child and put any tracking/preload images you don't want to be visible in there.

Devid Farinelli
  • 7,514
  • 9
  • 42
  • 73
bobince
  • 528,062
  • 107
  • 651
  • 834
55
var img = new Image(1,1); // width, height values are optional params 
img.src = 'http://www.testtrackinglink.com';
Jason Bunting
  • 58,249
  • 14
  • 102
  • 93
Tad
  • 639
  • 5
  • 12
27
var img = document.createElement('img');
img.src = 'my_image.jpg';
document.getElementById('container').appendChild(img);
Michael L Perry
  • 7,327
  • 3
  • 35
  • 34
  • @AndreiCristianProdan Use `console.log` between each pair of lines, so you'll know exactly which line is freezing it. – Rodrigo Aug 01 '19 at 12:52
10

jQuery:

$('#container').append('<img src="/path/to/image.jpg"
       width="16" height="16" alt="Test Image" title="Test Image" />');

I've found that this works even better because you don't have to worry about HTML escaping anything (which should be done in the above code, if the values weren't hard coded). It's also easier to read (from a JS perspective):

$('#container').append($('<img>', { 
    src : "/path/to/image.jpg", 
    width : 16, 
    height : 16, 
    alt : "Test Image", 
    title : "Test Image"
}));
Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
Darryl Hein
  • 142,451
  • 95
  • 218
  • 261
  • 25
    He specifically requested no jQuery. – Alex Mar 29 '14 at 22:30
  • 2
    Also, parsing text into code is pointless, ineffective and plain lazy. Whoever reads this, avoid doing it like that. I mean, if you're inserting literal `` into DOM, do it with [innerHTML](https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML) then. I just don't get this :/ – ᴍᴇʜᴏᴠ Apr 25 '16 at 14:01
9

Just for the sake of completeness, I would suggest using the InnerHTML way as well - even though I would not call it the best way...

document.getElementById("image-holder").innerHTML = "<img src='image.png' alt='The Image' />";

By the way, innerHTML is not that bad

Binny V A
  • 2,036
  • 3
  • 20
  • 23
  • 2
    I was using this method for a 50x50 grid of images. When I tried the above appending method my execution time jumped from 150ms to 2250ms. So I'm thinking innerHTML is much more efficient. – Nicholas Oct 17 '13 at 18:09
5

Shortest way:

(new Image()).src = "http:/track.me/image.gif";
aemkei
  • 11,076
  • 8
  • 37
  • 29
  • 2
    If not added to the document, it is not certain the image src will be fetched at all (browser-dependent). – bobince Oct 23 '08 at 12:26
  • 1
    does anyone have cases of browsers not fetching that image if not attached to the DOM? – Antoine Dec 09 '13 at 16:56
  • 2
    I've testing this in IE, FF, Chrome, and Safari—all load the image without it being appended to the DOM. Is this an issue with older browsers? – Seanonymous Mar 30 '15 at 23:39
3

Are you allowed to use a framework? jQuery and Prototype make this sort of thing pretty easy. Here's a sample in Prototype:

var elem = new Element('img', { 'class': 'foo', src: 'pic.jpg', alt: 'alternate text' });
$(document).insert(elem);
swilliams
  • 48,060
  • 27
  • 100
  • 130
3

you could simply do:

var newImage = new Image();
newImage.src = "someImg.jpg";

if(document.images)
{
  document.images.yourImageElementName.src = newImage.src;
}

Simple :)

Brigand
  • 84,529
  • 20
  • 165
  • 173
Nitin Bansal
  • 2,986
  • 3
  • 23
  • 30
2

Just to add full html JS example

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>create image demo</title>
    <script>


        function createImage() {
            var x = document.createElement("IMG");
            x.setAttribute("src", "http://www.iseebug.com/wp-content/uploads/2016/09/c2.png");
            x.setAttribute("height", "200");
            x.setAttribute("width", "400");
            x.setAttribute("alt", "suppp");
            document.getElementById("res").appendChild(x);
        }

    </script>
</head>
<body>
<button onclick="createImage()">ok</button>
<div id="res"></div>

</body>
</html>
Vaibs
  • 2,018
  • 22
  • 29
1

This is the method I follow to create a loop of img tags or a single tag as ur wish

method1 :
    let pics=document.getElementById("pics-thumbs");
            let divholder=document.createDocumentFragment();
            for(let i=1;i<73;i++)
            {
                let img=document.createElement("img");
                img.class="img-responsive";
                img.src=`images/fun${i}.jpg`;
                divholder.appendChild(img);
            }
            pics.appendChild(divholder);

or

method2: 
let pics = document.getElementById("pics-thumbs"),
  imgArr = [];
for (let i = 1; i < 73; i++) {

  imgArr.push(`<img class="img-responsive" src="images/fun${i}.jpg">`);
}
pics.innerHTML = imgArr.join('<br>')
<div id="pics-thumbs"></div>
Gvs Akhil
  • 2,165
  • 2
  • 16
  • 33
0

As others pointed out if you are allowed to use a framework like jQuery the best thing to do is use it, as it high likely will do it in the best possible way. If you are not allowed to use a framework then I guess manipulating the DOM is the best way to do it (and in my opinion, the right way to do it).

Leandro López
  • 2,185
  • 1
  • 15
  • 17