【问题标题】:Jquery text change eventJquery 文本更改事件
【发布时间】:2011-10-09 21:53:42
【问题描述】:

我需要在文本框的内容发生变化时触发一个事件。

我不能使用 keyup,也不能使用 keypress

如果你按住键,keyup 和 keydown 不起作用。

在文本实际更改之前触发按键。它也不识别退格或删除。

所以现在我假设我将不得不构建一些自定义逻辑或下载插件。那里有插件吗?或者如果我应该构建一个,我应该注意哪些限制?

例如。 Facebook 通过顶部的搜索来做到这一点。你可以长按。

另一个例子是写一个stackoverflow问题。在编辑器的正下方,内容被实时复制,退格和一切正常工作。他们是怎么做到的?

【问题讨论】:

标签: javascript jquery


【解决方案1】:

我刚刚查看了 SO 的来源。看起来他们做的事情很像this:

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

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

他们做了一些额外的事情来为粗体、斜体和链接等制作 HTML 标记,然后他们计时。如果生成 HTML 的时间过长,它们会将延迟从 1 增加到更长。

【讨论】:

  • 嗨,它对我来说效果很好,除了按键事件之外,您还可以添加粘贴事件来检测所有像这样的文本更改。 $('textarea').bind('paste', function(){ setTimeout(updatePreview, 1); } );​
【解决方案2】:

我成功使用了 jQuery(在 Chrome 中)。如果您按住一个键,它会计算每一个更改,而不仅仅是第一个更改,它还会计算非打印键,例如退格键。

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);

    }
});

就像我上面所说的,您需要过滤掉所有不改变文本的键码,例如 ctrlshift altenter 等。如果在文本框为空时按backspacedelete 键或如果文本框有最大长度并且按下了可打印的键,但处理这些也不是很困难。

这是一个有效的jsfiddle example

【讨论】:

    【解决方案3】:

    来个民意调查怎么样?执行setInterval 并调用一个检查文本的函数,每 500 毫秒说一次?无论如何,您都不想检测每个键上的内容更改,因为它在某些较旧的浏览器/较旧的计算机中变得有点慢,并且您会注意到键入和显示文本之间存在延迟。

    【讨论】:

      【解决方案4】:

      你需要一个观察者类型的功能。

      如果其他功能不可用,它会使用 setInterval 轮询:http://james.padolsey.com/javascript/monitoring-dom-properties/

      【讨论】:

        【解决方案5】:

        我有一个简单的解决方案,我们很乐意在我们的一个项目中使用它。

        你可以试试@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);
        

        【讨论】:

          【解决方案6】:

          Zurb 有一个很棒的插件,可能对你有用 http://www.zurb.com/playground/jquery-text-change-custom-event

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-01-26
            • 2011-08-28
            • 2017-04-14
            • 2011-10-24
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多