【问题标题】:Emulating syntax highlighting with Javascript用 Javascript 模拟语法高亮
【发布时间】:2013-09-07 12:16:25
【问题描述】:

我正在尝试一些东西,真的只是为了一点乐趣,当代码输入网页上的文本区域时,我试图模拟语法突出显示。

我写了一个小 JS 脚本,但是它抛出了错误。 “无法设置未定义的属性‘颜色’。”

为此,我创建了一个包含一些示例“流行语”的小数组来搜索输入的代码。然后我将代码字符串拆分为一个数组并循环查找两者之间的匹配项。 我对拆分方法或搜索方法不太熟悉。我怎样才能得到任何发现在屏幕上实时改变颜色的匹配项?

function init() {

window.setInterval(function() {
    var code = document.getElementById("texty").value;
    var buzzword = ["function","()","{","}","[","]",".getElementById",".getElementsByClassName",".style","$"];
    for(i=0; i < buzzword.length; i++) 
    {
        var testers = code.split(" ");
        for(i =0; i < testers.length; i++) 
        {
            if(buzzword[i] == testers[i]) 
            {
                code.search(testers[i]);
                code.match(testers[i]).style.color = 'blue';
            }
        }
    }
}, 10000);

}

函数 init() 在 textarea 的焦点上执行。

任何帮助将不胜感激,谢谢!

【问题讨论】:

  • 任意字符串没有样式,它们不是 DOM 的一部分,它们只是数据。您不能将样式应用于文本区域值的随机子字符串。代码code.match(testers[i]).style.color = 'blue'; 永远不会起作用。
  • 继续@meagar 所说的,这就是为什么在格式化用户输入的网站上,通常有一个文本区域供您输入,然后另一个区域供您查看格式化输入的预览,例如stackoverflow 回答 textarea 和预览。
  • 这是一个很好的观点。关于将捕获文本区域中的某些单词并在单独的“预览”div 中将它们涂成蓝色的代码的任何想法?
  • @tinkerbot,我已经修改了我之前的错误答案以允许您这样做。

标签: javascript arrays search syntax


【解决方案1】:

我决定再试一次。正确地安静,我之前的答案被击落了。这是一些代码。我无法对其进行 jsfiddle 操作,但我已经对其进行了测试,并且效果很好:

一些 CSS:

<style> .blue { color: blue; } </style>

一些用于测试的 HTML:

<div id="div"></div>
<textarea id="area" onfocus="init()">
  function writeTo() {
    var id = document.getElementById('id');
    var class = document.getElementsByClass('class');
    id.style.color = 'blue';
    var $id = $('#id');
    var array = [];
    var obj = {};
  }
</textarea>

一些Javascript。这使用正则表达式而不是数组。它对流行语进行查找/替换,用class="blue" 将它们包装在一个跨度中。然后将文本转储到等待的div

function init() {
  var area = document.getElementById('area');
  var div = document.getElementById('div');
  var buzzword = /function|.getElementById|.getElementsByClassName|.style|\{|\}|\(|\)|\$|\[|\]/g;
  var text = area.value;
  var replacedText = text.replace(buzzword, function (selection) {
    return '<span class="blue">' + selection + '</span>';
  });
  div.innerHTML = replacedText;
}

如果您希望它实时更新(或每次用户键入内容时),您应该将 keyup 事件绑定到 textarea 以每次运行 init。还有更多关于 here 的内容。

您应该删除您的 onfocus 事件并添加它:

if (window.addEventListener) {
  document.getElementById('area').addEventListener('keyup', init, false);
} else {
  document.getElementById('area').attachEvent('keyup', init);
}

这将确保当您键入textarea 时,div 中的语法着色应该是可以的。确保对 Javascript 的调用位于 HTML 页面的底部,而不是位于标题中,否则它将无法识别该元素。

【讨论】:

  • 谢谢@Andy,你的新答案效果很好!自从我问起,我稍微改变了我的 HTML,所以我不得不稍微改变你的解决方案,但现在它可以工作了!但是,当我继续打字时,文本仍然是蓝色的。我需要它,所以只有匹配的单词是蓝色的,然后任何不匹配的都是默认颜色。你知道如何实现这一目标吗? :)
  • @tinkerbot - 我已经更新了我的答案。希望事件监听器代码会有所帮助。
  • @tinkerbot,还要检查您是否有任何其他名为 blue 的样式,如果有,请将代码中的类更改为其他内容。
【解决方案2】:

我会做这样的事情:

var buzzwords = ['\\(\\)', 'function'];
previewDiv.innerHTML = textarea.value.replace(new RegExp(
    '(' + buzzwords.join('|') + ')', 'g'
), '<span style="color:blue">$1</span>');

不要忘记使用两个反斜杠转义特殊字符:.(){}[]$

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-09-10
    • 1970-01-01
    • 1970-01-01
    • 2012-01-21
    相关资源
    最近更新 更多