Wrox Programmer Forums
Go Back   Wrox Programmer Forums > Web Programming > JavaScript > Javascript
|
Javascript General Javascript discussions.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the Javascript section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
 
Old April 30th, 2009, 12:10 PM
Authorized User
 
Join Date: Jul 2007
Posts: 14
Thanks: 2
Thanked 0 Times in 0 Posts
Default Three state button doesn't work...

Hi Guys,

I'm trying to get my website http://www.apps-limited.co.uk to have working 3 state mouse buttons which are selectable by tab, accesskeys, etc...

For some reason the 3rd state shows fine in Safari (3.22), not at all in IE(All - IE Tester) or FF(3.0.5), and god only knows what's happening in Opera (9.63)

The script is called rollover.js and is an edited version of a Lynda.com script:

Code:
function rolloverInit() {
        for (var i=0; i<document.images.length; i++) {
            if (document.images[i].parentNode.parentNode.parentNode.parentNode.id == "nav-menu"){
                    setupRollover(document.images[i]);
            }
        }
    }

function setupRollover(thisImage) {
    thisImage.outImage = new Image();
    thisImage.outImage.src = thisImage.src;
    thisImage.onmouseout = rollOut;

    thisImage.overImage = new Image();
    thisImage.overImage.src = "images/" + thisImage.id + "_on.jpg";
    thisImage.onmouseover = rollOver;

    thisImage.clickImage = new Image();
    thisImage.clickImage.src = "images/" + thisImage.id + "_click.jpg";
    thisImage.onmousedown = rollClick;    

    thisImage.parentNode.childImg = thisImage;
    thisImage.parentNode.onblur = rollOutChild;
    thisImage.parentNode.onfocus = rollOverChild;
}

function rollOut() {
    this.src = this.outImage.src;
}

function rollOver() {
    this.src = this.overImage.src;
    return false;
}

function rollClick() {
    this.src = this.clickImage.src;
}

function rollOutChild() {
    this.childImg.src = this.childImg.outImage.src;
}

function rollOverChild() {
    this.childImg.src = this.childImg.overImage.src;
}

window.onload = rolloverInit;
Can anyone help?

Thanks in advance


Jim

