tags:

views:

130

answers:

5

I'm having troubles getting the attachEvent to work. In all browsers that support the addEventListener handler the code below works like a charm, but in IE is a complete disaster. They have their own (incomplete) variation of it called attachEvent.

Now here's the deal. How do I get the attachEvent to work in the same way addEventListener does?

Here's the code:

function aFunction(idname)
{
    document.writeln('<iframe id="'+idname+'"></iframe>');
    var Editor = document.getElementById(idname).contentWindow.document;

    /* Some other code */

    if (Editor.attachEvent)
    {
        document.writeln('<textarea id="'+this.idname+'" name="' + this.idname + '" style="display:none">'+this.html+'</textarea>');
        Editor.attachEvent("onkeyup", KeyBoardHandler);
    }
    else
    {
        document.writeln('<textarea id="hdn'+this.idname+'" name="' + this.idname + '" style="display:block">'+this.html+'</textarea>');
        Editor.addEventListener("keyup", KeyBoardHandler, true);
    }
}

This calls the function KeyBoardHandler that looks like this:

function KeyBoardHandler(Event, keyEventArgs) {
    if (Event.keyCode == 13) {
        Event.target.ownerDocument.execCommand("inserthtml",false,'<br />');
        Event.returnValue = false;
    }

    /* more code */
}

I don't want to use any frameworks because A) I'm trying to learn and understand something, and B) any framework is just an overload of code I'm nog going to use.

Any help is highly appreciated!

A: 

You might be better off using a JavaScript framework such as MooTools or jQuery of your choice to ease cross-browser support. For details, see also

MooTools port of parts of your sample code:

var Editor = $(idname).contentWindow.document;
...
$(document.body).grab(new Element('textarea', {
    'id'   : this.idname,
    'name' : this.idname,
    'style': 'display:none;',
    'html' : this.html
});
Editor.addEvent('keyup', KeyBoardHandler);

By the way, is it on purpose that you use both idname and this.idname in the code above ?

Archimedix
Thanks guys, but no thanks. ;-) First of all I'm trying to learn something here, secondly I don't want an overload of code that I'm not going to use. So please no external framework advice, although I understand the idea behind it.
Leon
+2  A: 

Just use a framework like jQuery or prototype. That's what they are there for, this exact reason: being able to do this sort of thing w/out having to worry about cross-browser compatibility. It's super easy to install...just include a .js script and add a line of code...

(edited just for you Crescent Fresh)

With a framework, the code is as simple as...

<script type='text/javascript' src='jquery.js'></script>
$('element').keyup(function() { 
  // stuff to happen on event here
});
Crayon Violent
seriously though...go pickup jQuery or something...I used to resist it for the longest time...one day I was forced to learn it to the extent of fixing some code that utilized it...ever since then...I constantly kick myself in the arse for not using it sooner. Greatest invention since sliced bread.
Crayon Violent
Why don't you show the OP how crazy easy it is to do with jQuery or Prototype then! "Just use jQuery" ain't no kind of answer.
Crescent Fresh
happy? I didn't think something that "crazy easy" needed explaining but since you want to be an arse like you're some kind of interweb police person...p.s. - thanks for the downvote, glad I made your self-righteous day a little brighter.
Crayon Violent
@Crayon you don't know whether Crescent Fresh actually cast that downvote. +1 because I agree though
Pekka
Let's keep it friendly please, no need to fight over such a stupid little thing. ;-)
Leon
you're right. His pet peeve triggered my pet peeve. Sorry.
Crayon Violent
A: 

Here is a function I use for both browsers:

function eventListen(t, fn, o) {
    o = o || window;
    var e = t+Math.round(Math.random()*99999999);
    if ( o.attachEvent ) {
        o['e'+e] = fn;
        o[e] = function(){
            o['e'+e]( window.event );
        };
        o.attachEvent( 'on'+t, o[e] );
    }else{
        o.addEventListener( t, fn, false );
    }
}

And you can use it like:

eventListen('keyup', function(ev){
  if (ev.keyCode === 13){
    ...
  }
  ...
}, Editor)
Mic
What would the converse `detachEvent`/`removeEventListener` look like? (you know, for symmetry's sake).
Crescent Fresh
So how would I use the code above in this case? Sorry, somewhat of a JS noob. :/
Leon
Strangely I've never had to detach in our app. No code available then...
Mic
@user451513, I've updated the example to look like yours. Is it your question?
Mic
@Mic; it doesn't work unfortunately. Can I e-mail you the entire code so you can see the purpose?
Leon
Yep. Post it somewhere like http://friendpaste.com, but quick it is near bedtime here ;)
Mic
Here's a small example that works on IE and others http://gist.github.com/586091 I'll check yours
Mic
Inside the callback function there are differences with IE. eg: `event.srcElement` while all other browsers use `event.target`, you may need as well to abstract these like `var target = ev.target || ev.srcElement` Good Night!
Mic
Thanks Mic, now I see what I've learned something and fixed the problem.
Leon
Good! Welcome to the client-side of the web! Keep PHP to read/generate JSON messages, and do the view with JS and HTML on the browser 8)
Mic
A: 

Different browsers will process events differently. Some browsers have event bubble up throw the controls where as some go top down. For more information on that take a look at this W3C doc: http://www.w3.org/TR/DOM-Level-3-Events/#event-flow

As for this specific issue setting the "userCapture" parameter to false for the addEventListener will make events behave the same as Internet Explorer: https://developer.mozilla.org/en/DOM/element.addEventListener#Internet_Explorer

Evan
`useCapture` only determines if the event fires during the capture sequence or bubble sequence. IE only does the bubble sequence, so `false` is used for compatibility. it won't change the process of the handler.
lincolnk
A: 

The source of your problems is the KeyBoardHandler function. Specifically, in IE Event objects do not have a target property: the equivalent is srcElement. Also, the returnValue property of Event objects is IE-only. You want the preventDefault() method in other browsers.

function KeyBoardHandler(evt, keyEventArgs) {
    if (evt.keyCode == 13) {
        var target = evt.target || evt.srcElement;
        target.ownerDocument.execCommand("inserthtml",false,'<br />');
        if (typeof evt.preventDefault != "undefined") {
            evt.preventDefault();
        } else {
            evt.returnValue = false;
        }
    }

    /* more code */
}
Tim Down