Jquery 读取非同级HTML标记之间的所有文本

Jquery 读取非同级HTML标记之间的所有文本,jquery,tags,between,Jquery,Tags,Between,我有一个HTML页面(由drupal创建),在页面顶部我选择的位置附近,有一个 <span class="marker-start"></span> <span class="marker-end"></span> 接近尾声时,在我选择的地方 <span class="marker-start"></span> <span class="marker-end"></span> 介于两者

我有一个HTML页面(由drupal创建),在页面顶部我选择的位置附近,有一个

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

接近尾声时,在我选择的地方

<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>

这里的HTML被排除在外
请注意,排除块以“marker end”开头,因为它与页面开头的“marker start”匹配以形成一对,类似地,排除块以“marker start”结尾以与文档结尾的“marker end”(或另一个排除块的开头)匹配

从理论上讲,排除块将是格式良好的,但我要再说一次:由用户编写。标签可以以不均匀的方式合法地打开或关闭(例如,/div可能在标记开始之后),等等。基本上,无法保证标记是兄弟

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

我需要一种方法来读取每对“标记开始”和“标记结束”之间的文本(而不是HTML),并且该文本(将排除任何排除块)将连接在一起。标记可能不是(事实上几乎肯定不会)处于平衡位置的同级标记,即它们之间可能存在打开但未关闭的标记,反之亦然

我尝试了中建议的方法,并在所有这些方法上都遇到了问题

一般来说,我很难让jQuery产生任何有用的结果


有人能提出实现这一目标的最简单方法吗?我确实有两个解决方案,我将在回答中概述,供其他人参考,但两者都不是完美的。

一个非常糟糕的选择是将HTML作为字符串,然后使用字符串分析,找到标记,抓住它们之间的HTML,然后使用某种HTML解析器将其简化为文本。恶心

我找到了一个更好的解决方案:

1) 我将唯一ID添加到页面最外层的打开和关闭标记(我控制的标记),例如


...
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)
var start_class='marker start';
var end_class='marker end';
var start_标签=“”;
var end_标签=“”;
var absolute_start_id=“#主标记开始”;
var absolute_end_id=“#主标记端”;
//在将返回的实际文本中添加方便的标记,
//要启用简单解析,请注意,这将转储已经存在的任何内容
//那么比如说,,
//开始
jQuery(“.”+start\u class).text(start\u标记);
jQuery(“.”+end\u class).text(end\u标记);
//获取两个最外层标记之间的文本-
//包括上面添加的方便标记
var content=start_tag+jQuery(绝对开始id).nextAll().not(绝对结束id).text();
//移除方便的标记,使其不会显示在页面上
jQuery(“.”+start\u class).text(“”);
jQuery(“.”+end_class).text(“”);
//此时,内容保存所有文本
//介于并包括绝对开始id和绝对结束id之间,
//用开始标记代替开始标记(如“”)
//和end_标记代替末端标记
//(包括正文开头和结尾)
在此之后,处理该字符串并适当地删除结束和开始标记之间的任何内容是一个相对简单的操作,以此类推


有人能提出更好的想法或方法来改进这一点吗?我不是jQuery专家,因此欢迎提供提示或解决方案。

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

举个简单的例子(如果我正确理解了排除逻辑):

JSFiddle:

更新:


由于您还希望保留原始文本,您可以将其收集到一个变量中(就像您在注释中所做的那样),或者将任何匹配的文本节点包装到适当的元素中(例如,带有适当类的跨距),这样排除的文本就可以简单地进行输入/输出样式设置,而不会破坏内容。

“…并解决所有这些问题。”什么问题?它们似乎直接适用。还可以看看jQuery
contents()
方法,它返回选择中的所有DOM节点(包括通常被jQuery过滤器排除的文本节点)。不过,jQuery解决方案不一定适用于格式错误的HTML。针对HTML的正则表达式是识别并删除这些文本块的后备方法。理想情况下,您需要在浏览器呈现它之前(或在Ajax加载中)在服务器端执行此操作。@T.J.Crowder,在中,我发现所有答案都只与两个边界标记是兄弟的情况有关,或者一个是另一个的父标记有关,这在我的问题中不是这样的。提供的between函数似乎无法正常工作,这是因为index()用于匹配兄弟标记;唯一的另一个答案似乎也不适合我的情况,尽管也许如果我更多地使用它,我本可以找到其他答案。我还查看了一系列其他问题,但没有找到一个匹配的问题。我无法排除的唯一解决方案是$(“#secondSelector”).prevAll(“#firstSelector~*”)-一旦我做了“s a”,它就工作了,但返回了一个我不知道如何使用的对象,我尝试过的所有jQuery函数(例如.css、.text、.html等)给出了错误或空结果,所以我甚至无法检查它是否有用。好吧,这很有趣。我学习了一个我不知道存在的节点的两个属性,以及一个方便的javascript技巧(传递函数作为将递归从操作中分离出来的一种方法-通常我只显式调用函数)。美好的谢谢。唯一的问题是这个解决方案会改变页面(除非我们