views:

61

answers:

2

I hate IE6, in fact I wish microsoft would force out a patch that killed the damn thing stone dead. The following script works fine in IE > 6 & FF,WebKit(chrome etal) without issue; any ideas?

(function getElementsByClass(searchClass) {
        node = document;
        tag = '*';
        var els = node.getElementsByTagName(tag);
        var elsLen = els.length;
        var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
        var count = 1;
        for (i = 0, j = 0; i < elsLen; i++) {
            if ( pattern.test(els[i].className) ) {
                    var re1='.*?';  // Non-greedy match on filler
                    var re2='(\\\'.*?\\\')';    // Single Quote String 1
                    var p = new RegExp(re1+re2,["i"]);
                    var m = p.exec(els[i].getAttribute("onclick"));
                    var popURL = "";
                    if (m != null)
                    {
                      var strng1=m[1];
                      popURL = strng1.replace(/'/g,'');
                    }

                    els[i].setAttribute("href", popURL + "?keepthis=true&tb_iframe=true&height=430&width=400");
                    els[i].setAttribute("class", "thickbox"); 
                    els[i].removeAttribute("onclick");
                    j++;
                    count++;
            }
        }
       // return count; Ignore the return
})("vtthickbox");
+1  A: 

Why not just use this instead:

function getElementsByClass(searchClass) {
 var classElements = new Array(),
     node = document,
     tag = '*',
     els = node.getElementsByTagName(tag),
     elsLen = els.length,
     pattern = new RegExp("(^|\\s)" + searchClass + "(\\s|$)"),
     i,
     j;
 for (i = 0, j = 0; i < elsLen; i++) {
  if (pattern.test(els[i].className)) {
   classElements[j] = els[i];
   j++;
  };
 };
 return classElements;
};

Then put the onclick event handler logic outside of the getElementsByClass() function.

Mathias Bynens
I tried a few methods, but I'll have a play with that and see if its any faster thanks.
Chris M
+3  A: 

typeof els[i].getAttribute("onclick") returns function in my IE6, but FF, Opera returns string.

I don't think RegExp.exec can handle function object.

And with that, typeof m[1] became undefined, which cause popURL to undefined too.

S.Mark
Ah should of tested the type, I think IE8 returns the appropriate string value as does 7. Seems a bit vicious to crash out the browser.
Chris M
Problem with getAttribute in < IE7 is down to the following and iFlag etc etc http://tobielangel.com/2007/1/11/attribute-nightmare-in-ie/
Chris M
Yeah, I am looking into that too. thanks.
S.Mark
Funny the quickest fix is to just test for ie var isIE6 = /msie|MSIE 6/.test(navigator.userAgent);One day... one day!
Chris M
I think jQuery's `attr` can handle that one, I saw some IE specific codes in jQuery source, and btw you mean `/msie 6/i.test` right?
S.Mark
IE7 won't return the string value; this was only fixed in IE8 native mode. You should generally never use `getAttribute`/`setAttribute` on an HTML document for this reason; using normal DOM Level 1 HTML properties like `el.href` is both more readable and more reliable. If you really must get the string value for an event handler you can do it with `getAttributeNode('onclick').value`, but surely there must be a less hideous way forward than hacking some JavaScript code with regex to find a string in it?
bobince
(Unless the markup is completely out of your hands of course, which would be sad.) Also you don't need the `[]` around the regex flags (luckily the array gets converted to a string with the same value, but you shouldn't rely on that). PS. Don't browser-sniff. You'll get many false-positives from looking at the user-agent. Capability-sniff if you have to, but for this, you don't.
bobince
Thanks @bobince for follow up, I was also suspected for regex flag [] too but its was surprisely working :D
S.Mark
Ta bob; I'd already switched to getAttributeNode which seems to work fine. setAttribute/removeAttribute seem to work fine universally; its a shame that the browser vendors arent trying to get DOM1 right before they float off working on HTML5 rendering...The less hideous alternative would be to simply change the C# to build a normal link with a css class, but thats not going to happen anytime soon (bloody outsourced code). So the faster the hack the better.
Chris M
@S.Mark ta; msie|MSIE lowercase or uppercase; I wasnt planning on browsersniffing it was just a bit of a joke
Chris M
I see, I am a bit sensitive to regex :P because it could match to any IE version, I think its normally UPPERCASE though :D
S.Mark
:o) With Microsoft I dare not take that risk. Some of our customers still use IE5.5 luckily we dont support that; I need their numbers under 2% before I can drop IE6 support and pullback OH so many man hours.Wouldnt It be much nicer if browsers supported scripts as per the spec rather than interpreting the spec their own way or in MSFTs case doing as they please :op
Chris M
Listen to @bobince. He has said exactly what I was about to say.
Tim Down
IE5.5? Dear Lord! How is that even possible, you have customers running WinME? [:is ill] Anyway yeah, the user-agent sniff would also catch other browsers that pretend to be IE; generally it is not a reliable source of info. `setAttribute` on event handlers doesn't work either with IE<8.
bobince
Just as a note setAttribute works in IE6 for elements that you can access normally (ele.href etal) (try it in VPC XPSP3 IE6 + 7) its onclick and all that lark it fails miserably at.removeAttribute wasn't working as expected even if debug bar showed it working fine (wtf) I hacked it half to death in the end to get the result i wanted :o)
Chris M
You almost never need `getAttribute` or `setAttribute` in browser scripting, and because of its behaviour in IE it should be avoided.
Tim Down
True but it would be nice if DOM1 methods actually worked. If I released software with as many spec cockups as IE I'd be shot out of a cannon.
Chris M