PS I posted this on sitepoint and got very little response (no slight on sitepoint there...they're very nice people). The only response I got was this:

Quote:
The focus event follows click, so the click image is overwritten. It's better to apply all event handlers to the link, and assign the same handler to mouseover and focus. The same for mouseout and blur.
Is this true: I didn't think the element would gain focus until it was moused-over again?
 
Old April 30th, 2009, 02:18 PM
Friend of Wrox
 
Join Date: Jun 2008
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
Default

I am MORE than a little suspicious of THIS code:
Code:
    thisImage.parentNode.childImg = thisImage;
    thisImage.parentNode.onblur = rollOutChild;
    thisImage.parentNode.onfocus = rollOverChild;
How do you *know* that thisImage.parentNode is indeed the node you want to use???

It's quite possible that a given browser might have another "layer" of object(s) in between the image and the object where you *really* want to apply those events.

When I write code like this, I always check the type of the object as I traverse "up" the node tree and keep going until I get one of the type I need.

No idea, at all, if that is the problem in this case, as you are showing only the JS code and none of the relevant HTML. But at a minimum you might try doing:
Code:
    var theParent = thisImage.parentNode;
    alert( "DEBUG: theParent contains " + theParent.innerHTML );
    theParent.childImg = thisImage; // this also might not be legit in all browsers
    theParent.onblur = rollOutChild;
    theParent.onfocus = rollOverChild;
You maybe can't just create a new attribute on an object in some browsers using the code as you have. You might need to use setAttribute.

Just guessing. Show me some relevant HTML and I'd play with it more.
 
Old April 30th, 2009, 03:23 PM
Authorized User
 
Join Date: Jul 2007
Posts: 14
Thanks: 2
Thanked 0 Times in 0 Posts
Default

Hi Old Pedant,

Thanks for your reply...

Here's the homepage html:

HTML Code:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <meta name="description" content="With over 16 years experience of bringing tangible results in both the public and private
         sector APPS brings the enhancement of organisational psychology to your workplace, making a positive visible difference to
         your working environment and to your bottom line!" />
         
        <meta name="keywords" content="Organisational, psychology, bullying, harrassment, mediation, sickness, absence," />
        <meta name="author" content="James Sherry" />
    
        <title>APPS Home</title>

    
        <link rel="stylesheet" type="text/css"  href="css/stylesheet.css" />
        <!--[if lt IE 7]><link rel="stylesheet" type="text/css"  href="css/ie.css" /><![endif]-->
        <link rel="shortcut icon" href="Images/favicon.ico" />
        <script src="rollover.js" type="text/JavaScript" ></script>

        
    </head>

    <body>

    <h1 class="hidden"><abbr title="Achieve Positive People Solutions">APPS</abbr>DotCoDotUk</h1>

        <div id="logo"> <!--This div holds the main logo-->

        <a href="index.html" tabindex="-1"><img src="images/logo.jpg" alt="APPS Logo" /></a></div>
 
        <div id="header"><!--This div holds the title text and horizontal separator together as a flattened image.-->
            <a href="index.html" tabindex="-1">
            <img src="Images/horizsep2.jpg" alt="Achieve Positive People Solutions (APPS) Ltd." />
            </a>
           </div>
         
        <div id="nav-menu"><!--This div contains the naviagation menu. The menu is operated by rollover.js-->
        
            <ul>
            
                <li class="hidden"><a href="#content" tabindex="0">Skip to Main Content</a>
                <!--Accessibility skip navigation function--></li>
                <li id="home_button"><a href="index.html" tabindex="1" accesskey="h">
                    <img src="images/home.jpg" id="home" alt="Home Button" /></a></li>
                    
                <li id="services_button"><a href="services.html" tabindex="2" accesskey="s">
                    <img src="images/services.jpg" id="services" alt="Services Button" /></a></li>
                    
                <li id="reviews_button"><a href="reviews.html" tabindex="3" accesskey="r">
                    <img src="images/reviews.jpg" id="reviews" alt="Reviews Button" /></a></li>
                    
                  <li id="contact_button"><a href="contact.html" tabindex="4" accesskey="c">
                         <img src="images/contact.jpg" id="contact" alt="Contact Button" /></a></li>

            </ul>
        </div>
    
        <div id ="contenthome" class="content" ><!--This div holds the main content of the page. -->
    
        <h1>A specialist approach</h1>
        <p>Achieve Positive People Solutions does exactly that!  This company is headed by 
        
        <a href="http://www.cityspeakersinternational.co.uk/speakers/speaker_mary_sherry.php?PHPSESSID=7gptoq1d4di5ksv057udur8vv6" 
         tabindex="5" onclick="return ! window.open(this.href);">Mary Sherry</a>, an Organisational Psychologist with fifteen 
         years practical experience working with managers and staff in both the public and private sector. </p>

        <p><abbr title="Achieve Positive People Solutions">APPS</abbr> tackles issues within your company, working with
         <abbr title="Human Resources">HR</abbr> and <abbr title="Occupational Health Unit">O.H.U.</abbr>, using a unique 
         one-on-one approach.</p>

         
        <p>Our results include:</p>
            <ul>
              <li>The removal of workplace tensions</li>
              <li>The reduction of sickness and absences</li>
              <li>Effective handling of bullying and harrasment allegations</li>
              <li>Increased management capability and confidence</li>
            </ul>

               
        <p>...which makes for the most important result of all:</p>
             
        <p class="strapline">A positive difference to your bottom line...</p>

        
        </div>
        
        <!--Google Analytics-->
            <script type="text/javascript">
            var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
            document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
            </script>
            <script type="text/javascript">
            try {
            var pageTracker = _gat._getTracker("UA-7998993-1");
            pageTracker._trackPageview();
            } catch(err) {}</script>        
    </body>
</html>
The onmouseover state works. For some reason the onclick state shows fine in Safari (3.22), not at all in IE(All - IE Tester) or FF(3.0.5), and god only knows what's happening in Opera (9.63)

The onblur and onfocus states work too...

Good tip about the error catch: The parentnode's innerhtml is the img, however...so no cigar there. :S
 
Old April 30th, 2009, 04:04 PM
Authorized User
 
Join Date: Jul 2007
Posts: 14
Thanks: 2
Thanked 0 Times in 0 Posts
Default SOLVED

OK So I solved it by accident when applying Old Pedant's debug...

Old Code...
Code:
function rolloverInit() {
        for (var i=0; i<document.images.length; i++) {
            if (document.images[i].parentNode.parentNode.parentNode.parentNode.id == "nav-menu"){
                    setupRollover(document.images[i]);
            }
        }
    }

function setupRollover(thisImage) {
    thisImage.outImage = new Image();
    thisImage.outImage.src = thisImage.src;
    thisImage.onmouseout = rollOut;

    thisImage.overImage = new Image();
    thisImage.overImage.src = "images/" + thisImage.id + "_on.jpg";
    thisImage.onmouseover = rollOver;

    thisImage.clickImage = new Image();
    thisImage.clickImage.src = "images/" + thisImage.id + "_click.jpg";
    thisImage.onmousedown = rollClick;    

    thisImage.parentNode.childImg = thisImage;
    thisImage.parentNode.onblur = rollOutChild;
    thisImage.parentNode.onfocus = rollOverChild;
}

function rollOut() {
    this.src = this.outImage.src;
}

function rollOver() {
    this.src = this.overImage.src;
    return false;
}

function rollClick() {
    this.src = this.clickImage.src;
}

function rollOutChild() {
    this.childImg.src = this.childImg.outImage.src;
}

function rollOverChild() {
    this.childImg.src = this.childImg.overImage.src;
}

window.onload = rolloverInit;
New Code...

Code:
function rolloverInit() {
        for (var i=0; i<document.images.length; i++) {
            if (document.images[i].parentNode.parentNode.parentNode.parentNode.id == "nav-menu"){
                    setupRollover(document.images[i]);
            }
        }
    }

function setupRollover(thisImage) {
    thisImage.outImage = new Image();
    thisImage.outImage.src = thisImage.src;
    thisImage.onmouseout = rollOut;

    thisImage.overImage = new Image();
    thisImage.overImage.src = "images/" + thisImage.id + "_on.jpg";
    thisImage.onmouseover = rollOver;

    thisImage.clickImage = new Image();
    thisImage.clickImage.src = "images/" + thisImage.id + "_click.jpg";
    thisImage.onmousedown = rollClick;    

    var theParent = thisImage.parentNode;
    theParent.childImg = thisImage; // this also might not be legit in all browsers
    theParent.onblur = rollOutChild;
    theParent.onfocus = rollOverChild;
    theParent.onkeydown = tabClickChild;
}

function rollOut() {
    this.src = this.outImage.src;
    return false;
}

function rollOver() {
    this.src = this.overImage.src;
    return false;
}

function rollClick() {
    this.src = this.clickImage.src;
    return false;
}

function rollOutChild() {
    this.childImg.src = this.childImg.outImage.src;
    return false;
}

function rollOverChild() {
    this.childImg.src = this.childImg.overImage.src;
    return false;
}

function tabClickChild() {
    this.childImg.src = this.childImg.clickImage.src;
    return false;
}

window.onload = rolloverInit;
Primarily, the change was to take:

Code:
    thisImage.parentNode.childImg = thisImage;
    thisImage.parentNode.onblur = rollOutChild;
    thisImage.parentNode.onfocus = rollOverChild;
(well done Old Pedant for spotting the problem area!!)

and replacing it with:

Code:
    var theParent = thisImage.parentNode;
    theParent.childImg = thisImage; // this also might not be legit in all browsers
    theParent.onblur = rollOutChild;
    theParent.onfocus = rollOverChild;
    theParent.onkeydown = tabClickChild;
This is why javascript makes me scratch my head sometimes...

Why is:

Code:
thisImage.parentNode.childImg = thisImage;
different from

Code:
theParent.childImg = thisImage;
Code:
(thisImage.parentNode).childImg = thisImage;
THEY ARE SURELY THE SAME...

Can anyone tell me why they are different?

Thanks again to Old Pedant, you're a hero! :)
 
Old April 30th, 2009, 10:45 PM
Friend of Wrox
 
Join Date: Jun 2007
Posts: 477
Thanks: 10
Thanked 19 Times in 18 Posts
Default

I can't answer the question, but I can cite a similar example. I do some back end work as well and one of the database books I was reading showed 7 different syntaxes in C# for calling data from a database. Every one was syntactically equivalent and pulled the exact same data set from the database, but no two returned results in exactly the same amount of time. The slowest syntax was x100 slower than the fastest.

So while I agree they're equivalent, that doesn't mean they're doing things the same way behind the scenes. Clearly something is different when the client computer or the server get down to crunching machine language. I don't know why, but you gradually get familiar with what works, what doesn't, and learn to live with it. ;)
__________________
-------------------------

Whatever you can do or dream you can, begin it. Boldness has genius, power and magic in it. Begin it now.
-Johann von Goethe

When Two Hearts Race... Both Win.
-Dove Chocolate Wrapper

Chroniclemaster1, Founder of www.EarthChronicle.com
A Growing History of our Planet, by our Planet, for our Planet.

Last edited by chroniclemaster1; April 30th, 2009 at 10:47 PM..
The Following User Says Thank You to chroniclemaster1 For This Useful Post:
jmsherry (May 1st, 2009)
 
Old May 1st, 2009, 05:20 AM
Friend of Wrox
 
Join Date: Jun 2008
Posts: 1,649
Thanks: 3
Thanked 141 Times in 140 Posts
Default

Well, you *DID* make one significant change. You added the onkeydown event.

No idea if that was relevant to the problem, but...
The Following User Says Thank You to Old Pedant For This Useful Post:
jmsherry (May 1st, 2009)
 
Old May 1st, 2009, 10:53 AM
Authorized User
 
Join Date: Jul 2007
Posts: 14
Thanks: 2
Thanked 0 Times in 0 Posts
Default

@Old Pedant

lol! No, that then caused a problem, because now if you press 'return' to activate the link and you're on the same page it then stays there and you can't do anything else...going to edit that now to make that condition impossible.

I was doing what I like to call 'Mozart Coding', where you get so cocky you just start coding like you're playing the minuet! It usually goes well, then the wheels fall off - I've got *some* way to go before I'm any good at JS, I feel... :)

Thanks again...

@chroniclemaster1...

Thanks for that: How very bizarre?! I feel it'll take a while until I get that level of intuition. as I said above. I guess it all depends on your frame of reference and level of experience.

My mother thought her CD drive came without an open button; she regularly tries to edit the title bar of certain windows, and; 'Doesn't believe in saving' (she just prints a hard copy and then presses buttons until the 'warnings go away'! - Hmmm, after 13 years, I wonder why her puter is SO SLOW!!): It's all about experience! :)
 
