获取在HTML字符串中包含Tag的属性

时间:2014-06-19 14:47:55

标签: javascript string screen

我正在开发一个简单的文本屏幕/终端模拟器(类似于JQuery终端插件,但没有RPC内容和窗口功能)。 屏幕的每一行是一个表格行(HTML字符串),并且打印命令可以插入具有某些属性(例如前景色和背景色)的文本。每个印刷文字 由带有样式属性的跨度括起来,例如:

<span style="color:#000000;background-color:#111111">A</span><span style="color:#222222;background-color:#333333>BC</span>

这很好用。现在我想添加一个函数,它给出了给定屏幕位置的角色的所有属性, 在上面一行中,位置0(A)的字符的颜色为#000000。 所以我必须计算不属于span标签的字符并获得最后的样式。我的第一个容易出错的解决方案是:

function getAttr(line, position) {
    var result = {foreground:'', background:''},
        ch = '', i, j = -1, tag = false;

    // Count characters
    for (i = 0; i < line.length && j < position; i++) {
        ch = line.charAt(i);

        if (ch == '<') {
            tag = true;
        }

        if (ch == '>') {
            tag = false;
        }
        else if (!tag) {
            j++;
        }
    }

    i--;

    // Find styles
    while (i > 0 && line.charAt(i) != '<') {
        if (line.substr(i, 6) == 'color:') {
            result.foreground = line.substr(i + 6, 7); 
        }
        if (line.substr(i, 17) == 'background-color:') {
            result.background = line.substr(i + 17, 7); 
        }
        i--;
    }

    return result;  
}

是否有一个更简单的解决方案,不计算字符(可能是JQuery或正则表达式)?

这类似于 Get parent element of a selected text 但我不需要选择,只需要一个字符索引。

2 个答案:

答案 0 :(得分:1)

一种可能的方法来处理构建数据结构,该数据结构允许您索引每一行并获得该字符,并且可以使用以下代码片段为每一行完成它的关联样式。这假设您为上面显示的HTML生成的标记也相当稳定(如果需要,您可以考虑正则表达式的变化):

var tagre = /\<span style="([^"]+)"\>([A-Za-z]+)\<\/span\>/ig,
    s = '<span style="color:#000000;background-color:#111111">A</span><span style="color:#222222;background-color:#333333">BC</span>';

var matches,
    positions = [];

while (matches = tagre.exec(s)) {
    var len = matches[2].length,
        chars = matches[2],
        styles = {};

    matches[1].split(';').forEach(function(o) {
        var _s = o.split(':'),
            key = _s[0],
            val = _s[1];
        styles[key] = val;
    });

    for (var i=0; i < len; i++) {
        var char = chars[i];
        positions.push({ 'char': char, 'styles': styles });
    }
}
console.log("positions=%o", positions);

这会为每行提供一个如下所示的数组:

[
  { char: 'A',
    styles: { 'background-color': '#111111', 'color': '#000000' }
  },
  { char: 'B',
    styles: { 'background-color': '#333333', 'color': '#222222' }
  },
  { char: 'C',
    styles: { 'background-color': '#333333', 'color': '#222222' }
  }
]

这样可以让你按整数字符位置索引每一行,并获得该位置的字符以及相关的样式作为对象。

答案 1 :(得分:0)

我将解析HTML的任务留给浏览器,只使用生成的DOM树。这里有一些基于使用DOM树的想法可以使用的伪代码:

function getAttr(lineNumber, position) {
  var lineDom = getDOMContainerForLineNumber(lineNumber);
  var current = 0; // the current character position

  function getAttrRec(elems, foreground, background) {
    for(elem in elems) {
      if(elem is <span>) {
        var res = getAttrRec(elem.children, elem.foregroundColor, elem.backgroundColor);
        if(res != null)
          return res;
      } else if(elem is TEXT) {
        current += elem.textLength;
        if(current >= position)
          return {foreground: foreground, background: background};
      }
    }
    return null;
  }

  return getAttrRec(lineDom.children, black, black);
}

这只是一个非常粗略的草图。特别是你必须注意空白 - 它们被浏览器严格剥离。因此,直接依赖文本长度可能不适用于您的情况。此外,您可能希望处理span标记不包含前景色或背景色信息的情况。