Слушатель событий jQuery, когда текст изменился в ячейке ‹td›?

Есть ли способ в jQuery прикрепить прослушиватель к ячейке <td>, чтобы при изменении текста внутри ячейки (с помощью JavaScript, а не пользователя) событие запускалось?


person roflwaffle    schedule 08.10.2010    source источник


Ответы (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
comment
Спасибо за расширение, уже поздно. ;) - person mway; 08.10.2010
comment
Если это сработает, я думаю, было бы лучше проверить, равны ли длины. if (td.html().length !== tdHtml.length) {..} Потому что я думаю, что сравнение чисел имеет более высокую производительность. - person Reigel; 08.10.2010
comment
@Reigel Конечно, но что, если я обновлю innerHTML, чтобы он имел одинаковую длину символов? - person alex; 08.10.2010
comment
если это так, я оставлю вас и с этим вопросом. "values" !== "&#118;&#97;&#108;&#117;&#101;&#115;" ? ;) - person Reigel; 08.10.2010
comment
Случаи @Reigel Edge всегда приветствуются :) Я думаю, это нужно будет задокументировать, однако это все еще изменение, даже если оно может показаться не таковым с точки зрения конечного пользователя. Кроме того, как часто JavaScript будет обновлять td закодированными символами? - person alex; 08.10.2010
comment
@Алекс. хаха хороший вопрос. и сколько раз с вами случалось, что вы должны изменить length из innerHTML напрямую. хе-хе - person Reigel; 08.10.2010
comment
@Reigel Я думаю, вы неправильно поняли меня выше ('bob'.length === 'tom'.length). Это то, к чему я стремился. Хотя сравнение будет быстрее, оно будет не совсем точным ;). - person alex; 08.10.2010
comment
@alex ааа, хороший улов! .. и я тоже думал о if (td.html().length !== tdHtml.length) { changed happened } else if (td.html() !== tdHtml) { changed happened }, поэтому, если длина не равна, нет необходимости проверять ее значение. ;) - person Reigel; 08.10.2010
comment
@Reigel О, да, я понял. :) Ну да, это было бы быстрее, но пахнет микрооптимизацией. Я думаю, было бы полезно, если бы ваш интервал setInterval был примерно 10 микросекунд :). - person alex; 08.10.2010
comment
@Алекс. ха-ха с 10 microseconds, интересно, как он отреагирует, если длина сравниваемых символов будет (скажем) Thousands или больше. И делать это без использования comparing of length's ;) - person Reigel; 08.10.2010
comment
Что ж, это слишком много символов для td. Интересно, как JavaScript хранит строки, если он сохраняет длину вместе, то это будет намного быстрее, но также будет медленнее, если ему нужно найти символ конца строки (хотя я не думаю, что это так). - person alex; 08.10.2010
comment
Спасибо, это работает, как и ожидалось! jQuery настолько упрощает работу с JS, что я всегда забываю основы. - person roflwaffle; 08.10.2010
comment
Обрабатывает ли это все случаи, когда содержимое изменилось? Работает ли это, если таблица уже загружена, а пользователь меняет содержимое? - 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