SitePoint Sponsor

User Tag List

Results 1 to 13 of 13
  1. #1
    SitePoint Guru tictike's Avatar
    Join Date
    Apr 2008
    Location
    Canada
    Posts
    863
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    change opacity with eventlisteners

    I saw a similar script on a site before so I thought I would try coding it, however the other person was using taller images and was adjusting the background position of the images on mouseover. I'm changing opacity.

    Anyway, the page here (does not support IE yet) basically works as desired but there are a few issues that I'm not sure how to fix.

    (change html to js in the url to view the .js file)

    1 - in init(), changeOpac(), and changeOpacBack() I'm using the same 2 variables and a for loop looping through the same elements. Is there a way to consolidate this script?

    2 - Also, when mousing over from one image to another (slowly), they flicker.
    I know they flicker because the mouseout and mouseover function are doing their job, but can this be fixed?

    3 - Last, am I using eventListeners the right way?

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,729
    Mentioned
    104 Post(s)
    Tagged
    4 Thread(s)
    If it helps, quirksmode has a cross-browser technique for opacity.
    http://www.quirksmode.org/js/opacity.html
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  3. #3
    SitePoint Evangelist
    Join Date
    Apr 2008
    Location
    Dublin, Ireland
    Posts
    461
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well for starters when you mouseout of an image you only really need to reset that particular image. Looping through them all is not necessary. At least I don't think so. It may be the cause of flickering because when you mouseout you reset all images and almost immediately as you mouseover the next image you are looping through them all again.

    Ideally you could encapsulate this into an object and the object could track which image is currently active with a property then when you mouseover you only need to reset the class of the active image and then set it to the new one the mouse is over and when you mouseout set the active image to null. Less looping around then.

  4. #4
    SitePoint Guru tictike's Avatar
    Join Date
    Apr 2008
    Location
    Canada
    Posts
    863
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi,

    I'm pretty sure I have to loop through them on mouseout because on mouseover I'm changing/setting classes and I need to change all of them back on mouseout. I think.

    I got rid of the flicker by adjusing CSS. Now there is not room in between the images eliminating the chance of a mouseout to occur. seen here.

    Could you please give an example of how I can eliminate or reduce these redundant holder and imgs variables. Or, maybe I can't..

    Code JavaScript:
    function init(){                      
    	var holder = document.getElementById("holder");
    	var imgs = holder.getElementsByTagName("img");
     
    	for(var i = 0; i < imgs.length; i++){
    		imgs[i].addEventListener("mouseover", changeOpac, false);
    		imgs[i].addEventListener("mouseout", changeOpacBack, false);	
    	}
    }
     
    function changeOpac(){
     
    	var holder = document.getElementById("holder");
    	var imgs = holder.getElementsByTagName("img");
     
    	for(var i = 0; i < imgs.length; i++){
    		if(imgs[i].className == "clear" || imgs[i].className == "" || imgs[i].className == null){
    			imgs[i].className = "dark";
    		}
    	}
    	this.className = "clear";
    }
     
    function changeOpacBack(){
    	var holder = document.getElementById("holder");
    	var imgs = holder.getElementsByTagName("img");
     
    	for(var i = 0; i < imgs.length; i++){
    		imgs[i].className = "clear";
    	}
    }

  5. #5
    SitePoint Evangelist
    Join Date
    Apr 2008
    Location
    Dublin, Ireland
    Posts
    461
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It's late here in the land of the Leprechauns. I'll have a look in the morning. Just to say I still think you only need to reset the image in question onmouseout because when you mouseover an image all are set to dark except the one you are over so that when you mouseout there is only currently one image that needs to be set to dark, i.e. the only you are leaving.

  6. #6
    SitePoint Guru tictike's Avatar
    Join Date
    Apr 2008
    Location
    Canada
    Posts
    863
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    ok . yes please have a look in the morning. I'm rather new to js so I can't really dispute what you're saying. But it is working as desired.

    Onmouseover I want the currently hovered image to be at 100&#37; opacity. And all others dark.

    And onmouseout I want all images to be at 100% opacity. So that's why I'm looping through all of them again to get rid of the 'dark' class attribute value that is previously set onmouseover.

  7. #7
    SitePoint Evangelist
    Join Date
    Apr 2008
    Location
    Dublin, Ireland
    Posts
    461
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    o.k. my mistake I thought you wanted them all dark on mouseout.

  8. #8
    SitePoint Evangelist
    Join Date
    Apr 2008
    Location
    Dublin, Ireland
    Posts
    461
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Almost forgot to get back to you on this. One quick suggestion would be to set the imgs as a property of the holder:-

    Code:
    function init(){                      
        var holder = document.getElementById("holder");
        holder.imgs = holder.getElementsByTagName("img");
        
        for(var i = 0; holder.imgs[i]; i++){
            imgs[i].addEventListener("mouseover", changeOpac, false);
            imgs[i].addEventListener("mouseout", changeOpacBack, false);    
        }
    }
    In later code once you get a reference to the holder you can then access the images through holder.imgs instead of using getElementsByTagName again. I've also used the holder.imgs[i] bit in the loop. What this says is keep going until holder.imgs[i] is null (false) instead of calculating the length of the array every time.

  9. #9
    SitePoint Guru tictike's Avatar
    Join Date
    Apr 2008
    Location
    Canada
    Posts
    863
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    If I replace this line:
    var imgs = holder.getElementsByTagName("img");

    for this line:
    holder.imgs = holder.getElementsByTagName("img");

    in the init function, wouldn't I also have to do that in the other two functions?

    Also, could make var holder = document.getElementById("holder"); a global variable so I don't have to declare it 3 times?

    ------------------
    better yet couldn't I declare both of these variables as global variables?

    var holder = document.getElementById("holder");
    holder.imgs = holder.getElementsByTagName("img");
    Last edited by tictike; Sep 24, 2008 at 15:56. Reason: edit

  10. #10
    SitePoint Evangelist
    Join Date
    Apr 2008
    Location
    Dublin, Ireland
    Posts
    461
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I avoid global variables at all costs when writing script. You shouldn't have to re-create a property once you have created it in the init function so the holder.imgs should remain. Ideally this could be done by creating your own object that could have properties etc. but it wouldn't be straightforward.

  11. #11
    SitePoint Guru tictike's Avatar
    Join Date
    Apr 2008
    Location
    Canada
    Posts
    863
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So declaring this variable - holder.imgs = holder.getElementsByTagName("img"); will give me access to holder.imgs in other funcitons?

    Why do you avoid global variables?

  12. #12
    SitePoint Guru tictike's Avatar
    Join Date
    Apr 2008
    Location
    Canada
    Posts
    863
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So declaring this variable - holder.imgs = holder.getElementsByTagName("img"); will give me access to holder.imgs in other funcitons?

    Why do you avoid global variables?

  13. #13
    SitePoint Evangelist
    Join Date
    Apr 2008
    Location
    Dublin, Ireland
    Posts
    461
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yes you are setting this imgs array as a property of the holder. It's a very handy feature of javascript that you can add properties/methods to a dom element on the fly.

    Global variables are just a recipe to messy code that could easily clash with other code - http://yuiblog.com/blog/2006/06/01/global-domination/


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •