如何单独检索父元素中子元素之前和之后的H​​TML?

时间:2012-03-28 15:51:50

标签: javascript jquery html dom

我们正在编写一个依赖于Javascript / jQuery的Web应用程序。它涉及用户填写大块文本中的单个单词,有点像Mad Libs。我们创建了一种HTML格式,用于编写大块文本,然后在用户填写时使用jQuery进行操作。

文本块的一部分可能如下所示:

<span class="fillmeout">This is a test of the <span>NOUN</span> Broadcast System.</span>

鉴于标记,我需要单独检索和操作内部<span>之前和之后的文本;我们称之为“前缀”和“后缀”。

知道 you can't parse HTML with simple string manipulation,但我还是试过了;我尝试在split()<span>标记上使用</span>。这似乎很简单。遗憾的是,Internet Explorer将所有HTML标记转换为大写,因此该技术失败。我可以写一个特例,但错误教会我以正确的方式做到这一点。

我知道我可以简单地使用额外的HTML标签来手动表示前缀和后缀,但这看起来很丑陋和多余;我希望我们的标记格式尽可能精简,可读和可写。

我查看了jQuery文档,找不到能够完全满足我需要的函数。 添加之前和之后以及内部和内部元素都有各种各样的功能,但我找不到检索已经存在的东西。我可以删除内部<span>,但后来我不知道如何告诉删除元素之前的内容除了之后的内容。

有没有“正确”的方式去做我想做的事情?

9 个答案:

答案 0 :(得分:1)

使用简单的字符串操作,您也可以使用Regex。 这应该可以解决你的问题。

var array = $('.fillmeout').html().split(/<\/?span>/i);

答案 1 :(得分:1)

使用您的jQuery API! $('.fillmeout').children()然后您可以根据需要操作该元素。

http://api.jquery.com/children/

答案 2 :(得分:1)

为了完整性,我想我应该指出最干净的答案是将前缀和后缀文本放在它自己的<span>中,然后你可以使用jQuery选择器和方法直接访问所需的文本:

<span class="fillmeout">
    <span class="prefix">This is a test of the </span>
    <span>NOUN</span>
    <span class="suffix"> Broadcast System.</span>
</span>

然后,代码将如下:

var fillme = $(".fillmeout").eq(0);
var prefix = fillme.find(".prefix").text();
var suffix = fillme.find(".suffix").text();

仅供参考,我不会将这种简单程度称为“丑陋和冗余”,因为你理论化了。您正在使用HTML标记将文本描述为要单独访问的单独元素。这很聪明,而不是多余。

通过类比,假设你有三种不同颜色的玩具(红色,白色和蓝色),它们最初是按颜色组织的,你知道在未来的某个时候你需要再次用颜色分开它们。您还可以使用三个盒子存放它们。您可以将它们全部放在一个盒子中,然后再用颜色再次手动对它们进行排序,或者您可以只取出已经分离的颜色并将它们分别放入自己的盒子中,这样就没有分离以后要做的工作。哪个更容易?哪个更聪明?

HTML元素就像盒子一样。它们是您文本的容器。如果您希望将来分离出文本,您可以将每段文本放入其自己的命名容器中,以便将来可以轻松访问该文本。

答案 3 :(得分:1)

这些答案中的一些几乎让我得到了我所需要的东西,但最后我发现了一个未在此处提及的功能:.contents()。它返回一个包含文本节点的所有子节点的数组,然后我可以迭代(如果需要的话递归)以找到我需要的东西。

答案 4 :(得分:0)

我不确定这是否也是'正确'的方式,但您可以用一个可以一直拆分字符串的元素替换SPAN:

jQuery('.fillmeout span').replaceWith('|');

http://api.jquery.com/replaceWith/

http://jsfiddle.net/mdarnell/P24se/

答案 5 :(得分:0)

您可以使用

$('.fillmeout span').get(0).previousSibling.textContent
$('.fillmeout span').get(0).nextSibling.textContent

这适用于IE9,但遗憾的是不适用于小于9的IE版本。

答案 6 :(得分:0)

根据您的示例,您可以使用目标作为分隔符来分割句子。

var str = $('.fillmeout').html();
str = str.split('<span>NOUN</span>');

这将返回["This is a test of the ", " Broadcast System."]的数组。这是一个 jsFiddle example

答案 7 :(得分:0)

如果你想使用DOM而不是自己解析HTML,并且你不能将所需的文本放在它自己的元素中,那么你需要查看DOM中的文本节点并找到之前和之后的文本节点span标签。

jQuery在处理文本节点而不是元素节点时并没有很多帮助,所以工作大多是在普通的javascript中完成的,如下所示:

$(".fillmeout").each(function() {
    var node = this.firstChild, prefix = "", suffix = "", foundSpan = false;
    while (node) {
        if (node.nodeType == 3) {
            // if text node
            if (!foundSpan) {
                prefix += node.nodeValue;
            } else  {
                suffix += node.nodeValue;
            }
        } else if (node.nodeType == 1 && node.tagName == "SPAN") {
            // if element and span tag
            foundSpan = true;
        }
        node = node.nextSibling;
    }
    // here prefix and suffix are the text before and after the first
    // <span> tag in the HTML
    // You can do with them what you want here
});

注意:此代码不假定跨度之前的所有文本都只位于一个文本节点和一个文本节点中。它可能是,但它也可能不是这样,它将所有文本节点整理在span标记之前和之后。如果您只能在每一侧引用一个文本节点,那么代码会更简单,但并不是100%确定这是一个安全的假设。

此代码还处理跨度之前或之后没有文本的情况。

您可以在此处查看:http://jsfiddle.net/jfriend00/P9YQ6/

答案 8 :(得分:0)

您可以使用nextSiblingpreviousSibling原生JavaScript(加上jQuery选择器):

$('.fillmeout span').each(
    function(){
        var prefix = this.previousSibling.nodeValue,
            suffix = this.nextSibling.nodeValue;
    });

JS Fiddle proof of concept

参考文献: