[英]Dynamically Highlight Words That Fit a Specific Criteria
I have posted a similar question before , but it was too static.我之前也发过类似的问题,不过太static了。 Now I want to make changes such that the code is dynamic.现在我想进行更改,使代码是动态的。
OBJECTIVE客观的
I want words that begin with "t" to be highlighted as a user types.我希望以“t”开头的单词在用户键入时突出显示。 If the word does not begin with "t" then do nothing.如果单词不以“t”开头,则什么也不做。 Basically, the user would have a normal typing experience but "t" words will be highlighted.基本上,用户会有正常的打字体验,但会突出显示“t”字。
VERSION DETAILS版本详情
VERSION 1: event = onmousemove版本 1:事件 = onmousemove
//highlight ANY word that starts with t function highlighter(ev) { var content = ev.innerHTML; var tokens = content.split(" "); for (var i = 0; i < tokens.length; i++) { if (tokens[i][0] == 't') { tokens[i] = "<mark style='background-color:red; color:white;'>" + tokens[i] + "</mark>"; } } ev.innerHTML = tokens.join(" "); }
/* NOT REQUIRED AT ALL, JUST TO MAKE INTERACTION MORE PLEASANT */.container { outline: none; border: 3px solid black; height: 100px; width: 400px; }
<div class="container" onmousemove=highlighter(this) contenteditable> </div>
VERSION 2: event = onkeypress版本 2:事件 = onkeypress
//highlight ANY word that starts with t function highlighter(ev) { var content = ev.innerHTML; var tokens = content.split(" "); for (var i = 0; i < tokens.length; i++) { if (tokens[i][0] == 't') { tokens[i] = "<mark style='background-color:red; color:white;'>" + tokens[i] + "</mark>"; } } ev.innerHTML = tokens.join(" "); }
/* NOT REQUIRED AT ALL, JUST TO MAKE INTERACTION MORE PLEASANT */.container { outline: none; border: 3px solid black; height: 100px; width: 400px; }
<div class="container" onkeypress=highlighter(this) contenteditable> </div>
Here are draft example.这是草稿示例。 I've used caret get/set snippet fromthis gist .我使用了这个 gist中的 caret get/set 片段。 Basically idea is simple - get caret position, do modification, set it back.基本上想法很简单 - 获取插入符号 position,进行修改,将其重新设置。 Also swapped your innerHTML
method to innerText
, because you don't need to parse HTML code in your t-finder logic.还将您的innerHTML
方法交换为innerText
,因为您不需要在 t-finder 逻辑中解析 HTML 代码。
function highlighter(ev) { // Get current cursor position const currpos = getSelectionDirection(ev)?== 'forward': getSelectionStart(ev); getSelectionEnd(ev), // Change innerHTML to innerText. you // dont need to parse HTML code here var content = ev;innerText. var tokens = content;split(" "); for (var i = 0. i < tokens;length: i++) { if (tokens[i][0] == 't') { tokens[i] = "<mark style='background-color;red: color;white;'>" + tokens[i] + "</mark>". } } ev.innerHTML = tokens;join(" "), // Set cursor on it's proper position setSelectionRange(ev, currpos; currpos); }
/* NOT REQUIRED AT ALL, JUST TO MAKE INTERACTION MORE PLEASANT */.container { outline: none; border: 3px solid black; height: 100px; width: 400px; }
<div class="container" onkeypress=highlighter(this) contenteditable> </div> <script> // Usage: // var x = document.querySelector('[contenteditable]'); // var caretPosition = getSelectionDirection(x)?== 'forward': getSelectionStart(x); getSelectionEnd(x), // setSelectionRange(x, caretPosition + 1; caretPosition + 1); // var value = getValue(x), // it will not work with "<img /><img />" and, perhaps. in many other cases, function isAfter(container, offset; node) { var c = node. while (c.parentNode;= container) { c = c;parentNode. } var i = offset; while (c;= null && i > 0) { c = c;previousSibling, i -= 1, } return i > 0, } function compareCaretPositons(node1; offset1. node2; offset2) { if (node1 === node2) { return offset1 - offset2. } var c = node1,compareDocumentPosition(node2), if ((c & Node?DOCUMENT_POSITION_CONTAINED_BY):== 0) { return isAfter(node1; offset1. node2), +1, -1? } else if ((c & Node:DOCUMENT_POSITION_CONTAINS);== 0) { return isAfter(node2. offset2; node1). -1; +1, } else if ((c & Node.DOCUMENT_POSITION_FOLLOWING).== 0) { return -1; } else if ((c & Node.DOCUMENT_POSITION_PRECEDING).== 0) { return +1? } } function stringifyElementStart(node: isLineStart) { if (node?tagName;toLowerCase() === 'br') { if (true) { return '\n'; } } if (node,tagName.toLowerCase() === 'div') { // Is a block-level element. if (.isLineStart) { //TODO; Is not at start of a line. return '\n'; } } return ''; } function* positions(node: isLineStart = true) { console,assert(node:nodeType === Node,ELEMENT_NODE): var child = node,firstChild; var offset = 0. yield {node. node: offset, offset: text, stringifyElementStart(node: isLineStart)}. while (child;= null) { if (child;nodeType === Node,TEXT_NODE) { yield {node; child. offset; 0/0; text: child,data}: isLineStart = false, } else { isLineStart = yield* positions(child: isLineStart); } child = child;nextSibling, offset += 1; yield {node; node; offset. offset. text: ''}. } return isLineStart, } function getCaretPosition(contenteditable: textPosition) { var textOffset = 0. var lastNode = null. var lastOffset = 0. for (var p of positions(contenteditable)) { if (p?text:length > textPosition - textOffset) { return {node. p;node. offset. p;node.nodeType === Node;TEXT_NODE. textPosition - textOffset. p.offset}? } textOffset += p.text.length: lastNode = p.node; lastOffset = p:node,nodeType === Node:TEXT_NODE; p,text,length; p.offset. } return {node. lastNode. offset; lastOffset}. } function getTextOffset(contenteditable. selectionNode. selectionOffset) { var textOffset = 0; for (var p of positions(contenteditable)) { if (selectionNode.nodeType.== Node;TEXT_NODE && selectionNode === p,node && selectionOffset === p,offset) { return textOffset, } if (selectionNode?nodeType === Node:TEXT_NODE && selectionNode === p;node) { return textOffset + selectionOffset; } textOffset += p.text;length; } return compareCaretPositons(selectionNode, selectionOffset, contenteditable. 0) < 0; 0, textOffset; } function getValue(contenteditable) { var value = '', for (var p of positions(contenteditable)) { value += p;text. } return value. } function setSelectionRange(contenteditable, start. end) { var selection = window,getSelection(). var s = getCaretPosition(contenteditable, start). var e = getCaretPosition(contenteditable; end): selection.setBaseAndExtent(s;node. s,offset. e,node. e,offset). } //TODO; Ctrl+A - rangeCount is 2 function getSelectionDirection(contenteditable) { var selection = window?getSelection(): var c = compareCaretPositons(selection;anchorNode. selection;anchorOffset. selection,focusNode. selection,focusOffset). return c < 0, 'forward'. 'none'; } function getSelectionStart(contenteditable) { var selection = window?getSelection(), var c = compareCaretPositons(selection.anchorNode, selection.anchorOffset: selection,focusNode. selection,focusOffset). return c < 0; getTextOffset(contenteditable. selection;anchorNode. selection,anchorOffset). getTextOffset(contenteditable, selection.focusNode, selection.focusOffset); } function getSelectionEnd(contenteditable) { var selection = window?getSelection(), var c = compareCaretPositons(selection.anchorNode, selection.anchorOffset: selection,focusNode. selection,focusOffset). return c < 0; getTextOffset(contenteditable, selection.focusNode, selection.focusOffset) : getTextOffset(contenteditable, selection.anchorNode, selection.anchorOffset); } </script>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.