【问题标题】:Remove one-sample capture delay in .keydown()删除 .keydown() 中的单样本捕获延迟
【发布时间】:2015-01-15 11:08:05
【问题描述】:

出于特殊原因,我使用 JQuery 的 keydown() 事件来过滤隐藏输入字段中的击键。然后输入字段的值被复制到可见的 div 中。问题是由于某种原因,我按下的键在下次按下键时被复制到 div,这意味着输入延迟了一个周期。

我已经尝试过 keyup() 并且这个确实有效,但是我不喜欢在释放键时更新值的行为。如何在保持 keydown() 的同时即时更新?

var wordInput = '';

$('#input').keydown(function(event) {
    var keycode = event.which;
    switch(keycode) {
    	// Enter key
    	case 13: 	
    		console.log('Submit');
	    // Space key
        case 32: 	
        	console.log('Space disabled');
        	break;
    	// Backspace
    	case 8:
            // Subscract the last char
            wordInput = wordInput.substr(0, wordInput.length - 1);
    		break;
    	// Any other key
		default: 	
			// If char limit not exceeded
			if (wordInput.length < 20) {
                wordInput += $('#input').val(); // Add the typed letter
            }             
    }
    // Update the word displayed
    $('#story-input').html(wordInput);
    // Clear the  input
    $('#input').val('');
});

在此处查看示例:http://jsfiddle.net/mqbxqLp7/

【问题讨论】:

    标签: javascript jquery keydown


    【解决方案1】:

    这是因为事件首先被触发并由您的代码处理,然后字符被添加到输入字段中。这使得$('#input').val() 返回之前输入的字符。

    您可以使用String.fromCharCode(event.which),但这不会区分不同的大小写,您必须解析事件对象以获取修饰键并将字符转换为正确的大小写。


    另一种解决方案是使用.keydown 来处理您现在所做的特殊键,并使用.keypress 来处理字符键。原因是.keypress 没有注册某些键,例如退格键。

    这结合了“两全其美”,它会立即处理所有事件,您无需担心解析字符以使用正确的大小写。

    使用此代码或查看jsfiddle 上的(固定)示例。

    $('#input').keydown(function(event) {
        var prevent = true;
        switch(event.which) {
            // Enter key
            case 13:    
                console.log('Submit');
            // Space key
            case 32:    
                console.log('Space disabled');
                break;
            // Backspace
            case 8:
                // Subscript the last char
                wordInput = wordInput.substr(0, wordInput.length - 1);
                break;
            // Any other key
            default:    
                prevent = false;
        }
        // Update the word displayed
        $('#story-input').html(wordInput);
        // Clear the  input
        $('#input').val('');
    
        // Stop event propagation, keypress will not be executed
        if(prevent)
            event.stopPropagation();
    });
    
    $('#input').keypress(function(event) {
        if (wordInput.length < 20) {
            wordInput += String.fromCharCode(event.which); // Add the typed letter
        }
        $('#story-input').html(wordInput);
    });
    

    【讨论】:

    • 对替代解决方案的评论:唯一的缺点是.keypress 在按住键时只注册一个字符,但我想你只使用了.keydown 用于退格,所以你可以按住它并通过一次按键删除多个字符。我认为常规键的.keydown 对常规键没有任何用处,因为用户在键入时按下每个键,他们(通常)不会按住它。
    • 不错! stopPropagation 是我需要的。那么,为了清楚起见,为什么按键会在之后发生?仅仅是因为它在keydown代码下面吗?
    • 不,这是因为键盘事件是如何工作的。按照这个link 阅读更多关于键盘事件的信息。请注意,这不仅适用于 jquery 或 javascript,它是键盘事件在系统范围内的工作方式。它是keydown -> keypress -> keyup,由操作系统处理,程序或编程语言无法覆盖此事件序列。顺便说一句,如果这个答案对你有帮助,请采纳,我将不胜感激。
    • 我不会认为顺序取决于操作系统。感谢您的帮助!
    • 现在的问题是移动 chrome 不支持按键 :(
    【解决方案2】:

    对于这种情况,jQuery 的keyup() 钩子可能更合适。这样,它只会在按键被释放后触发,并且值在输入框中。这应该使它更平滑,消除下一次按键触发上一次推送到该值,而不是在当前按键结束时触发。 (包含的 sn-p 中的演示。)

    var wordInput = '';
    
    $('#input').keyup(function(event) {
        var keycode = event.which;
        switch(keycode) {
        	// Enter key
        	case 13: 	
        		console.log('Submit');
    	    // Space key
            case 32: 	
            	console.log('Space disabled');
            	break;
        	// Backspace
        	case 8:
                // Subscract the last char
                wordInput = wordInput.substr(0, wordInput.length - 1);
        		break;
        	// Any other key
    		default: 	
    			// If char limit not exceeded
    			if (wordInput.length < 20) {
                    wordInput += $('#input').val(); // Add the typed letter
                }             
        }
        // Update the word displayed
        $('#story-input').html(wordInput);
        // Clear the  input
        $('#input').val('');
        
    });
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <div id="story-input">text</div>
    <input type="text" id="input" style="opacity: 1">

    但是,请注意,用户可以通过按住单个字符来绕过长度要求,因此检查wordInput 的长度与#input 值的长度之和可能是明智的。

    【讨论】:

      猜你喜欢
      • 2015-07-08
      • 2014-06-03
      • 1970-01-01
      • 2021-11-10
      • 2020-10-09
      • 2012-07-11
      • 1970-01-01
      • 2012-06-24
      • 2014-01-25
      相关资源
      最近更新 更多