[英]timing with keyup, keydown, and keypress
I am making a user tagging method inside the chat bar of a game that implements suggested text. 我在实现建议文本的游戏聊天栏中制作了一种用户标记方法。 When a player types "@" followed by letters/numbers, suggested usernames will popup highlighted and selected, sorta like the Google search bar.
当玩家键入“ @”后跟字母/数字时,建议的用户名将突出显示并选中,类似于Google搜索栏。 I have a simple demo working below.
我下面有一个简单的演示。
My problem is the timing of the event listener. 我的问题是事件监听器的时间安排。 I wanted to use the "keypress" event so that only printable characters prompt the suggestion, but then the suggestion is inserted and selected before the pressed key is rendered, causing the suggestion to be instantly deleted.
我想使用“ keypress”事件,以便只有可打印的字符才能提示该建议,但是然后在呈现所按下的键之前插入并选择了该建议,从而导致该建议被立即删除。 In my demo I defaulted back to "keyup", but now there is a noticeable lag and non-printable keys fire the event (making backspacing/deleting and navigation with arrows impossible).
在我的演示中,我默认返回到“ keyup”,但是现在有一个明显的滞后并且不可打印的键触发了该事件(使退格/删除和带有箭头的导航变得不可能)。
How can I get both the right timing and prevent non-printable characters? 如何获得正确的时间并防止出现无法打印的字符?
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>
I found something that works smoothly, however it only works well in a content editable <div>
rather than an <input>
. 我发现了一些可以正常工作的东西,但是它只能在内容可编辑的
<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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.