2010-09-18 2 views
12

У меня возникают проблемы с подключением attachEvent. Во всех браузерах, поддерживающих обработчик addEventListener, приведенный ниже код работает как шарм, но в IE это полная катастрофа. У них есть своя (неполная) вариация, называемая attachEvent.attachEvent versus addEventListener

Теперь вот сделка. Как заставить attachEvent работать так же, как это делает addEventListener?

Вот код:

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); 
    } 
} 

Это вызывает функцию KeyBoardHandler, которая выглядит следующим образом:

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

    /* more code */ 
} 

Я не хочу использовать какие-либо рамки, потому что а) я пытаюсь научиться и понять что-то, и B) любая фреймворк - это просто перегрузка кода, который я буду использовать.

Любая помощь очень ценится!

+0

У вас есть отличная возможность учиться, не используя рамки для понимания внутренней работы браузера на основе JavaScript. Однако я бы предположил, что вы переходите к использованию фреймворков для производственного кода, как только вы освоите низкоуровневый JavaScript, не имеет большого смысла изобретать колесо (рамки широко протестированы с помощью множества браузеров, и один раз вы катите свой собственный фреймворк, он будет в любом случае зависеть от особенностей браузера и избежать кода шаблона в другом месте вашего кода). Кроме того, внешний JavaScript может быть кэширован браузером один раз для нескольких запросов. – Archimedix

+0

Что вы пытаетесь сделать и что происходит сейчас, это неправильно? – lincolnk

+0

Рамки, подобные jquery, сегодня больше похожи на стандарт, они пытаются сделать кросс-браузерную совместимость реальной, используйте javascript, когда вы действительно хотите сделать что-то конкретное и хотите получить полный контроль. –

ответ

0

Возможно, вам лучше использовать инфраструктуру JavaScript, такую ​​как MooTools или jQuery по вашему выбору, чтобы упростить поддержку кросс-браузера. Для получения дополнительной информации см также

MooTools порт части вашего образца кода:

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); 

Кстати, это нарочно, что вы используете и idname и this.idname в коде выше?

+3

Спасибо, ребята, но не спасибо. ;-) Прежде всего, я пытаюсь что-то узнать здесь, во-вторых, я не хочу перегружать код, который я не буду использовать. Поэтому, пожалуйста, не обращайтесь к внешним советам по инфраструктуре, хотя я понимаю идею, лежащую в ее основе. –

+1

Я имею в виду это с лучшими намерениями - возможно, было бы лучше узнать не причуды базовых браузеров, а вместо этого потратить свое время на изучение концепций более высокого уровня, таких как обратные вызовы, обещания, шаблон модуля, каррирование и т. Д. браузеры становятся более стандартизованными, ваша рентабельность при изучении таких особенностей будет уменьшаться, тогда как изучение более абстрактных идей Javascript так же увлекательно учится, а в то же время оснащает вас другими языками и разными вещами вниз. – iono

3

Просто используйте фреймворк, например, jQuery или прототип. Именно для этого они и есть, эта точная причина: иметь возможность делать такие вещи, чтобы не беспокоиться о совместимости между браузерами. Это очень легко установить ... просто включить .js скрипт и добавить строку кода ...

(отредактированного только для вас Crescent Fresh)

С фреймворка, код так просто, как. ..

<script type='text/javascript' src='jquery.js'></script> 
$('element').keyup(function() { 
    // stuff to happen on event here 
}); 
+0

всерьез, хотя ... пойти на пикап jQuery или что-то в этом роде ... Раньше я сопротивлялся ему в течение самого долгого времени ... однажды мне пришлось изучить его до степени исправления кода, который его использовал ... с тех пор ... Я постоянно пинаю себя в задницу, чтобы не использовать ее раньше. Величайшее изобретение, так как нарезанный хлеб. –

+11

Почему бы вам не показать OP, как безумно легко это сделать с jQuery или Prototype? «Просто использовать jQuery» - это не какой-то ответ. –

+1

счастливы? Я не думал, что «сумасшедший легко» нужно объяснить, но так как ты хочешь быть задницей, как будто ты какой-то полицейский из Интернета ... p. - спасибо за нижний план, рад, что я сделал свой самодовольный день немного ярче. –

2

Вот функция, я использую для обоих браузеров:

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); 
    } 
} 

И вы можете использовать его как:

eventListen('keyup', function(ev){ 
    if (ev.keyCode === 13){ 
    ... 
    } 
    ... 
}, Editor) 
+1

Как выглядит обратный 'detachEvent' /' removeEventListener'? (вы знаете, ради симметрии). –

+0

Итак, как бы я использовал код в этом случае? Извините, немного JS noob. :/ –

+0

Странно, что мне никогда не приходилось отсоединяться в нашем приложении. Тогда нет кода ... – Mic

2

Различные браузеры будут обрабатывать события по-разному. У некоторых браузеров есть пузырь событий, которые бросают элементы управления, когда некоторые спускаются вниз. Для получения более подробной информации о том, что смотреть на этой W3C документ: http://www.w3.org/TR/DOM-Level-3-Events/#event-flow

Что касается этого конкретного установки параметра «userCapture» ложь для addEventListener вопроса сделает события ведут себя так же, как Internet Explorer: https://developer.mozilla.org/en/DOM/element.addEventListener#Internet_Explorer

+0

'useCapture' определяет только, будет ли событие срабатывать во время последовательности захвата или последовательности пузырьков. IE выполняет только последовательность пузырьков, поэтому для совместимости используется 'false'. он не изменит процесс обработчика. – lincolnk

7

источником ваших проблем является функция KeyBoardHandler.В частности, в IE Event объекты не имеют свойства target: эквивалент srcElement. Кроме того, свойство returnValue объектов Event является IE-only. Вы хотите использовать метод preventDefault() в других браузерах.

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 */ 
} 
14

Вот как это сделать, кросс-браузер, только для справки.

var myFunction=function(){ 
    //do something here 
} 
var el=document.getElementById('myId'); 

if (el.addEventListener) { 
    el.addEventListener('mouseover',myFunction,false); 
    el.addEventListener('mouseout',myFunction,false); 
} else if(el.attachEvent) { 
    el.attachEvent('onmouseover',myFunction); 
    el.attachEvent('onmouseout',myFunction); 
} else { 
    el.onmouseover = myFunction; 
    el.onmouseout = myFunction; 
} 

исй: http://jquerydojo.blogspot.com/2012/12/javascript-dom-addeventlistener-and.html

0

Кто-то выше, что «.. в объектах событий IE не имеет целевое свойство: эквивалент является srcElement ...» Ну, в IE11 есть такая цель.