There must be an easier way...



  • I know hardly any javascript, but when I found this on a site tonight I thought that there must be an easier way to determine if someone is using a client as recent as IE5 or not:

     // Ultimate client-side JavaScript client sniff.
    // (C) Netscape Communications 1999.  Permission granted to reuse and distribute.
    // Revised 17 May 99 to add is_nav5up and is_ie5up (see below).
    // Everything you always wanted to know about your JavaScript client
    // but were afraid to ask. Creates "is_" variables indicating:
    // (1) browser vendor:
    //     is_nav, is_ie, is_opera
    // (2) browser version number:
    //     is_major (integer indicating major version number: 2, 3, 4 ...)
    //     is_minor (float   indicating full  version number: 2.02, 3.01, 4.04 ...)
    // (3) browser vendor AND major version number
    //     is_nav2, is_nav3, is_nav4, is_nav4up, is_nav5, is_nav5up, is_ie3, is_ie4, is_ie4up
    // (4) JavaScript version number:
    //     is_js (float indicating full JavaScript version number: 1, 1.1, 1.2 ...)
    // (5) OS platform and version:
    //     is_win, is_win16, is_win32, is_win31, is_win95, is_winnt, is_win98
    //     is_os2
    //     is_mac, is_mac68k, is_macppc
    //     is_unix
    //        is_sun, is_sun4, is_sun5, is_suni86
    //        is_irix, is_irix5, is_irix6
    //        is_hpux, is_hpux9, is_hpux10
    //        is_aix, is_aix1, is_aix2, is_aix3, is_aix4
    //        is_linux, is_sco, is_unixware, is_mpras, is_reliant
    //        is_dec, is_sinix, is_freebsd, is_bsd
    //     is_vms
    //
    // See http://www.it97.de/JavaScript/JS_tutorial/bstat/navobj.html and
    // http://www.it97.de/JavaScript/JS_tutorial/bstat/Browseraol.html
    // for detailed lists of userAgent strings.
    //
    // Note: you don't want your Nav4 or IE4 code to "turn off" or
    // stop working when Nav5 and IE5 (or later) are released, so
    // in conditional code forks, use is_nav4up ("Nav4 or greater")
    // and is_ie4up ("IE4 or greater") instead of is_nav4 or is_ie4
    // to check version in code which you want to work on future
    // versions.
     
        // convert all characters to lowercase to simplify testing
        var agt=navigator.userAgent.toLowerCase();
     
        // *** BROWSER VERSION ***
        // Note: On IE5, these return 4, so use is_ie5up to detect IE5.
        var is_major = parseInt(navigator.appVersion);
        var is_minor = parseFloat(navigator.appVersion);
     
        // Note: Opera and WebTV spoof Navigator.  We do strict client detection.
        // If you want to allow spoofing, take out the tests for opera and webtv.
        var is_nav  = ((agt.indexOf('mozilla')!=-1) && (agt.indexOf('spoofer')==-1)
                    && (agt.indexOf('compatible') == -1) && (agt.indexOf('opera')==-1)
                    && (agt.indexOf('webtv')==-1));
        var is_nav2 = (is_nav && (is_major == 2));
        var is_nav3 = (is_nav && (is_major == 3));
        var is_nav4 = (is_nav && (is_major == 4));
        var is_nav4up = (is_nav && (is_major >= 4));
        var is_navonly      = (is_nav && ((agt.indexOf(";nav") != -1) ||
                              (agt.indexOf("; nav") != -1)) );
        var is_nav5 = (is_nav && (is_major == 5));
        var is_nav5up = (is_nav && (is_major >= 5));
     
        var is_ie   = (agt.indexOf("msie") != -1);
        var is_ie3  = (is_ie && (is_major < 4));
        var is_ie4  = (is_ie && (is_major == 4) && (agt.indexOf("msie 4")!=-1) );
        var is_ie4up  = (is_ie  && (is_major >= 4));
        var is_ie5  = (is_ie && (is_major == 4) && (agt.indexOf("msie 5.0")!=-1) );
        var is_ie5up  = (is_ie  && !is_ie3 && !is_ie4);
     
        // KNOWN BUG: On AOL4, returns false if IE3 is embedded browser
        // or if this is the first browser window opened.  Thus the
        // variables is_aol, is_aol3, and is_aol4 aren't 100% reliable.
        var is_aol   = (agt.indexOf("aol") != -1);
        var is_aol3  = (is_aol && is_ie3);
        var is_aol4  = (is_aol && is_ie4);
     
        var is_opera = (agt.indexOf("opera") != -1);
        var is_webtv = (agt.indexOf("webtv") != -1);
     
      var is_blackberry = (agt.indexOf("blackberry") != -1);
     
        // *** JAVASCRIPT VERSION CHECK ***
        var is_js;
        if (is_nav2 || is_ie3) is_js = 1.0
        else if (is_nav3 || is_opera) is_js = 1.1
        else if ((is_nav4 && (is_minor <= 4.05)) || is_ie4) is_js = 1.2
        else if ((is_nav4 && (is_minor > 4.05)) || is_ie5) is_js = 1.3
        else if (is_nav5) is_js = 1.4
        // NOTE: In the future, update this code when newer versions of JS
        // are released. For now, we try to provide some upward compatibility
        // so that future versions of Nav and IE will show they are at
        // *least* JS 1.x capable. Always check for JS version compatibility
        // with > or >=.
        else if (is_nav && (is_major > 5)) is_js = 1.4
        else if (is_ie && (is_major > 5)) is_js = 1.3
        // HACK: no idea for other browsers; always check for JS version with > or >=
        else is_js = 0.0;
     
        // *** PLATFORM ***
        var is_win   = ( (agt.indexOf("win")!=-1) || (agt.indexOf("16bit")!=-1) );
        // NOTE: On Opera 3.0, the userAgent string includes "Windows 95/NT4" on all
        //        Win32, so you can't distinguish between Win95 and WinNT.
        var is_win95 = ((agt.indexOf("win95")!=-1) || (agt.indexOf("windows 95")!=-1));
     
        // is this a 16 bit compiled version?
        var is_win16 = ((agt.indexOf("win16")!=-1) ||
                   (agt.indexOf("16bit")!=-1) || (agt.indexOf("windows 3.1")!=-1) ||
                   (agt.indexOf("windows 16-bit")!=-1) ); 
     
        var is_win31 = ((agt.indexOf("windows 3.1")!=-1) || (agt.indexOf("win16")!=-1) ||
                        (agt.indexOf("windows 16-bit")!=-1));
     
        // NOTE: Reliable detection of Win98 may not be possible. It appears that:
        //       - On Nav 4.x and before you'll get plain "Windows" in userAgent.
        //       - On Mercury client, the 32-bit version will return "Win98", but
        //         the 16-bit version running on Win98 will still return "Win95".
        var is_win98 = ((agt.indexOf("win98")!=-1) || (agt.indexOf("windows 98")!=-1));
        var is_winnt = ((agt.indexOf("winnt")!=-1) || (agt.indexOf("windows nt")!=-1));
        var is_win32 = (is_win95 || is_winnt || is_win98 ||
                        ((is_major >= 4) && (navigator.platform == "Win32")) ||
                        (agt.indexOf("win32")!=-1) || (agt.indexOf("32bit")!=-1));
     
        var is_os2   = ((agt.indexOf("os/2")!=-1) ||
                        (navigator.appVersion.indexOf("OS/2")!=-1) ||  
                        (agt.indexOf("ibm-webexplorer")!=-1));
     
        var is_mac    = (agt.indexOf("mac")!=-1);
        var is_mac68k = (is_mac && ((agt.indexOf("68k")!=-1) ||
                                   (agt.indexOf("68000")!=-1)));
        var is_macppc = (is_mac && ((agt.indexOf("ppc")!=-1) ||
                                    (agt.indexOf("powerpc")!=-1)));
     
        var is_sun   = (agt.indexOf("sunos")!=-1);
        var is_sun4  = (agt.indexOf("sunos 4")!=-1);
        var is_sun5  = (agt.indexOf("sunos 5")!=-1);
        var is_suni86= (is_sun && (agt.indexOf("i86")!=-1));
        var is_irix  = (agt.indexOf("irix") !=-1);    // SGI
        var is_irix5 = (agt.indexOf("irix 5") !=-1);
        var is_irix6 = ((agt.indexOf("irix 6") !=-1) || (agt.indexOf("irix6") !=-1));
        var is_hpux  = (agt.indexOf("hp-ux")!=-1);
        var is_hpux9 = (is_hpux && (agt.indexOf("09.")!=-1));
        var is_hpux10= (is_hpux && (agt.indexOf("10.")!=-1));
        var is_aix   = (agt.indexOf("aix") !=-1);      // IBM
        var is_aix1  = (agt.indexOf("aix 1") !=-1);   
        var is_aix2  = (agt.indexOf("aix 2") !=-1);   
        var is_aix3  = (agt.indexOf("aix 3") !=-1);   
        var is_aix4  = (agt.indexOf("aix 4") !=-1);   
        var is_linux = (agt.indexOf("inux")!=-1);
        var is_sco   = (agt.indexOf("sco")!=-1) || (agt.indexOf("unix_sv")!=-1);
        var is_unixware = (agt.indexOf("unix_system_v")!=-1);
        var is_mpras    = (agt.indexOf("ncr")!=-1);
        var is_reliant  = (agt.indexOf("reliantunix")!=-1);
        var is_dec   = ((agt.indexOf("dec")!=-1) || (agt.indexOf("osf1")!=-1) ||
               (agt.indexOf("dec_alpha")!=-1) || (agt.indexOf("alphaserver")!=-1) ||
               (agt.indexOf("ultrix")!=-1) || (agt.indexOf("alphastation")!=-1));
        var is_sinix = (agt.indexOf("sinix")!=-1);
        var is_freebsd = (agt.indexOf("freebsd")!=-1);
        var is_bsd = (agt.indexOf("bsd")!=-1);
        var is_unix  = ((agt.indexOf("x11")!=-1) || is_sun || is_irix || is_hpux ||
                     is_sco ||is_unixware || is_mpras || is_reliant ||
                     is_dec || is_sinix || is_aix || is_linux || is_bsd || is_freebsd);
     
        var is_vms   = ((agt.indexOf("vax")!=-1) || (agt.indexOf("openvms")!=-1));
       
        var is_winmobile   = (agt.indexOf("Windows CE")!=-1);



  • Unfortunately, I don't think so.

     Web technology is so wonderful.  All the browsers are compliant with all the standards (even the stupid ones), and all the user agent data can be trusted without question.



  • This has been the extent of my browser-checking in the past 6 years:

    if (/MSIE \d/.test(navigator.userAgent)) { }

    where \d is a number of my choosing; usually  6 or 7.



  • This is the easier way:

    if ( navigator.appName.substr( 0, 9 ) == "Microsoft" )
    {
        window.alert( "Get yourself a decent browser!" );
        Abort();
    }

     





  • @AndyCanfield said:

    if ( navigator.appName.substr( 0, 9 ) == "Microsoft" )
    {
        window.alert( "Get yourself a decent browser!" );
        Abort();
    }
    I'd like to see your definition of <font face="courier new,courier">Abort()</font>. Does it envolve <font face="courier new,courier">while(true){ window.close() ;</font>} ?



  • @Zecc said:

    @AndyCanfield said:

    if ( navigator.appName.substr( 0, 9 ) == "Microsoft" )
    {
        window.alert( "Get yourself a decent browser!" );
        Abort();
    }
    I'd like to see your definition of <font face="courier new,courier">Abort()</font>. Does it envolve <font face="courier new,courier">while(true){ window.close() ;</font>} ?



    while (fetus.hit_points > 0) {
        vacuum();
    }


    I am so going to hell...



  • @morbiuswilters said:

    I am so going to hell...
    We knew that already.



  • @Nelle said:

    i like this

    http://www.ie6nomore.com/

    While I understand and mostly agree with the sentiment, nobody will be swayed by that website. If you look at the list of web developers who support the site, it's entirely small web design shops. Oh look! Some random photographer doesn't think I should use IE6! Wow, that really changed my mind!

    Unfortunately, unless you're a huge company that has something that most web users want to see, you don't get to choose which browsers to support. You pretty much have to support the ones your customers use. If IE6 represents a small enough portion of your income that you can justify losing it, then you'll probably just do it without a second thought. I really don't see the need for a website, though.



  • @morbiuswilters said:

    I am so going to hell...
     

    That's probably an extra year or two in purgatory just for LOLing. Thanks a lot, morbs.



  • @morbiuswilters said:

    while (fetus.hit_points > 0) {
        vacuum();
    }
     

    #ifndef ABORTION_CLINIC
    #define vacuum coat_hanger
    #endif
    

    @morbiuswilters said:


    I am so going to hell...
    You're supposed to hide your shame and remorse in the tags, you fool!



  • @DescentJS said:

    Unfortunately, I don't think so.

     Web technology is so wonderful.  All the browsers are compliant with all the standards (even the stupid ones), and all the user agent data can be trusted without question.

     

    Yah that's what the shrill "follow the standards!!!" people usually miss: the standards are crap.

    I actually agree with IE in nearly every way that IE deviates from the standards:

    * innerText makes more sense than textContent (especially when pair with its buddy innerHTML)

    * the Event object approach allows you to process events even when the handler is included in the static HTML

    * document.readyState allows you to build a Javascript that needs to make DOM changes, but doesn't know whether or not the "Load" event has already occurred

    * the way IE handles mouse buttons in a mouse-related event is far superior to the DOM method. Apparently the W3C wasn't aware that you could hold 2 mouse buttons down simultaneously

    Anyway.



  • @bstorer said:

    @morbiuswilters said:

    while (fetus.hit_points > 0) {
        vacuum();
    }
     

    #ifndef ABORTION_CLINIC
    #define vacuum coat_hanger
    #endif
    

    Careful with that: coat_hanger causes a slow leak that eventually results in a segmentation fault.  It's suggested you immediately replace it with a call to the push_down_stairs method on the girlfriend (or mistress) object.



  • @morbiuswilters said:

    @bstorer said:

    @morbiuswilters said:

    while (fetus.hit_points > 0) {
        vacuum();
    }
     

    #ifndef ABORTION_CLINIC
    #define vacuum coat_hanger
    #endif
    

    Careful with that: coat_hanger causes a slow leak that eventually results in a segmentation fault.  It's suggested you immediately replace it with a call to the push_down_stairs method on the girlfriend (or mistress) object.

    Have you read the documentation?  push_down_stairs is just a heuristic; it's not guaranteed to be successful.  This is a mission-critical application.  I can't take that chance.


  • @bstorer said:

    @morbiuswilters said:

    @bstorer said:

    @morbiuswilters said:

    while (fetus.hit_points > 0) {
        vacuum();
    }
     

    #ifndef ABORTION_CLINIC
    #define vacuum coat_hanger
    #endif
    

    Careful with that: coat_hanger causes a slow leak that eventually results in a segmentation fault.  It's suggested you immediately replace it with a call to the push_down_stairs method on the girlfriend (or mistress) object.

    Have you read the documentation?  push_down_stairs is just a heuristic; it's not guaranteed to be successful.  This is a mission-critical application.  I can't take that chance.
     

     

    Y'all are the TWTF.  How can you even joke about wasting test subjects like that? 



  • @aesis said:

    @bstorer said:

    @morbiuswilters said:

    @bstorer said:

    @morbiuswilters said:

    while (fetus.hit_points > 0) {
        vacuum();
    }
     

    #ifndef ABORTION_CLINIC
    #define vacuum coat_hanger
    #endif
    

    Careful with that: coat_hanger causes a slow leak that eventually results in a segmentation fault.  It's suggested you immediately replace it with a call to the push_down_stairs method on the girlfriend (or mistress) object.

    Have you read the documentation?  push_down_stairs is just a heuristic; it's not guaranteed to be successful.  This is a mission-critical application.  I can't take that chance.
     

     

    Y'all are the TWTF.  How can you even joke about wasting test subjects like that? 

    Because otherwise they run the risk of growing up into people who say "y'all".


  • @blakeyrat said:

    innerText makes more sense than textContent (especially when pair with its buddy innerHTML)

    TextContent is in line with text nodes and the general node based concept of a DOM tree. InnerText and InnerHTML are not and in fact represent the concept of serializing (read from the property) and deserializing (write to the property) a subtree of the DOM tree. The DOM standard actually dictates other methods to explicitly achieve (de)serialization of subtrees.

    @blakeyrat said:

    the Event object approach allows you to process events even when the handler is included in the static HTML

    Disregarding for a moment that you shouldn't add events directly to the static html, there is still the fact that something like

    <a onclick='function(e){ e.preventDefault(); }'>Click me to do nothing</a>
    should work fine in standards compliant browsers.

    @blakeyrat said:

    document.readyState allows you to build a Javascript that needs to make DOM changes, but doesn't know whether or not the "Load" event has already occurred

    Except that readyState is broken. Read Dean Edwards reports on it not being reliable. What's wrong with simply attaching an event handler to the load (or DOMContentLoaded, if your browser supports it) event and setting a boolean 'loaded' to true should you require the document state during further execution of scripts?

    @blakeyrat said:

    the way IE handles mouse buttons in a mouse-related event is far superior to the DOM method. Apparently the W3C wasn't aware that you could hold 2 mouse buttons down simultaneously.

    Apparantly you weren't aware that mouseup and mousedown events exist and fire for each mouse button you press or release, even if pressed simultaneously. You can track pressed buttons with some simple boolean switches again. Moreover, the standards compliant DOM method of handling mouse buttons allows for many more than three buttons by using an unsigned short integer. Many more buttons such as found on pointing devices other than your vanilla three-button mouse...



  • ]I'd like to see your definition of Abort().

    There is no definition of Abort. That's why JavaScript stops. Halt execution, but don't close the window. Legitimately used only in debugging situations where continued processing is pointless.There's probably some throw("Kill me please") variation I could use instead.  Still, nothing you want the user to see.



  • @Ragnax said:

    TextContent is in line with text nodes and the general node based concept of a DOM tree. InnerText and InnerHTML are not and in fact represent the concept of serializing (read from the property) and deserializing (write to the property) a subtree of the DOM tree. The DOM standard actually dictates other methods to explicitly achieve (de)serialization of subtrees.
     

    Yes, but "innerHTML" is part of the DOM. So somewhere, someone got their wires crossed. In any case, who the hell cares whether it explicitly or implicitly achieves yada of yada, I just want to grab the text (or HTML) out of the damned thing.

    @Ragnax said:

    Disregarding for a moment that you shouldn't add events directly to the static html, there is still the fact that something like

    <a onclick='function(e){ e.preventDefault(); }'>Click me to do nothing</a>
    should work fine in standards compliant browsers.

    Possibly; but it doesn't work in Firefox. And, when I was trying to do this about 6 months ago, I seem to recall there was no way of getting this to work in Firefox.

     @Ragnax said:

    Except that readyState is broken. Read Dean Edwards reports on it not being reliable. What's wrong with simply attaching an event handler to the load (or DOMContentLoaded, if your browser supports it) event and setting a boolean 'loaded' to true should you require the document state during further execution of scripts?

    Fine; then the W3C should put a non-broken version of this extremely helpful property into the standard.

    The script I encountered this with was designed to run either as a bookmarklet (rather, a bookmarklet including it on the page), included from a double-redirect-type analytics tag, or being called from the page. Note that in the first case, it can (virtually) guarantee that the DOM is ready. In the second case, the DOM may or may not be ready, depending on the configuration of that specific analytics tag. So while your idea of setting a boolean first in the bookmarklet, then writing the script tag to the page, will work in the first case, there's no way to get the script to universally work in the second case.

     @Ragnax said:

    Apparantly you weren't aware that mouseup and mousedown events exist and fire for each mouse button you press or release, even if pressed simultaneously.

     Yah, which makes detecting chording a huge pain in the ass. It's definitely possible, true, and I'd even go as far as saying that web pages shouldn't even be doing it for usability reasons. But if you're going to write the spec, you might as well make the spec complete.

    I do find it interesting that the W3C cares about having more than 3 mouse buttons, while they still have no support for detecting more than one computer monitor.



  • @blakeyrat said:

    I do find it interesting that the W3C cares about having more than 3 mouse buttons, while they still have no support for detecting more than one computer monitor.

    Why does a web app need to know how many monitors I have?



  • @Lingerance said:

    @blakeyrat said:
    I do find it interesting that the W3C cares about having more than 3 mouse buttons, while they still have no support for detecting more than one computer monitor.

    Why does a web app need to know how many monitors I have?




    How else would you determine the optimal number of popups ?




  • @AndyCanfield said:

    This is the easier way:

    if ( navigator.appName.substr( 0, 9 ) == "Microsoft" )
    {
        window.alert( "Get yourself a decent browser!" );
        Abort();
    }

    Yeah, yeah, piss off.  IE works fine for me. It is decent.  (Cue the anti-MS crowd.) 



  • @Lingerance said:

    Why does a web app need to know how many monitors I have?
     

    It doesn't, but my point is that if you're going to put *any* amount of "monitor detection" in, you might as well do it right. Right now, they have an extremely half-assed way of telling your monitor resolution... either remove that and say "scripts can't know it", or make it correct.

    In other words, if it's worth doing, it's worth doing right. (Of course in this case it's not worth doing, but ... eh.)



  • @Lingerance said:

    @blakeyrat said:
    I do find it interesting that the W3C cares about having more than 3 mouse buttons, while they still have no support for detecting more than one computer monitor.
    Why does a web app need to know how many monitors I have?

    Why should a webpage use more than 3 mouse buttons?



  • @blakeyrat said:

    @Ragnax said:

    TextContent is in line with text nodes and the general node based concept of a DOM tree. InnerText and InnerHTML are not and in fact represent the concept of serializing (read from the property) and deserializing (write to the property) a subtree of the DOM tree. The DOM standard actually dictates other methods to explicitly achieve (de)serialization of subtrees.
     

    Yes, but "innerHTML" is part of the DOM. So somewhere, someone got their wires crossed. In any case, who the hell cares whether it explicitly or implicitly achieves yada of yada, I just want to grab the text (or HTML) out of the damned thing.

    innerHTML is also faster than adding content via the DOM and a fuck of a lot easier, less-verbose and less brittle.



  • @blakeyrat said:

    Yes, but "innerHTML" is part of the DOM.

    No it isn't.

     

    @Ragnax said:

    Disregarding for a moment that you shouldn't add events directly to the static html, there is still the fact that something like

    <a onclick='function(e){ e.preventDefault(); }'>Click me to do nothing</a>
    should work fine in standards compliant browsers.

    Rubbish.

    In practice*, browsers parse the data inside an event handling attribute into something like if(false == (function(event) { eval(textContentOfAttribute); })(_internalEvent)) _internalEvent.preventDefault();, so when you use a function closure, what you end up with is function(event) { function(e) { e.preventDefault(); } }, which as you can see will do nothing. If you wanted to use a closure, you could by using onclick="(function(e) { e.preventDefault(); })(event);", but I don’t know why you would ever do that.

    This method happens to work in IE since they assign events to window.event and the function is a closure of window, but of course since IE’s event model is still non-compliant you have to do the event handling differently anyway. Yaaaay.


    @blakeyrat said:

    Fine; then the W3C should put a non-broken version of this extremely helpful property into the standard.

    Everyone else (Mozilla, Opera, WebKit) seem to have decided that firing DOMContentLoaded event makes more sense (since it doesn’t require a loop checking to see if a property has changed, for one), and so it is far more likely that DOMContentLoaded would be added at some point. Of course, they did try that in 2006 and then it just ended up being deferred for…some reason that was never explained, which just goes to show you why WHATWG is so desperately needed.

     

    @blakeyrat said:

    Yah, which makes detecting chording a huge pain in the ass. It's definitely possible, true, and I'd even go as far as saying that web pages shouldn't even be doing it for usability reasons. But if you're going to write the spec, you might as well make the spec complete.

    1. How often do you need to detect people pressing multiple buttons simultaneously?
    2. It is physically impossible to press more than one button at a time on an Apple mouse, so you had better not be relying on it for proper functionality.
    3. Detecting chords is trivial with the DOM.
    var listener = function(event)
    {
      window.currentButtons ^= Math.pow(2, event.button);
      switch(window.currentButtons)
      {
        case 0: // no buttons
        case 1: // lmb
        case 2: // mmb
        case 3: // lmb+mmb
        case 4: // rmb
        case 5: // lmb+rmb
        case 6: // mmb+rmb
        case 7: // lmb+rmb+mmb
        case 8: // 4mb
        // etc.
      }
    };

    obj.addEventListener('mousedown', listener, false);
    obj.addEventListener('mouseup', listener, false);

    @blakeyrat said:
    I do find it interesting that the W3C cares about having more than 3 mouse buttons, while they still have no support for detecting more than one computer monitor.
    Why? The DOM is concerned with document events, such as UI events, not physical browser properties which should be larely irrelevant to a Web page.

    @morbiuswilters said:
    innerHTML is also faster than adding content via the DOM and a fuck of a lot easier, less-verbose and less brittle.
    QFT.

    * I don’t honestly know if this is truly what happens behind the scenes or not, but is how all the browsers act.


  • @blakeyrat said:

    Possibly; but it doesn't work in Firefox. And, when I was trying to do this about 6 months ago, I seem to recall there was no way of getting this to work in Firefox.
    You must have a very broken Firefox then. I remember implementing some scripts that use preventDefault around a year and a half ago, and back then it worked fine in Firefox, Opera and Safari.



  • @snover said:

    Everyone else (Mozilla, Opera, WebKit) seem to have decided that firing DOMContentLoaded event makes more sense (since it doesn’t require a loop checking to see if a property has changed, for one), and so it is far more likely that DOMContentLoaded would be added at some point. Of course, they did try that in 2006 and then it just ended up being deferred for…some reason that was never explained, which just goes to show you why WHATWG is so desperately needed.

    The issue is that my script can't tell if the DOM is ready because it's been included on the page during load (in which case it should listen to the event), or because it's been added to the page after the DOMContentLoaded event (or equivalent) has already fired.

    That proposal wouldn't fix that situation; it's just talking about an event that gets fired once, and then that's it. What I need for my purposes is a property of the page I can read to determine its status without an event, so my script can tell whether it should be listening for DOMContentLoaded, or whether it's ok to start doing its thing right away. AFAIK, the W3C hasn't even started to tackle that problem.

    @snover said:

    1. How often do you need to detect people pressing multiple buttons simultaneously?

    I'd go as far as saying that *no* website should require that, but that's not the point: if the standard includes support for it, it shouldn't be half-assed support.

     To re-iterate: I don't think websites should be using chording for anything. I think it's a horrible idea for usability and accessibility. I'm just saying that if the standard is going to include support for it, it shouldn't be half-assed.

    @snover said:

    3. Detecting chords is trivial with the DOM.

    According to QuirksMode the Microsoft button values are:

    • Left button – 1
    • Middle button – 4
    • Right button – 2

     According to W3C, the values should be:

    • Left button – 0
    • Middle button – 1
    • Right button – 2

    So your code sample should fail on W3C-compliant browsers.

    See: http://www.quirksmode.org/js/events_properties.html#button

    @snover said:

    Why? The DOM is concerned with document events, such as UI events, not physical browser properties which should be larely irrelevant to a Web page.

    As I've said multiple times, if they're going to have any support for this at all, it should be proper support, not the current half-assed support. If it's not worth supporting (which I agree with), then it should be removed.

     

     



  • @blakeyrat said:

    The issue is that my script can't tell if the DOM is ready because it's been included on the page during load (in which case it should listen to the event), or because it's been added to the page after the DOMContentLoaded event (or equivalent) has already fired.

    That proposal wouldn't fix that situation; it's just talking about an event that gets fired once, and then that's it. What I need for my purposes is a property of the page I can read to determine its status without an event, so my script can tell whether it should be listening for DOMContentLoaded, or whether it's ok to start doing its thing right away. AFAIK, the W3C hasn't even started to tackle that problem.


    Do it in your app? The vast majority of web pages don’t load extra script content after the intial load so the DOM event works just fine. In your case, something very simple like this would be necessary:

    var init = function(event) { window.DOMContentLoaded = true; }
    window.DOMContentLoaded = false;
    window.addEventListener('DOMContentLoaded', init, false);

    @blakeyrat said:

    To re-iterate: I don't think websites should be using chording for anything. I think it's a horrible idea for usability and accessibility. I'm just saying that if the standard is going to include support for it, it shouldn't be half-assed.

    What you are advocating is the kitchen sink approach: “Someone might want to do these things, so make sure that every possible permutation is thought about and accounted for”. There are already very simple methods that you can use to do everything that you’ve mentioned already. My counter-response is: why should we be bloating the standard with crap that 99.9%+ of developers are not going to use? The only time something really ought to be written into the standard is when it’s impossible or prohibitively difficult to do it otherwise. DOM Events is flexible enough that it does everything required of it with a minimum of fuss.

    @blakeyrat said:

    @snover said:
    3. Detecting chords is trivial with the DOM.

    According to QuirksMode the Microsoft button values are:

    • Left button – 1
    • Middle button – 4
    • Right button – 2

     According to W3C, the values should be:

    • Left button – 0
    • Middle button – 1
    • Right button – 2

    So your code sample should fail on W3C-compliant browsers.

    Just the opposite, actually (note how I call Math.pow). But once again, that’s Microsoft’s fault for not even complying with the standards that do exist.

    @blakeyrat said:

    @snover said:
    Why? The DOM is concerned with document events, such as UI events, not physical browser properties which should be larely irrelevant to a Web page.

    As I've said multiple times, if they're going to have any support for this at all, it should be proper support, not the current half-assed support. If it's not worth supporting (which I agree with), then it should be removed.

    I think you are confusing browser manufacturers’ de facto standards with the actual published standards. The “navigator” object is not part of any W3C standard. There is absolutely no support for determining anything about the physical properties of the screen in any part of the DOM. The fact that everyone followed Netscape’s lead (well, except Microsoft, again, who decided not to populate navigator.plugins) has nothing to do with the W3C creating half-assed standards. Since it exists, it probably should be standardised, and you can call them out for failing to do that at least.



  • @snover said:

    Do it in your app?
     

    My app *is* the JS. It can be deployed either as a bookmarklet (i.e. after page load), or by including it on the page.

     @snover said:

    The vast majority of web pages don’t load extra script content after the intial load so the DOM event works just fine.

    Obviously I'm aware of that. But for the minority of products that *do*, like the one I was writing for example, the IE readyState property allows it to work just fine. Look, I'm not saying Microsoft is the holy grail we should all worship, nor am I saying that it should be easy to do. But it should be *possible* to do, and right now, it's not (in Firefox and other relatively-strict browsers.)

    If people have to modify the page that my bookmarklet is going to run on, it defeats the purpose of making the bookmarklet in the first place-- they could just include the script directly on the page. (Which in this case is the only work-around for non-IE users.)

    @snover said:

    Just the opposite, actually (note how I call Math.pow).

    Maybe I'm a tard, but you call Math.pow, and then say 0 == no buttons down. If W3C-compliant browsers return 0, they mean the left button is down... maybe I'm misreading it.

     @snover said:

    But once again, that’s Microsoft’s fault for not even complying with the standards that do exist.

    Microsoft implemented their version before the standard existed.



  • @blakeyrat said:

    My app *is* the JS. It can be deployed either as a bookmarklet (i.e. after page load), or by including it on the page.

    I think this might be an X-Y problem. I don’t know enough about whatever this bookmarklet is to say whether or not there is a reasonable workaround. My guess is that there is, like polling for whatever element you want to find instead of polling on readyState, or by polling for document.body. Or just tell users not to click it until the page has finished loading.

    @blakeyrat said:

    Maybe I'm a tard, but you call Math.pow, and then say 0 == no buttons down. If W3C-compliant browsers return 0, they mean the left button is down... maybe I'm misreading it.

    Math.pow(2, 0) = 1.
    Math.pow(2, 1) = 2.
    Math.pow(2, 2) = 4.
    et cetera.

    Since the function execute on both mouse down and mouse up actions, once the final mouse up occurs, you end up with 0 in window.currentButtons. I should point out that window.currentButtons should be initialized to 0 but by the time I realised my example was incomplete I couldn’t edit the post any more.

    @blakeyrat said:

    Microsoft implemented their version before the standard existed.

    So did Netscape, but you don’t see Mozilla still using it. :)



  • TRWTF is that is_winmobile is always false.


Log in to reply