【问题标题】:Get Attributes of enclosing Tag in HTML String获取 HTML 字符串中包含标签的属性
【发布时间】:2014-06-19 14:47:55
【问题描述】:

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

<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 但我不需要选择,只需要一个字符索引。

【问题讨论】:

    标签: javascript string screen


    【解决方案1】:

    一种可能的方法来处理构建一个允许您索引每一行并获取字符及其相关样式的数据结构,可以使用以下 sn-p 为每一行完成。这假设您为上面显示的 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' }
      }
    ]
    

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

    【讨论】:

      【解决方案2】:

      我会将解析 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 标签不包含前景色或背景色信息的情况。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-12
        • 2012-01-19
        • 2011-05-30
        • 2012-10-09
        • 2013-07-23
        • 2018-08-24
        相关资源
        最近更新 更多