首页 文章

使用JQuery检测对<input type =“text”>(立即)的所有更改

提问于
浏览
359

<input type="text"> 的 Value 可以通过多种方式改变,包括:

  • 按键

  • 复制/粘贴

  • 用JavaScript修改

  • 由浏览器或工具栏自动完成

我希望我的JavaScript函数在任何时候都会被调用(使用当前输入值) . 我希望它立即被调用,而不仅仅是当输入失去焦点时 .

我正在寻找在所有浏览器中执行此操作的最干净,最强大的方法(最好使用jQuery) .

示例用例:在Twitter Signup页面上,用户名字段的值显示在其下方的URL“http://twitter/ username”中 .

16 回答

  • 94

    这个jQuery代码捕获任何元素的即时更改,并且应该适用于所有浏览器:

    $('.myElements').each(function() {
       var elem = $(this);
    
       // Save current value of element
       elem.data('oldVal', elem.val());
    
       // Look for changes in the value
       elem.bind("propertychange change click keyup input paste", function(event){
          // If value has changed...
          if (elem.data('oldVal') != elem.val()) {
           // Updated stored value
           elem.data('oldVal', elem.val());
    
           // Do action
           ....
         }
       });
     });
    
  • -2

    jQuery> = 1.9的实时奇特解决方案

    $("#input-id").on("change keyup paste", function(){
        dosomething();
    })
    

    如果您还想检测“点击”事件,只需:

    $("#input-id").on("change keyup paste click", function(){
        dosomething();
    })
    

    如果你使用jQuery <= 1.4,只需使用 live 而不是 on .

  • -3

    不幸的是,我认为 setInterval 获奖:

    <input type=text id=input_id />
    <script>
    setInterval(function() { ObserveInputValue($('#input_id').val()); }, 100);
    </script>
    

    它也是最强大的,因为您不必担心 input 可以获得值的所有不同事件/方式 .

    在这种情况下,使用'setInterval'的缺点似乎不适用:

    • The 100ms latency? 对于许多应用程序,100ms足够快 .

    • Added load on the browser? 一般来说,在页面上添加大量的重量级setIntervals是不好的 . 但在这种特殊情况下,添加的页面加载是不可检测的 .

    • It doesn't scale to many inputs? 大多数页面没有多少输入,您可以在同一个setInterval中嗅探所有输入 .

  • 1

    绑定到 oninput 事件似乎在大多数理智的浏览器中都能正常工作 . IE9也支持它,但实现是错误的(删除字符时不会触发事件) .

    使用jQuery 1.7版, on 方法可以像这样绑定到事件:

    $(".inputElement").on("input", null, null, callbackFunction);
    
  • 56

    2017 answerinput event确实适用于比IE8更近的任何内容 .

    $(el).on('input', callback)
    
  • 15

    遗憾的是,没有符合您条件的事件或事件集 . 可以使用 keyup 事件处理Keress和复制/粘贴 . 通过JS进行的更改比较棘手 . 如果您可以控制设置文本框的代码,最好将其修改为直接调用函数或触发文本框上的用户事件:

    // Compare the textbox's current and last value.  Report a change to the console.
    function watchTextbox() {
      var txtInput = $('#txtInput');
      var lastValue = txtInput.data('lastValue');
      var currentValue = txtInput.val();
      if (lastValue != currentValue) {
        console.log('Value changed from ' + lastValue + ' to ' + currentValue);
        txtInput.data('lastValue', currentValue);
      }
    }
    
    // Record the initial value of the textbox.
    $('#txtInput').data('lastValue', $('#txtInput').val());
    
    // Bind to the keypress and user-defined set event.
    $('#txtInput').bind('keypress set', null, watchTextbox);
    
    // Example of JS code triggering the user event
    $('#btnSetText').click(function (ev) {
      $('#txtInput').val('abc def').trigger('set');
    });
    

    如果您无法控制该代码,可以使用 setInterval() 来'watch'文本框进行更改:

    // Check the textbox every 100 milliseconds.  This seems to be pretty responsive.
    setInterval(watchTextbox, 100);
    

    如果你需要观察大量的输入,那么这种主动监控立刻就能很好地扩展.848751_ . 您始终可以将第二个参数调整为 setInterval() 以进行更频繁或更低频率的检查 .

  • 3

    如果你不喜欢任何其他答案,这里有一个稍微不同的解决方案:

    var field_selectors = ["#a", "#b"];
    setInterval(function() { 
      $.each(field_selectors, function() { 
        var input = $(this);
        var old = input.attr("data-old-value");
        var current = input.val();
        if (old !== current) { 
          if (typeof old != 'undefined') { 
            ... your code ...
          }
          input.attr("data-old-value", current);
        }   
      }   
    }, 500);
    

    考虑到您不能依靠点击和键盘来捕获上下文菜单粘贴 .

  • -4

    我创建了一个样本 . 愿它适合你 .

    var typingTimer;
    var doneTypingInterval = 10;
    var finaldoneTypingInterval = 500;
    
    var oldData = $("p.content").html();
    $('#tyingBox').keydown(function () {
        clearTimeout(typingTimer);
        if ($('#tyingBox').val) {
            typingTimer = setTimeout(function () {
                $("p.content").html('Typing...');
            }, doneTypingInterval);
        }
    });
    
    $('#tyingBox').keyup(function () {
        clearTimeout(typingTimer);
        typingTimer = setTimeout(function () {
            $("p.content").html(oldData);
        }, finaldoneTypingInterval);
    });
    
    
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    
    
    <textarea id="tyingBox" tabindex="1" placeholder="Enter Message"></textarea>
    <p class="content">Text will be replace here and after Stop typing it will get back</p>
    

    http://jsfiddle.net/utbh575s/

  • 325

    实际上,我们不需要设置循环来检测javaScript更改 . 我们已经为要检测的元素设置了许多事件监听器 . 只是触发任何无害的事件都会成功 .

    $("input[name='test-element']").on("propertychange change click keyup input paste blur", function(){
    console.log("yeh thats worked!");
    });
    
    $("input[name='test-element']").val("test").trigger("blur");
    

    并且只有在您对项目的javascript更改有完全控制权时才能使用此功能 .

  • 1

    在某处添加此代码,这将解决问题 .

    var originalVal = $.fn.val;
    $.fn.val = function(){
        var result =originalVal.apply(this,arguments);
        if(arguments.length>0)
            $(this).change(); // OR with custom event $(this).trigger('value-changed');
        return result;
    };
    

    val() doesn't trigger change() in jQuery找到了这个解决方案

  • 6

    那么,最好的办法是覆盖你自己列出的三个基地 . 一个简单的:onblur,:onkeyup等不适用于你想要的东西,所以只需将它们组合起来 .

    KeyUp应该涵盖前两个,如果Javascript正在修改输入框,我确定希望它是你自己的javascript,所以只需在修改它的函数中添加一个回调 .

  • 3

    这是一个工作示例,我用来实现自动完成变体,填充jqueryui选择器(列表),但我不希望它的功能与jqueryui自动完成功能完全相同,后者执行下拉菜单 .

    $("#tagFilter").on("change keyup paste", function() {
         var filterText = $("#tagFilter").val();
        $("#tags").empty();
        $.getJSON("http://localhost/cgi-bin/tags.php?term=" + filterText,
            function(data) {
                var i;
                for (i = 0; i < data.length; i++) {
                    var tag = data[i].value;
                    $("#tags").append("<li class=\"tag\">" + tag + "</li>");
                }
            }); 
    });
    
  • 3

    你不能只用 <span contenteditable="true" spellcheck="false"> 元素代替 <input type="text"> 吗?

    <span>contenteditable="true" spellcheck="false" 作为属性)由 <input> 区分主要是因为:

    • 它的风格不像 <input> .

    • 它没有 value 属性,但文本呈现为 innerText 并成为其内部主体的一部分 .

    • 它是多行的,而 <input> 不是你设置属性 multiline="true" .

    当然,为了实现外观,您可以在CSS中设置样式,而将值写为 innerText 则可以获得一个事件:

    这是一个fiddle .

    不幸的是,有些东西在IE和Edge中实际上并不起作用,我无法找到它 .

  • 26

    您可以看到此示例并选择您感兴趣的事件:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script> 
    <title>evetns</title>
    </head>
    <body>
    <form>
        <input class="controlevents" id="i1" type="text" />
    <input class="controlevents" id="i2" type="text" />
    <input class="controlevents" id="i3" type="text" />
    <input class="controlevents" id="i4" type="text" />
    <input class="controlevents" id="i5" type="text" />
    </form> <div id="datatext"></div> </body> </html> <script> $(function(){ function testingevent(ev){ if (ev.currentTarget.tagName=="INPUT") $("#datatext").append("<div>id : " + ev.currentTarget.id + ", tag: " + ev.currentTarget.tagName + ", type: "+ ev.type +"</div>"); } var eventlist = ["resizeend","rowenter","dragleave","beforepaste","dragover","beforecopy","page","beforeactivate","beforeeditfocus","controlselect","blur", "beforedeactivate","keydown","dragstart","scroll","propertychange","dragenter","rowsinserted","mouseup","contextmenu","beforeupdate", "readystatechange","mouseenter","resize","copy","selectstart","move","dragend","rowexit","activate","focus","focusin","mouseover","cut", "mousemove","focusout","filterchange","drop","blclick","rowsdelete","keypress","losecapture","deactivate","datasetchanged","dataavailable", "afterupdate","mousewheel","keyup","movestart","mouseout","moveend","cellchange","layoutcomplete","help","errorupdate","mousedown","paste", "mouseleave","click","drag","resizestart","datasetcomplete","beforecut","change","error","abort","load","select"]; var inputs = $(".controlevents"); $.each(eventlist, function(i, el){ inputs.bind(el, testingevent); }); }); </script>
  • 110

    我可能在这里参加聚会,但你不能只使用jQuery提供的.change()事件 .

    你应该可以做类似......

    $(#CONTROLID).change(function(){
        do your stuff here ...
    });
    

    你总是可以将它绑定到控件列表中,例如...

    var flds = $("input, textarea", window.document);
    
    flds.live('change keyup', function() {
        do your code here ...
    });
    

    实时 Binders 可确保处理现在和将来页面上存在的所有元素 .

  • 0

    这是最快速,最干净的方法:

    我正在使用Jquery - >

    $('selector').on('change', function () {
        console.log(this.id+": "+ this.value);
    });
    

    它对我来说很好 .

相关问题