Old May 19th, 2009, 02:24 PM
Friend of Wrox
 
Join Date: Jun 2007
Posts: 477
Thanks: 10
Thanked 19 Times in 18 Posts
Default

Quote:
Originally Posted by jmsherry View Post
@chroniclemaster1...

Thanks for that: How very bizarre?! I feel it'll take a while until I get that level of intuition. as I said above. I guess it all depends on your frame of reference and level of experience.
:) That's really the trick, it's all about patience. You start by trying something new and little by little piece by piece you reshape it: ie it doesn't do this so you tweak it until it does... it DOES do that so you tweak it until it doesn't. That's one of the reasons I comment extensively because it may be months in between when you get a chance to work on something if there are higher priority issues that come up. Gradually you get familiar with what works for you and your code preserves the memory of that.
__________________
-------------------------

Whatever you can do or dream you can, begin it. Boldness has genius, power and magic in it. Begin it now.
-Johann von Goethe

When Two Hearts Race... Both Win.
-Dove Chocolate Wrapper

Chroniclemaster1, Founder of www.EarthChronicle.com
A Growing History of our Planet, by our Planet, for our Planet.





Similar Threads
Thread Thread Starter Forum Replies Last Post
movie in the over state of a button Adam H-W Flash (all versions) 0 December 6th, 2005 12:14 PM
Toggle active state of textbox with a radio button Hatchingabrain Javascript How-To 2 April 4th, 2005 07:13 AM
Toggle active state of text area with radio button Hatchingabrain Javascript 2 April 4th, 2005 04:03 AM
Refresh Button and View State Sunil Sabir General .NET 3 August 16th, 2004 02:40 PM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.