文本突出显示(从头开始)输出问题
text highlighting (from scratch) output issue
我正在尝试使用在 keyup 上调用函数的文本区域和用于输出结果(highlighted/colored 文本)的 div 构建一个简单的彩色荧光笔。
要突出显示的单词及其关联的颜色存储在此对象中:
var obj = {
"to": "green",
"code": "red",
"applet": "blue"
}
然后将输入字符串拆分为单词单元,以检查它们是否与 obj
键匹配。
var splitRequest = input.value.toLowerCase().split(' ');
如果是,则应突出显示。我写了一个简单的代码来完成这个技巧(见最后的 fiddle),除了这一行:
output.innerHTML += '<span style="color:' + obj[splitRequest[i]] + '">' + splitRequest[i] + " </span>";
它会在每次按键时打印整个文本,而不是因为 +=
符号而用新内容替换当前内容。问题是我不能简单地使用 =
符号,因为它只会打印 splitRequest
数组的第一个元素而不是整个数组。我尝试使用 join()
方法,但它显然没有像我预期的那样工作 (test)。
也许代码本身不是很好,我应该使用另一种方法来让它工作。这将是更好地学习 javascript 的好方法,但实际上我不知道该怎么做。
如何在突出显示匹配词的同时输出用户输入的文本而不会出现此问题?
这是我卡住的工作演示:https://jsfiddle.net/Lau1989/9oL7umtt/1/
感谢您的帮助
PS :我知道有第三方可用于语法高亮显示,但为了自学,我正在尝试使用纯 javascript 从头开始编码(没有 jQuery).
添加
output.innerHTML = "";
在
之后
var output = document.getElementById('output');
第 9 行
这是一个可行的解决方案
var obj = {
"to": "green",
"code": "red",
"applet": "blue"
}
function highlight() {
var input = document.getElementById('input');
var output = document.getElementById('output'),
pattern = /\s+(to|code|applet)(?=\s+)/gi;
output.innerHTML = input.value.replace(pattern, function (x) {
return "<span style=\"color:" + obj[x.toLowerCase().trim()] +
"\"> " + x + "</span>" });
}
你可以用这个。
变量对象 = {
"to": "green",
"code": "red",
"applet": "blue"
}
props = [];
for (var p in obj) {
props.push(p);
}
var pat = new RegExp("\s+(" + props.join("|") + ")(?=\s+)", "gi");
alert(pat);
function highlight() {
var input = document.getElementById('input');
var output = document.getElementById('output');
output.innerHTML = input.value.replace(pat, function (x) { return "<span style=\"color:" + obj[x.toLowerCase().trim()] + "\"> " + x + "</span>" });
}
这里是 ES2015/ES6 样式的示例,使用 map/reduce 和字符串模板。
'use strict'
const obj = {
"to": "green",
"code": "red",
"applet": "blue"
}
const output = document.getElementById('output')
document.getElementById('input')
.addEventListener('keyup', highlight)
/**
* Process text and provides provides that text in output control
*/
function highlight() {
output.innerHTML = processText(input.value.toLowerCase())
}
/**
* Process text and returns formatted HTML text to be displayed
*
* @param {string} text - text to be processed
* @return {string} - formatted HTML text
*/
function processText(text) {
return text.split(' ')
.map(x => obj[x] ? `<span style="color: ${obj[x]}">${x}</span>` : x)
.reduce((prev, cur) => `${prev} ${cur}`)
}
/**
* Trigger first time hightlight function
* so it will highlight text if there is any text in input contol
*/
highlight()
textarea {
padding: 10px;
}
div {
width: 235px;
height: 80px;
border: 1px solid black;
padding: 10px;
overflow: auto;
color: black;
}
<textarea cols="30" rows="5" id="input" autofocus>To code or not to code this Applet</textarea>
<div id="output"></div>
我正在尝试使用在 keyup 上调用函数的文本区域和用于输出结果(highlighted/colored 文本)的 div 构建一个简单的彩色荧光笔。
要突出显示的单词及其关联的颜色存储在此对象中:
var obj = {
"to": "green",
"code": "red",
"applet": "blue"
}
然后将输入字符串拆分为单词单元,以检查它们是否与 obj
键匹配。
var splitRequest = input.value.toLowerCase().split(' ');
如果是,则应突出显示。我写了一个简单的代码来完成这个技巧(见最后的 fiddle),除了这一行:
output.innerHTML += '<span style="color:' + obj[splitRequest[i]] + '">' + splitRequest[i] + " </span>";
它会在每次按键时打印整个文本,而不是因为 +=
符号而用新内容替换当前内容。问题是我不能简单地使用 =
符号,因为它只会打印 splitRequest
数组的第一个元素而不是整个数组。我尝试使用 join()
方法,但它显然没有像我预期的那样工作 (test)。
也许代码本身不是很好,我应该使用另一种方法来让它工作。这将是更好地学习 javascript 的好方法,但实际上我不知道该怎么做。
如何在突出显示匹配词的同时输出用户输入的文本而不会出现此问题?
这是我卡住的工作演示:https://jsfiddle.net/Lau1989/9oL7umtt/1/
感谢您的帮助
PS :我知道有第三方可用于语法高亮显示,但为了自学,我正在尝试使用纯 javascript 从头开始编码(没有 jQuery).
添加
output.innerHTML = "";
在
之后var output = document.getElementById('output');
第 9 行
这是一个可行的解决方案
var obj = {
"to": "green",
"code": "red",
"applet": "blue"
}
function highlight() {
var input = document.getElementById('input');
var output = document.getElementById('output'),
pattern = /\s+(to|code|applet)(?=\s+)/gi;
output.innerHTML = input.value.replace(pattern, function (x) {
return "<span style=\"color:" + obj[x.toLowerCase().trim()] +
"\"> " + x + "</span>" });
}
你可以用这个。 变量对象 = { "to": "green", "code": "red", "applet": "blue" }
props = [];
for (var p in obj) {
props.push(p);
}
var pat = new RegExp("\s+(" + props.join("|") + ")(?=\s+)", "gi");
alert(pat);
function highlight() {
var input = document.getElementById('input');
var output = document.getElementById('output');
output.innerHTML = input.value.replace(pat, function (x) { return "<span style=\"color:" + obj[x.toLowerCase().trim()] + "\"> " + x + "</span>" });
}
这里是 ES2015/ES6 样式的示例,使用 map/reduce 和字符串模板。
'use strict'
const obj = {
"to": "green",
"code": "red",
"applet": "blue"
}
const output = document.getElementById('output')
document.getElementById('input')
.addEventListener('keyup', highlight)
/**
* Process text and provides provides that text in output control
*/
function highlight() {
output.innerHTML = processText(input.value.toLowerCase())
}
/**
* Process text and returns formatted HTML text to be displayed
*
* @param {string} text - text to be processed
* @return {string} - formatted HTML text
*/
function processText(text) {
return text.split(' ')
.map(x => obj[x] ? `<span style="color: ${obj[x]}">${x}</span>` : x)
.reduce((prev, cur) => `${prev} ${cur}`)
}
/**
* Trigger first time hightlight function
* so it will highlight text if there is any text in input contol
*/
highlight()
textarea {
padding: 10px;
}
div {
width: 235px;
height: 80px;
border: 1px solid black;
padding: 10px;
overflow: auto;
color: black;
}
<textarea cols="30" rows="5" id="input" autofocus>To code or not to code this Applet</textarea>
<div id="output"></div>