Есть ли способ в jQuery прикрепить прослушиватель к ячейке <td>
, чтобы при изменении текста внутри ячейки (с помощью JavaScript, а не пользователя) событие запускалось?
Слушатель событий jQuery, когда текст изменился в ячейке ‹td›?
Ответы (4)
Чтобы расширить ответ mway на , вот код.
var td = $('#my-table tr td:eq(1)');
var tdHtml = td.html();
setInterval(function() {
if (td.html() !== tdHtml) {
// it has changed
tdHtml = td.html();
}
}, 500);
... и за его второе предложение.
function updateTd(html) {
$('#my-table tr td:eq(1)').html(html);
// additional code
}
Вы также можете привязать событие DOMSubtreeModified
к элементу, но поддержка браузера не самая лучшая.
person
alex
schedule
08.10.2010
Спасибо за расширение, уже поздно. ;)
- person mway; 08.10.2010
Если это сработает, я думаю, было бы лучше проверить, равны ли длины.
if (td.html().length !== tdHtml.length) {..}
Потому что я думаю, что сравнение чисел имеет более высокую производительность.
- person Reigel; 08.10.2010
@Reigel Конечно, но что, если я обновлю
innerHTML
, чтобы он имел одинаковую длину символов?
- person alex; 08.10.2010
если это так, я оставлю вас и с этим вопросом.
"values" !== "values"
? ;)
- person Reigel; 08.10.2010
Случаи @Reigel Edge всегда приветствуются :) Я думаю, это нужно будет задокументировать, однако это все еще изменение, даже если оно может показаться не таковым с точки зрения конечного пользователя. Кроме того, как часто JavaScript будет обновлять
td
закодированными символами?
- person alex; 08.10.2010
@Алекс. хаха хороший вопрос. и сколько раз с вами случалось, что вы должны изменить
length
из innerHTML
напрямую. хе-хе
- person Reigel; 08.10.2010
@Reigel Я думаю, вы неправильно поняли меня выше
('bob'.length === 'tom'.length)
. Это то, к чему я стремился. Хотя сравнение будет быстрее, оно будет не совсем точным ;).
- person alex; 08.10.2010
@alex ааа, хороший улов! .. и я тоже думал о
if (td.html().length !== tdHtml.length) { changed happened } else if (td.html() !== tdHtml) { changed happened }
, поэтому, если длина не равна, нет необходимости проверять ее значение. ;)
- person Reigel; 08.10.2010
@Reigel О, да, я понял. :) Ну да, это было бы быстрее, но пахнет микрооптимизацией. Я думаю, было бы полезно, если бы ваш интервал
setInterval
был примерно 10 микросекунд :).
- person alex; 08.10.2010
@Алекс. ха-ха с
10 microseconds
, интересно, как он отреагирует, если длина сравниваемых символов будет (скажем) Thousands
или больше. И делать это без использования comparing of length's
;)
- person Reigel; 08.10.2010
Что ж, это слишком много символов для
td
. Интересно, как JavaScript хранит строки, если он сохраняет длину вместе, то это будет намного быстрее, но также будет медленнее, если ему нужно найти символ конца строки (хотя я не думаю, что это так).
- person alex; 08.10.2010
Спасибо, это работает, как и ожидалось! jQuery настолько упрощает работу с JS, что я всегда забываю основы.
- person roflwaffle; 08.10.2010
Обрабатывает ли это все случаи, когда содержимое изменилось? Работает ли это, если таблица уже загружена, а пользователь меняет содержимое?
- person user3281466; 15.09.2014
Не родное, нет. У вас есть несколько вариантов:
1) Используйте setInterval()
, чтобы проверить значение по сравнению с его предыдущим значением, и действуйте соответствующим образом, если оно отличается.
2) Используйте общий метод для изменения содержимого ячейки, чтобы вы также могли выполнять дополнительную логику, когда ее значение изменяется, не перезаписывая его много раз.
person
mway
schedule
08.10.2010
Используйте прослушиватель событий ввода.
$(document).on('input', '#table > tbody > tr > td', function(){ })
person
akansh tayal
schedule
22.08.2019
Ужасы. Возможно, в 2010 году это было приемлемо.
const observer = new MutationObserver((mutations) => {
mutations.forEach((mutation) => {
let target = mutation.target;
// when the cell is empty, typing a character involves 1 event:
// target: TD, type childList, addNodes has 1 element
if( target.constructor.name === 'HTMLTableCellElement' && mutation.type === 'childList' ){
if( mutation.addedNodes.length == 1 ){
if( mutation.addedNodes[ 0 ].constructor.name === 'Text' ){
if( mutation.addedNodes[ 0 ].length == 1 ){
console.log( `new 1-char Text added, contents: |${mutation.addedNodes[ 0 ].data}|`)
// remove "hanging" BR if applicable
// NB this BR gets added automatically when the Text node is removed on
// becoming empty. You don't want to remove the BR until new text starts
// to be added, because if you remove the BR immediately the cursor goes
// to a funny location in the cell
if( target.childNodes.length == 2 ){
if( target.childNodes[ 1 ].nodeName === 'BR' ){
target.removeChild( target.childNodes[ 1 ] )
}
}
}
}
}
}
else if( target.constructor.name === 'Text' && mutation.type === 'characterData' ){
console.log( `Text has changed, contents now: |${target.data}|`)
}
const cell = target.constructor.name === 'HTMLTableCellElement'? target : target.parentElement
// respond to the changed text:
// NB with the "characterData" mutation where cell is null (Text set to empty string), this is followed immediately
// by another "childList" mutation where the target is the cell...
if( cell !== null ){
console.log( `current cell contents |${cell.innerHTML}|`)
}
});
});
const config = { attributes: false, childList: true, characterData : true, subtree : true };
observer.observe( htmlTable, config );
person
mike rodent
schedule
29.08.2017