0

I want to add a overlay on the images of a website when you hover them. I implemented this here and it's working fine http://jsfiddle.net/stujLbjh/

This is the js code:

var divs = document.querySelectorAll('.image-thumb');

for (var i = 0; i < divs.length; i++) 
{
    var overlay = document.createElement('a')
    overlay.className = 'icon-overlay';
    overlay.href = '#';

    divs[i].appendChild(overlay);

    divs[i].onmouseover = function () {
        this.querySelector('.icon-overlay').style.display = 'block';}
    divs[i].onmouseout = function () {
        this.querySelector('.icon-overlay').style.display = 'none';}
    overlay.onclick = function()  {
        alert("clicked");}
}

Further on, i wanted to get rid of those div declarations in html that are including the imgs and add them dynamically straight from javascript, in order to have the same result as in the first jsfiddle, but the behaviour is weird and i miss something. You can see that here: http://jsfiddle.net/uwrae91p/1/

Any hints?

Zack.

6
  • "the behaviour is weird" — Define "weird" Commented Aug 14, 2014 at 12:44
  • If it in the first example, at hover the icon appears for every image, in the second example when i try to dynamically add the divs, if i hover the third image, the icon appears on the second and if i hover over the first image nothing happens. I've added a border for the .image-thumb class and only the second and third picture have it, and the picture is overlapping a empty div. Commented Aug 14, 2014 at 12:47
  • 1
    Check your browser console: Uncaught HierarchyRequestError: Failed to execute 'appendChild' on 'Node': The new child element contains the parent. Commented Aug 14, 2014 at 12:56
  • 1
    And also: Uncaught TypeError: Cannot read property 'style' of null Commented Aug 14, 2014 at 12:56
  • 2
    And your code is trying to place all the images within a div. Commented Aug 14, 2014 at 13:01

2 Answers 2

1

The problem is that you're using getElementsByTagName() when trying to retrieve the images. This method is a Live NodeList, so any changes to the DOM will reflect immediately.

Like in your first code attempt, you could just use querySelectorAll().

var imgs = document.querySelectorAll('img');

for (var i = 0; i < imgs.length; i++) {
    var div = document.createElement('div')
    div.className = 'image-thumb';

    var overlay = document.createElement('a')
    overlay.className = 'icon-overlay';
    overlay.href = '#';

    div.appendChild(imgs[i]);
    div.appendChild(overlay);
    document.body.appendChild(div);

    div.onmouseover = function () {
        this.querySelector('.icon-overlay').style.display = 'block';
    }
    div.onmouseout = function () {
        this.querySelector('.icon-overlay').style.display = 'none';
    }
    overlay.onclick = function () {
        alert("clicked");
    }
}

Demo

document.querySelectorAll

document.getElementsByTagName

Sign up to request clarification or add additional context in comments.

12 Comments

I've learned a couple of things today. Thank you for your detailed answer!
do you have any idea why the formatting is changed when the js code is called? In the jsfiddle everything works as a charm, but if i create a html with 3 pictures, when the page is loaded, the pictures are displayed horizontally and after the js code is called they are displayed vertically and i can't understand why because if i inject this js code, it ruins the page image formatting.
Some images are contained into links, and some are not. Do you want to keep these links?
The problem is, these images contained into links, will have a link within another link, because you want to add the icon overlay. It would be something like: original link -> injected div -> img -> injected link.
Right... To keep the images inline, I've changed a few bits. Check the comments in this jsFiddle: jsfiddle.net/MelanciaUK/oz5t0p19 You'll need to adjust a bit your CSS, but that's the idea to go from.
|
1
  • You are creating div element outside the loop. That means it is created only one time. You need it multiple times. So put it inside the for loop.
  • Use querySelectorAll() instead of getElementsByTagName().

That's it. All of your code is perfect -- other than these two points.

1 Comment

@ZackKaytranada My pleasure...I am here to answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.