阅读非兄弟HTML标记之间的所有文本

时间:2014-08-18 09:18:18

标签: jquery tags between

我有一个HTML页面(从drupal创建),在我选择的地方页面顶部附近有

<span class="marker-start"></span>

并且接近结尾,在我选择的地方,

<span class="marker-end"></span>

在这些之间是用户编写的一些HTML,可能但不一定非常好。

用户可以添加上述其他标签,以便排除内容,例如:

<span class="marker-end"></span>
<div>This HTML here is excluded</div>
<span class="marker-start"></span>

请注意,排除区块以&#39; marker-end&#39;开头,因为它匹配&#39; marker-start&#39;在页面的开头形成一对,类似地,排除块以“标记 - 开始”结束。与&#39;标记结束&#39;配对在文档的末尾(或另一个排除块的开头)。

虽然理论上排除块将很好地形成,但我将再次说:由用户编写。标签可能以不均匀的方式合法地打开或关闭(例如,/ div可能在标记开始之后),依此类推。基本上,不能保证标记是兄弟姐妹。

用户可以在文档中添加多个排除的跨度。

我需要一种方法来阅读每对&#39; marker-start&#39;之间的文本(而不是HTML)。和&#39; marker-end&#39;,并且该文本(将排除任何排除块)将连接在一起。标记可能(实际上几乎肯定不会)是处于平衡位置的兄弟姐妹,即可能会有标签打开但不关闭,反之亦然。

我已经尝试了How to select all content between two tags in jQueryGet text between two elements JQUERY中建议的方法,并遇到了所有方法的问题。

总的来说,我真的很难让jQuery产生任何有用的结果。

有人能建议最简单的方法吗?我确实有两个解决方案,我将在其他人看到的答案中概述,但两者都不完美。

2 个答案:

答案 0 :(得分:1)

您可以尝试递归遍历整个DOM,并根据找到的先前开始和结束标记排除元素:

作为一个简单的例子(如果我理解你的排除逻辑):

JSFiddle:http://jsfiddle.net/fdductdg/2/

function walkDOM(node, func) {
    func(node);
    node = node.firstChild;
    while (node) {
        walkDOM(node, func);
        node = node.nextSibling;
    }
};

var inMarker = false;

walkDOM(document.body, function (node) {
    var $node = $(node);
    if ($node.is('span')) {
        if ($node.hasClass('marker-end')) {
            inMarker = false;
            console.log("end marker");
        } else if ($node.hasClass("marker-start")) {
            inMarker = true;
            console.log("start marker");
        }
    }
    if (node.nodeType == 3)
    {
        if (!inMarker)
        {
            // Not inside a marker, remove the text content
            node.textContent = "";
        }
    }
});

<强>更新

由于您还希望保留原始文本,您可以在变量中收集它(如您在评论中所做的那样)或将任何匹配的文本节点包装在适当的元素中(例如,具有适当类的跨度),以便排除的文本可以简单地进行样式设置,而不会破坏内容。

答案 1 :(得分:0)

一个非常糟糕的选择是将HTML作为字符串,然后使用字符串分析,找到标记,在它们之间抓取HTML,然后使用某种HTML解析器将其减少为文本。呸!

我找到的更好的解决方案是:

1)我在页面的最外面的开始和结束标记(我控制的标记)中添加了唯一的ID,例如

<span class="marker-start" id="primary-marker-start"></span>
...
<span class="marker-end" id="primary-marker-end"></span>

2)我使用以下内容来获取文本:

var start_class = 'marker-start';
var end_class = 'marker-end';
var start_tag = '<start>';
var end_tag = '<end>';
var absolute_start_id = "#primary-marker-start";
var absolute_end_id = "#primary-marker-end";

// put convenient markers into the actual text that will be returned,
// to enable simple parsing - note that this will dump anything already there
// so for example, <span class="marker-start"></span>
// becomes <span class="marker-start">&lt;start&gt;</span>
jQuery("." + start_class).text(start_tag);
jQuery("." + end_class).text(end_tag);

// get the text between the two outermost markers -
// including the convenient markers added above
var content = start_tag + jQuery(absolute_start_id).nextAll().not(absolute_end_id).text();

// remove the convenient markers so they don't show up on the page
jQuery("." + start_class).text("");
jQuery("." + end_class).text("");

// at this point, content holds all the text
// between and including absolute_start_id and absolute_end_id,
// with start_tag in place of the start markers, (eg '<start>')
// and end_tag in place of the end markers
// (including at the beginning and end of the text)

在此之后,处理该字符串并适当地删除结束标记和开始标记之间的任何内容是相对简单的行为,依此类推。

有人能提出更好的想法或改进方法吗?我不是jQuery专家,所以欢迎提示或解决方案。