SitePoint Sponsor

User Tag List

Results 1 to 4 of 4
  1. #1
    SitePoint Enthusiast
    Join Date
    Nov 2005
    Posts
    26
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Alternative approaches to IE/FF Event Handlers

    Hi,

    I've just inherited a bit of javascript which is supposed to show tooltip-style help boxes on rolling over particular page elements. It works fine in IE but not in FF. The responsibility to fix it now falls to me.

    I've determined that the problem looks to be with the event-handling code. The legacy code uses the "event" (as in event.x, event.y) object of the IE DOM which is, of course, undefined in FF. Here's the offending function (which I've already started modifiying to be less browser dependent):

    Code:
    var tipElement = new Object;
    
    function infoTipOn( ID )
    {
        var screenX
        var screenY
        
         if( navigator.appName.match('Microsoft') != null)
         {
         	screenX = document.body.clientWidth;
            screenY = document.body.clientHeight;
         }
         else
         {
            screenX = window.innerWidth;
            screenY = window.innerHeight;
          }
    
        tipElement = document.getElementById(ID).style;
    
        if( event.x + 300 > screenX )
            tipElement.left = (event.x > 310)? event.x-305: 10;
        else tipElement.left = parseInt( event.x+10 );
       
    
        if( event.y + 200 > screenY )
            tipElement.top = event.y-115;
        else
            tipElement.top = parseInt( event.y+20 );
    
        tipElement.zIndex = "50";
        tipElement.visibility = "visible";
    }
    The problem is that this function is getting called all over the shop - so going through every bit that uses it and adding an "event" argument to the function call is going to take forever and a day, let alone the nightmare that's likely to ensue when I try and deploy it.

    Is there any way I can get this FF friendly by just modifying the above function code and not dipping in to each and every HTML element that calls it?

    Cheers,
    Matt

  2. #2
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,705
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    For a start you can tidy up the following excerpt

    Code Javascript:
    var screenX
    var screenY
     
    if( navigator.appName.match('Microsoft') != null)
    {
        screenX = document.body.clientWidth;
        screenY = document.body.clientHeight;
    }
    else
    {
        screenX = window.innerWidth;
        screenY = window.innerHeight;
    }

    by changing it to the following

    Code Javascript:
    var screenX = self.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
    var screenY = self.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;

    http://www.quirksmode.org/viewport/compatibility.html has a nice article about such issues.

    As far as the rest of the code goes, http://www.quirksmode.org/js/events_properties.html has the answers for you.

    Most other browsers don't store the event as a global object, instead it's passed to the function when you specify no arguments

    Code HTML4Strict:
    <element onclick="infoTipOn()">

    The good news is that you can easily get the event and the element, and from that the other required information.

    Code Javascript:
    function infoTipOn(e) {
        e = e || window.event;
        var targ = e.target || e.srcElement;
        if (targ.nodeType == 3) { // Safari passes text node instead
            targ = targ.parentNode;
        }
        var screenX = self.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
        var screenY = self.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
        var posX = evt.screenX;
        var posY = evt.screenY;

    And then carry on, by replacing document.getElementById(ID) with targ
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript

  3. #3
    SitePoint Enthusiast
    Join Date
    Nov 2005
    Posts
    26
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by pmw57 View Post
    And then carry on, by replacing document.getElementById(ID) with targ
    That was interesting and helpful. Thanks for the information!

    Unfortunately it isn't going to save me modifying a bunch of code because the functions are being called with an argument. So, if I've understood correctly, to do it your way I still need to go through all the function calls everywhere in the site and remove the argument.

    Unless I've misunderstood or someone has a workaround?

  4. #4
    Unobtrusively zen silver trophybronze trophy
    paul_wilkins's Avatar
    Join Date
    Jan 2007
    Location
    Christchurch, New Zealand
    Posts
    14,705
    Mentioned
    101 Post(s)
    Tagged
    4 Thread(s)
    Internet Explorer is one of the few browsers with a global event system.
    Most other browsers require the event to be passed to the function.

    There may be other ways to simulate a global event situation, with something like

    Code Javascript:
    document.onmousemove = function(evt) {
    	window.event = window.event || evt;
    }

    But I wouldn't want to use such a solution.
    Not only will it negatively impact the performance of every browser on youe Web page, but it will create a maintenance nightmare for the code that uses it.

    I'm in the middle of upgrading IE, so haven't checked to see if it blows up on there yet.
    Programming Group Advisor
    Reference: JavaScript, Quirksmode Validate: HTML Validation, JSLint
    Car is to Carpet as Java is to JavaScript


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
  •