【问题标题】:text highlighting (from scratch) output issue文本突出显示(从头开始)输出问题
【发布时间】:2024-01-21 13:32:01
【问题描述】:

我正在尝试使用 textarea 调用 keyup 上的函数和 div 来输出结果(突出显示/彩色文本)来构建一个简单的颜色荧光笔。

要突出显示的单词及其相关颜色存储在此对象中:

var obj = {
  "to": "green",
  "code": "red",
  "applet": "blue"
}

然后将输入字符串拆分为单词单元以检查它们是否与 obj 键匹配。

var splitRequest = input.value.toLowerCase().split(' ');

如果有,则应突出显示。我写了一个简单的代码来解决这个问题(见最后的小提琴),除了这一行:

output.innerHTML += '<span style="color:' + obj[splitRequest[i]] + '">' + splitRequest[i] + " </span>";

由于+= 符号,它会在每次按键时打印整个文本,而不是用新内容替换当前内容。问题是我不能简单地使用= 符号,因为它只会打印splitRequest 数组的第一个元素而不是整个数组。我尝试使用join() 方法,但它显然没有像我预期的那样工作(test)。

也许代码本身不是很好,我应该使用另一种方法来让它工作。这将是更好地学习 javascript 的好方法,但我实际上不知道如何做到这一点。

如何在突出匹配单词的同时输出用户输入的文本而不会出现此问题?

这是我遇到的工作演示:https://jsfiddle.net/Lau1989/9oL7umtt/1/

感谢您的帮助

PS:我知道有第三方可用于语法高亮显示,但为了自学,我尝试使用纯 javascript(无 jQuery)从头开始编写代码。

【问题讨论】:

  • &lt;font&gt; 标记已成为 deprecated in HTML 4.01。你不应该再使用它了。将其替换为:&lt;span style="color:..."&gt;...&lt;/span&gt;

标签: javascript highlighting


【解决方案1】:

添加

output.innerHTML = "";

之后

var output = document.getElementById('output');

第 9 行

https://jsfiddle.net/Lauy79kv/

【讨论】:

  • 天哪...我已经尝试过了,但将它添加到错误的行中(在 for 循环内)。现在可以正常使用了,谢谢!
  • 没问题。许多最困难的错误都是由最简单的事情引起的——这就是他们有 QA 的原因
【解决方案2】:

这是一个可行的解决方案

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>" });
}

【讨论】:

  • 很好的答案,我只是想在我的代码中使用 regExp。有没有办法使用变量而不是使用预定义的键使模式动态匹配对象属性?像 for (var prop in obj) { pattern = /\s+(/ + prop + /)(?=\s+)/gi; } 而不是 (to|code|applet) 这样的东西会很棒。由于我对 RegExp 还不太熟悉,因此我无法找到正确的语法。
  • 见答案
【解决方案3】:

你可以使用它。 变量 obj = { “到”:“绿色”, “红色代码”, “小程序”:“蓝色” }

    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>" });

    }

【讨论】:

    【解决方案4】:

    这里是 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>

    【讨论】: