Я разработал расширение для Firefox с кучей слушателей событий, особенно для функции с предсказательным текстом .
Отлично работает на большинстве "простых"textarea
, input
и contenteditable
элементов.
Но это определенно не работает с некоторыми важными другими.
Мое первое наблюдение состоит в том, что слушатели не применяются в большинстве редакторов WYSIWYG,или на элементах с уже большим количеством слушателей событий.Но также и на некоторых других.
Могут ли сценарии веб-сайтов предотвращать / блокировать добавление внешних прослушивателей событий?
Какой конфликт может привести к такому поведению?
Чего мне не хватает?
Это мой код: https://github.com/ANN-MB/LEIA/blob/master/extension%20firefox/leia.js
Примеротсутствующие события (мое): https://ibb.co/SxXJFR4
Это способ добавления прослушивателей событий:
document.querySelectorAll("input,textarea").forEach(function(x) {
if (x.type.match(/SEARCH|TEXT|TEXTAREA/i)) {
x.addEventListener("keyup", function(e) {
middot(e,this)
}, false);
}
});
document.querySelectorAll("[contenteditable],[contenteditable=true]").forEach(function(x) {
x.addEventListener("keyup", function(e) {
middotCE(e,this)
}, false);
});
То же поведение с другими способами добавления прослушивателей событий в элементы (циклы for
,без условного совпадения и т. д.)
РЕДАКТИРОВАТЬ
Основываясь на комментарии Яроманды Х, я сделал это.Совершенно хорошо с моими тестовыми страницами, но все еще не на некоторых веб-сайтах.Таким образом, проблема не в динамически генерируемых элементах.
// add listeners to contenteditable elements
function addCEListeners(elem) {
elem.addEventListener("keyup", function(e) { middotCE(e,this); feminizeCE(this); }, false);
elem.addEventListener("keydown", function(e) { switcherCE(e,this) },false);
}
var callback = function(mutationsList, observer) {
for (var mutation of mutationsList) {
if (mutation.type == 'childList') {
var added_node = mutation.addedNodes[0];
if (added_node.nodeType == 1) { // if added node is an element
if (added_node.tagName.match(/INPUT|TEXTAREA/i)) { // if it is any kind of input or a textarea
if (added_node.type.match(/TEXT|TEXTAREA/i){ // if it is an input "text" or a textarea
added_node.addEventListener("keyup", function(e) { middot(e,this);feminize(this); }, false);
added_node.addEventListener("keydown", function(e) { switcher(e,this) },false);
}
if (added_node.type.match(/SEARCH/i)) { // if it is an input "search"
added_node.addEventListener("keyup", function(e) { middot(e,this) },false);
}
} else if (added_node.contentEditable == "true") { // if any other added alement is contenteditable
addCEListeners(added_node)
}
}
} else if (mutation.type == 'attributes' && mutation.attributeName == 'contenteditable') { // if an existing element is given a "contenteditable" attribute
mutation.target.contentEditable == "true" && addCEListeners(mutation.target);
}
}
};
var observer = new MutationObserver(callback);
observer.observe(document.body, {attributes: true, childList: true, subtree: true});
РЕДАКТИРОВАТЬ 2:
Кажется, что некоторые из веб-сайтов, на которых я могу наблюдать этоПоведение просто уничтожает все addEventListeners
, кроме их, с помощью removeEventListeners
при обнаружении нового слушателя.
Есть ли способ обойти это, избегая войны добавления / удаления событий EventListeners ??
РЕДАКТИРОВАТЬ 3:
Я нашел компромисс, но я не удовлетворен этим.Я слушаю keyup
и keypress
из всего документа, и если целью является текстовое поле, я вызываю функции.Работает в течение input
с, но не для некоторых contenteditable
элементов.Плюс это тяжелое решение, верно?Скрипт создан для слепых, поэтому они часто используют клавиатуру для навигации.Так что это много событий нажатия клавиш для обработки.
document.addEventListener("keyup",function(e){
let targ = e.target;
if (targ.tagName.match(/INPUT|TEXTAREA/i) &&
targ.type.match(/SEARCH|TEXT|TEXTAREA/i)) {
middot(e,targ);
!elem.type.match(/SEARCH/i) && feminize(targ)
} else if (elem.contentEditable == "true") {
middotCE(e,targ);
feminizeCE(targ);
}
})
document.addEventListener("keydown",function(e){
let targ = e.target;
if (targ.tagName.match(/INPUT|TEXTAREA/i) &&
targ.type.match(/TEXT|TEXTAREA/i)) {
switcher(e,targ)
} else if (targ.contentEditable == "true") {
switcherCE(e,targ)
}
})