Захват нажатия клавиши в Javascript (Документы Google)

Я пытаюсь написать небольшой скрипт Greasemonkey/букмарклет/что у вас есть для Google Docs. Функциональность, которую я хотел бы добавить, нуждается в обработчике событий keypress/keyup/keydown (одного из этих трех). К сожалению, Javascript не моя сильная сторона, и я не могу зафиксировать (?) событие нажатия клавиши, находясь в панели редактирования. В крайнем случае я пробовал следующее:

javascript:(function(){
  els = document.getElementsByTagName("*");
  for(i=0;i<els.length;i++){
    els[i].onkeypress=function(){alert("hello!");};
    els[i].onkeyup=function(){alert("hello2!");};
    els[i].onkeydown=function(){alert("hello3!");};
  }
})();

Тем не менее, это по-прежнему не фиксирует нажатия клавиш в панели редактирования - никаких надоедливых предупреждений (хотя, похоже, это работает для большинства других сайтов...). Я проверил в Chrome и Firefox оба (я не могу заставить его работать ни в одном из них).

Я попробовал «Журналировать события» в Firebug (и проверил все зарегистрированные события с помощью аккуратного небольшого расширения для Firebug, Eventbug); не похоже, чтобы эти события срабатывали при нажатии клавиш.

Редактировать:
Чтобы пояснить [Тима], я сделал этот скриншот с некоторыми аннотациями... скриншот

«Панель редактирования», о которой я говорю, кажется набором элементов div с Javascript, отображающих то, что я печатаю.

Любые идеи? Спасибо!


person Jacob    schedule 07.12.2010    source источник
comment
Что вы подразумеваете под панелью редактирования? Это iframe? Текстовое поле?   -  person Tim Down    schedule 07.12.2010
comment
@Jacob, пожалуйста, проверьте свою учетную запись электронной почты в профиле.   -  person    schedule 10.01.2011


Ответы (3)


Редактирование в Документах Google использует iframe. Вам нужно прикрепить прослушиватель к документу iframe. Кажется, что-то сложное с iframe, которое я еще не смог полностью проработать, но для Firefox работает следующее:

var iframe = document.getElementsByTagName("iframe")[0];
if (iframe) {
    iframe.contentDocument.addEventListener("keypress", function(evt) {
        console.log("iframe keypress: " + evt.which);
    }, false);
}
person Tim Down    schedule 08.12.2010
comment
Ах, я не подумал об этом, и это действительно именно то, что я хотел - спасибо! - person Jacob; 10.12.2010

Кажется, у меня работает... но я использую jQuery $(document).ready(), чтобы убедиться, что моя страница загружена, прежде чем прикреплять какое-либо событие. Я думаю, вы могли бы сделать это в голом javascript с помощью:

window.onload = function()
{
  els = document.getElementsByTagName("*");
  for(i=0;i<els.length;i++) {
    els[i].onkeypress=function(){alert("hello!");};
  }
}

Кстати, к событию нельзя прикрепить более одной функции:

for(i=0;i<els.length;i++){
    els[i].onkeypress=function(){alert("hello!");};
    els[i].onkeypress=function(){alert("hello2!");};
    els[i].onkeypress=function(){alert("hello3!");};
}

Элемент зарегистрирует только последний (переопределяет предыдущую функцию), в данном случае "alert("hello3!");"

person Romain Meresse    schedule 07.12.2010
comment
Ой, это была опечатка (исправлю выше), спасибо! Я пробовал все три из onkeypress, onkeyup и onkeydown безрезультатно. - person Jacob; 08.12.2010

Вам не нужно прикреплять слушателя ко всем элементам на странице. Достаточно прикрепить его к документу.

window.addEventListener('load', function() {
    document.addEventListener('keypress', function() { alert("hello!"); });
}

Поскольку это скрипт GreaseMonkey, вам не нужно беспокоиться об IE, и вы можете использовать метод addEventListener.

person Christian Tellnes    schedule 07.12.2010
comment
Да, это то, что я попробовал в первую очередь ... Моя проблема кажется специфичной для Документов Google. Приведенный выше код отлично работает на любом другом сайте, но не в Документах Google при редактировании документа. Это работает для вас в этом случае? - person Jacob; 08.12.2010
comment
Я бы подумал, что они останавливают событие для дальнейшего выполнения своего обработчика событий. Я не смог заставить его работать сам. Я думаю, вам нужно удалить их прослушиватель событий и вызвать его вручную. Вы можете попробовать взглянуть на библиотеку закрытия js, которую они используют. - person Christian Tellnes; 10.12.2010