如何找到最接近内部文本的标签

时间:2013-12-06 00:29:34

标签: javascript jquery

我正在尝试找到一种方法来获取包含特定文本值的标记,问题是如果包含文本的后代,则包含返回元素。我只想要一个专门包含文本的那个。

例如:

<table>
    <tr id='tag1'>
        <td>First Name $first$</td>
        <td>Last Name $last$</td>
    </tr>
</table>

我需要找到包含$的文本的所有标签。使用:contains给我TABLE和TR标签。我只想要TD标签。

请注意,这些可能是DIV而不是TD,因此我无法专门搜索TD。

任何人都有一些光鲜的想法?

1 个答案:

答案 0 :(得分:2)

为了提高速度和处理嵌入式子元素,您可能会发现使用普通JS并仅搜索文本节点既快又实用。我有一个treewalk()函数,我调整了它来调用某些父文件中所有文本节点的回调,然后你可以使用回调在这些文本节点中做你想做的任何事情。

以下是此概念的有效演示,它将$first$$last$替换为地图对象中的值:http://jsfiddle.net/jfriend00/d2fsE/

这里有更通用的代码,只是建立一个节点和匹配列表:

var treeWalkTextNodes = (function() {
    // create closure for constants
    var skipTags = {"SCRIPT": true, "IFRAME": true, "OBJECT": true, 
        "EMBED": true, "STYLE": true, "LINK": true, "META": true};
    return function(parent, fn, data) {
        var node = parent.firstChild, nextNode;
        while (node && node != parent) {
            if (node.nodeType === 3) {
                if (fn(node, data) === false) {
                    return false ;
                }
            }
            // if element with children and not a skipTag type element, then
            //     iterate through it's children
            if (node.nodeType === 1 && node.firstChild && !(node.tagName && skipTags[node.tagName])) {
                node = node.firstChild;
            } else  if (node.nextSibling) {
                node = node.nextSibling;
            } else {
                // no child and no nextsibling
                // find parent that has a nextSibling
                while ((node = node.parentNode) != parent) {
                    if (node.nextSibling) {
                        node = node.nextSibling;
                        break;
                    }
                }
            }
        }
    }
})();

function replace$Data(parent, map) {
    var dollars = /\$(.*?)\$/;
    treeWalkTextNodes(parent, function(node, data) {
        // node is the text node
        // node.parentNode is the element containing the text node
        var str, found = false;
        str = node.nodeValue.replace(dollars, function(match, p1) {
            if (p1 in map) {
                found = true;
                return map[p1];
            } else {
                return match;
            }
        });
        if (found) {
            node.nodeValue = str;
        }
    });
}


// then to call this, you would do something like this:
var matchMap = {
    first: "John",
    last: "Kennedy"
};
replace$Data(document.body, matchMap);

你显然可以在回调函数中实现自己的逻辑 - 我刚刚选择显示一个实现,它用$ sign替换$ sign与地图中其他文本之间的文本。

相关问题