Событие изменения текста Jquery - PullRequest
8 голосов
/ 21 июля 2011

Мне нужно инициировать событие всякий раз, когда содержимое текстового поля изменилось.

Я не могу использовать keyup , и я не могу использовать нажатие клавиши .

Keyup и keydown не работают, если вы удерживаете нажатой клавишу.

Нажатие клавиши срабатывает до того, как текст действительно изменится.Он не распознает ни возврат, ни удаление.

Так что теперь я предполагаю, что мне придется создать какую-то собственную логику или скачать плагин.Есть ли там плагины?Или, если я должен построить один, какие ограничения я должен искать?

Например.Facebook делает это с их поиском наверху.Вы можете нажать и удерживать.

еще один пример - написание вопроса о переполнении стека.Прямо под редактором, содержимое копируется в реальном времени, Backspace и все работает.Как они это делают?

Ответы [ 6 ]

16 голосов
/ 21 июля 2011

Я только что посмотрел на источник SO. Похоже, они делают что-то похожее на this :

function updatePreview(){
    $('div').text($('textarea').val());
}

$('textarea').bind('keypress', function(){
        setTimeout(updatePreview, 1);
    }
);​

Они делают некоторые дополнительные вещи, чтобы сделать HTML-теги жирным шрифтом, курсивом и ссылками, и тому подобное, и они рассчитывают это. Они увеличивают задержку с 1 до дольше, если генерация HTML занимает слишком много времени.

4 голосов
/ 21 июля 2011

Я успешно использовал jQuery (в Chrome).Если вы удерживаете клавишу нажатой, она подсчитывает каждое изменение, а не только первое, и подсчитывает непечатные ключи, например, клавишу Backspace.

HTML

<input id="txt" type="text" />
<span id="changeCount">0</span>

JavaScript

$('#txt').keydown(function(event) {
    // Don't count the keys which don't actually change
    // the text. The four below are the arrow keys, but
    // there are more that I omitted for brevity.
    if (event.which != 37 && event.which != 38 &&
        event.which != 39 && event.which != 40) {

        // Replace the two lines below with whatever you want to
        // do when the text changes.
        var count = parseInt($('#changeCount').text(), 10) + 1;
        $('#changeCount').text(count);

    }
});

Как я уже говорил выше, вы захотите отфильтровать все коды клавиш, которые не изменяют текст, например ctrl , shift , alt , , введите и т. Д. Существует также граничное условие, если вы нажимаете backspace или delete Клавиша, когда текстовое поле пустое или текстовое поле имеет максимальную длину и нажата клавиша для печати, но с этим тоже не сложно справиться.

Вот рабочий пример jsfiddle .

2 голосов
/ 21 июля 2011

Как насчет опроса? Сделайте setInterval и вызовите функцию, которая проверяет текст, скажем, каждые 500 мс? В любом случае вы не хотите обнаруживать изменение содержимого на каждом ключе, потому что в некоторых старых браузерах или на старых компьютерах оно работает довольно медленно, и вы заметили бы разрыв между набором текста и отображением текста.

1 голос
/ 01 июля 2012

Zurb имеет отличный плагин, который может быть полезен для вас http://www.zurb.com/playground/jquery-text-change-custom-event

1 голос
/ 21 июля 2011

У меня есть простое решение, которое мы успешно используем в одном из наших проектов.

можешь попробовать @ http://jsfiddle.net/zSFdp/17/

var i = 0;
$('#text').bind('check_changed', function(){
    var t = $(this);

    // do something after certain interval, for better performance
    delayRun('my_text', function(){
        var pv = t.data('prev_val');

        // if previous value is undefined or not equals to the current value then blablabla
        if(pv == undefined || pv != t.val()){
            $('#count').html(++i);
            t.data('prev_val', t.val());
        }
    }, 1000);
})
// if the textbox is changed via typing
.keydown(function(){$(this).trigger('check_changed')})
// if the textbox is changed via 'paste' action from mouse context menu
.bind('paste', function(){$(this).trigger('check_changed')});

// clicking the flush button can force all pending functions to be run immediately
// e.g., if you want to submit the form, all delayed functions or validations should be called before submitting. 
// delayRun.flush() is the method for this purpose
$('#flush').click(function(){ delayRun.flush(); });

Функция delayRun ()

;(function(g){
    var delayRuns = {};
    var allFuncs = {};

    g.delayRun = function(id, func, delay){
        if(delay == undefined) delay = 200;
        if(delayRuns[id] != null){
            clearTimeout(delayRuns[id]);
            delete delayRuns[id];
            delete allFuncs[id];
        }
        allFuncs[id] = func;
        delayRuns[id] = setTimeout(function(){
            func();
            delete allFuncs[id];
            delete delayRuns[id];
        }, delay);
    };

    g.delayRun.flush = function(){
        for(var i in delayRuns){
            if(delayRuns.hasOwnProperty(i)){
                clearTimeout(delayRuns[i]);
                allFuncs[i]();
                delete delayRuns[i];
                delete allFuncs[i];
            }
        }
    };
})(window);
1 голос
/ 21 июля 2011

Вам нужна функциональность типа наблюдателя.

Возвращается к опросу setInterval, если другие функции недоступны: http://james.padolsey.com/javascript/monitoring-dom-properties/

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...