使用keyup,keydown和keypress进行计时

时间:2018-02-07 05:23:52

标签: javascript jquery events event-handling

我在实现建议文本的游戏的聊天栏中制作用户标记方法。当玩家键入“@”后跟字母/数字时,建议的用户名将突出显示并选中,如Google搜索栏那样排序。 我在下面有一个简单的演示。

我的问题是事件监听器的时间。我想使用“按键”事件,以便只有可打印的字符提示建议,但是在按下的按键呈现之前插入并选择了建议,导致建议立即被删除。在我的演示中,我默认返回“keyup”,但现在有一个明显的滞后和不可打印的键触发事件(使用箭头进行退格/删除和导航不可能)。

如何同时获得正确的时间并阻止不可打印的字符?

var users = ["benjamin", "nick", "joe", "tyler"];

$input = $("#input");

$input.focus();
$input.on("keyup", function() {
	var message = $input.text();
  var pattern = /^[@]([a-zA-Z0-9]{1,16})$/;
  
  if(pattern.test(message)) {
    var username = pattern.exec(message);
    var matches = [];
    
    
        
    users.forEach(function(element) {
    	if(element.indexOf(username[1]) == 0) matches.push(element);
    });
    
    if(matches.length) {
      $input.text("@" + matches[0]);
      
      var textNode = $input.get(0).childNodes[0];
      
      var range = document.createRange();
      range.setStart(textNode, message.length);
      range.setEnd(textNode, matches[0].length + 1);
      
      var selection = window.getSelection();
      selection.removeAllRanges();
      selection.addRange(range);
    }
  }
  
});
#input {
  border: 2px solid black;
  padding: 2px 4px;
  width: 200px;
  box-sizing: border-box;
}
#input:focus {
  outline: none;
  box-shadow: 5px 5px 5px #aaa;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="input" contenteditable="true"></div>

1 个答案:

答案 0 :(得分:0)

我发现了一些可以顺利运作的内容,但它只适用于内容可编辑<div>而不是<input>

var users = ["benjamin", "nick", "joe", "tyler"];

$input = $("#input");

$input.focus();
$input.on("keypress", function(event) {
	var highlight = window.getSelection().toString();
	var message = $input.text();
  message = message.replace(highlight, "");
  message += event.key;
  var pattern = /^[@]([a-zA-Z0-9]{1,16})$/;
  
  if(pattern.test(message)) {
    var username = pattern.exec(message);
    var matches = [];
    
    
        
    users.forEach(function(element) {
    	if(element.indexOf(username[1]) == 0) matches.push(element);
    });
    
    if(matches.length) {
        event.preventDefault();
      	$input.text("@" + matches[0]);

        var textNode = $input.get(0).childNodes[0];

        var range = document.createRange();
        range.setStart(textNode, message.length);
        range.setEnd(textNode, matches[0].length + 1);

        var selection = window.getSelection();
        selection.removeAllRanges();
        selection.addRange(range);
    }
  }
});
#input {
  border: 2px solid black;
  padding: 2px 4px;
  width: 200px;
  box-sizing: border-box;
}
#input:focus {
  outline: none;
  box-shadow: 5px 5px 5px #aaa;
}
#input::selection {
  background-color: #d8d8d8;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="input" contenteditable="true"></div>