在两个标签/节点之间查找文本

时间:2023-02-01 16:18:04

I thought that this would be rather straightforward, but I think the keywords are just too general so I keep getting query results for things like this and this.

我认为这将是相当简单的,但我认为关键字太一般,所以我不断得到这样的事情的查询结果。

Basically, I have the following HTML:

基本上,我有以下HTML:

<div id="test">
    Lorem
    <span class="highlighted">ipsum</span>
    dolor sit amet,
    <span class="highlighted">consectetur</span>
    <span class="highlighted">adipiscing</span>
    elit. Sed massa.
<div>

I'd like to merge adjacent span tags into a single span tag, which means finding spans with only whitespace between them (this could include spaces, tabs and newlines).

我想将相邻的span标签合并到一个span标签中,这意味着找到它们之间只有空格的跨距(这可能包括空格,制表符和换行符)。

The result I'm looking for is this:

我正在寻找的结果是这样的:

<div id="test">
    Lorem
    <span class="highlighted">ipsum</span>
    dolor sit amet,
    <span class="highlighted">consectetur adipiscing</span>
    elit. Sed massa.
<div>

I've examined the nextUntil function, but it seems to only return tags, not text. The result, for example, of

我已经检查了nextUntil函数,但它似乎只返回标签,而不是文本。结果,例如,

$("span.highlighted").nextUntil("span.highlighted").andSelf().text();

is

ipsumconsecteturadipiscing

rather than

ipsum dolor sit amet, consecteturadipiscing

ipsum dolor坐下来,精神饱满

Given two tags, how can I find the text between them?

鉴于两个标签,我如何找到它们之间的文本?

6 个解决方案

#1


5  

Dropping down to the DOM lets you see text node contents when checking siblings.

通过下拉到DOM,您可以在检查兄弟节点时查看文本节点内容。

Something like:

function combineSpans(span, nextspan)
{
  var follower = span.nextSibling;
  var concat = true;

   while (follower != nextspan)
   {
     if (follower.nodeName != '#text')
     {
       concat = false;
       break;
     }

     var len = follower.data.trim().length;
     if (len > 0)
     {
       concat = false;
       break;
     }

     follower = follower.nextSibling;
   }

  if (concat)
  {
    $(span).text($(span).text() + " " + $(follower).text());
    $(follower).remove();
  }
}

Using this with your HTML in this CodePen.

在此CodePen中将此与HTML一起使用。

#2


1  

Well, you can try this...

好吧,你可以尝试这个......

At least it works perfect when using 2 spans to merge them like your example (when an "empty" element is present). Otherwise, you will need to think a little to handle the span that lasts.

至少它使用2个跨度来合并它们就像你的例子一样(当存在“空”元素时)。否则,你需要考虑一点来处理持续的跨度。

(To check what I am talking about just take a look commenting the last line: nextElem.remove() and check the new div html).

(要检查我在说什么,只需看一下评论最后一行:nextElem.remove()并检查新的div html)。

Live Demo: http://jsfiddle.net/oscarj24/t45MR/

现场演示:http://jsfiddle.net/oscarj24/t45MR/


HTML:

<div id="test">
    Lorem
    <span class="highlighted">ipsum</span>
    dolor sit amet,
    <span class="highlighted">consectetur</span>
    <span class="highlighted">adipiscing</span>
    elit. Sed massa.
</div>

jQuery:

$(document).ready(function () {

    var elem = $('#test');

    elem.contents().filter(function(index) {
        //Get index of an empty element
        if($.trim($(this).text()) === '') 
            //Merge the previous index span with the next index span texts
            mergeSpan(index);
    });

    //Print new inner html
    alert(elem.html());
});

function mergeSpan(index){

    //Get all 'div' elements
    var elems = $('#test').contents();

    //Get previous and next element according to index
    var prevElem = elems.eq(index - 1);
    var nextElem = elems.eq(index + 1);

    //Concat both texts
    var concatText = prevElem.text() + ' ' + nextElem.text();

    //Set the new text in the first span
    prevElem.text(concatText);
    //Remove other span that lasts
    nextElem.remove();
};

Result:

<div id="test">
    Lorem
    <span class="highlighted">ipsum</span>
    dolor sit amet,
    <span class="highlighted">consectetur adipiscing</span>
    elit. Sed massa.
<div>

#3


1  

I know you have already accepted a solution, but I wanted to take the challenge to provide a pure javascript solution which can be incorporated into your toolset. Here's what I came up with, and would like any help to make this better.

我知道你已经接受了一个解决方案,但是我想接受挑战来提供一个纯粹的javascript解决方案,它可以整合到你的工具集中。这是我想出来的,并希望有任何帮助,使这更好​​。

http://jsfiddle.net/ryanwheale/JhZPK/

function joinNeighborsByClassName( className ) {
    var items = document.getElementsByClassName(className),
        next = null,
        remove = [],
        append = '',
        i = 0;

    while( i < items.length && (next = items[i++]) ) {
        while( (next = next.nextSibling) && next !== null ) {
            if((next.nodeType === 3  && /^\s+$/.test(next.nodeValue)) ||     
               (new RegExp("(?:^|\s)" + className + "(?!\S)", "g")).test(next.className) ) {
                append += (next.innerHTML || next.nodeValue);

                if(next.nodeType !== 3) {
                    remove.push(next);
                }
            } else {
                break;
            }
        }

        if(append) items[i-1].innerHTML += append;
        for(var n = 0; n < remove.length; n++) {
            remove[n].parentNode.removeChild(remove[n]);
        }

        remove = [];
        append = '';
    }
}

joinNeighborsByClassName('highlighted');

#4


0  

As the title request it, here's a possible way to get text nodes between spans:

当标题请求它时,这是在跨度之间获取文本节点的可能方法:

var textNodes=$('#test').contents().filter(function(){
    return this.nodeType == 3; // text node
});

It is also possible to manually check for consecutive spans that have no empty text node between them by comparing each node with the precedent one. Something like this will do the trick:

通过将每个节点与先前节点进行比较,还可以手动检查它们之间没有空文本节点的连续跨距。像这样的东西可以解决这个问题:

function combineSpansIn(selector, spanClass) {
    // initialize precedent values
    var prec=null;
    var precNodeType;

    $(selector).contents().each(function(){
        if ($.trim( $(this).text() ) !== "") { // empty nodes will be useless here
            var nodeType = this.nodeType;

            // check if still a combinable span
            if (nodeType == 1 && this.className==spanClass && nodeType == precNodeType) {
                // append current node to precedent one
                $(prec).append(" "+ $(this).text() );

                // remove current node
                $(this).remove();
            } else {
                // update precedent values
                prec=this;
                precNodeType = nodeType;
            }
        }
    });
}

combineSpansIn('#test', 'highlighted');

Please take a look at this FIDDLE.

请看一下这个FIDDLE。

#5


0  

Heh . . . looks like Oscar Jara and I came up with similar ideas around using the JQuery .contents() method, but ended up with some considerably different implementations:

嘿。 。看起来像Oscar Jara和我在使用JQuery .contents()方法时提出了类似的想法,但最终得到了一些相当不同的实现:

$(document).ready(function () {
    $("#testDiv").contents().each(function() {
        var prevNode = this.previousSibling;
        var fillerText = "";
        while ((prevNode) && ($.trim($(prevNode).text()) === "")) {
            fillerText += prevNode.nodeValue;
            prevNode = prevNode.previousSibling;
        }

        if ((prevNode) && (this.nodeType === 1) && (prevNode.nodeType === 1)) {
            $(prevNode).text($(prevNode).text() + fillerText + $(this).text());
            $(this).remove();
        }
    });
});

I tested a few different sets of HTML data (three spans back-to-back, spans with spaces in between and without, etc.) all based on your original code, and it seems to work . . . the key was to skip over any "whitespace only" text nodes in between the <span> tags, while preserving any needed spacing that they may have contained.

我测试了一些不同的HTML数据集(三个背靠背,跨越空间和没有空间等)都基于您的原始代码,它似乎工作。 。 。关键是跳过标签之间的任何“仅空白”文本节点,同时保留它们可能包含的任何所需间距。

#6


-1  

For your last question "Given two tags, how can i find the text between them?"

对于您的上一个问题“给定两个标签,我如何在它们之间找到文本?”

Well, I have this solution for you.

好吧,我有这个解决方案给你。

var divData = $("#test").html(); // Getting html code inside div

Now, using preg_match() you can obtain the text between two words, in your case the text between spans, like this:

现在,使用preg_match()可以获得两个单词之间的文本,在您的情况下是跨越之间的文本,如下所示:

preg_match('/'.preg_quote($word1).'(.*?)'.preg_quote($word2).'/is', $html, $matches);

$word1 = '<span class="highlighted">';
$word2 = '<';
$html = $_POST['divData']; // Via post/get you will have to send the html code gotten in "var divData"

and for each match(with a for cycle) concat em in a variable adding whitespaces between them. Then do an echo your result and in your call back function add it to your div

并且对于每个匹配(使用for循环)concat em在变量中添加它们之间的空格。然后回显你的结果,并在你的回调函数中将它添加到你的div

This link could help you in how make a POST call in jquery jquery post

此链接可以帮助您在jquery jquery帖子中进行POST调用

#1


5  

Dropping down to the DOM lets you see text node contents when checking siblings.

通过下拉到DOM,您可以在检查兄弟节点时查看文本节点内容。

Something like:

function combineSpans(span, nextspan)
{
  var follower = span.nextSibling;
  var concat = true;

   while (follower != nextspan)
   {
     if (follower.nodeName != '#text')
     {
       concat = false;
       break;
     }

     var len = follower.data.trim().length;
     if (len > 0)
     {
       concat = false;
       break;
     }

     follower = follower.nextSibling;
   }

  if (concat)
  {
    $(span).text($(span).text() + " " + $(follower).text());
    $(follower).remove();
  }
}

Using this with your HTML in this CodePen.

在此CodePen中将此与HTML一起使用。

#2


1  

Well, you can try this...

好吧,你可以尝试这个......

At least it works perfect when using 2 spans to merge them like your example (when an "empty" element is present). Otherwise, you will need to think a little to handle the span that lasts.

至少它使用2个跨度来合并它们就像你的例子一样(当存在“空”元素时)。否则,你需要考虑一点来处理持续的跨度。

(To check what I am talking about just take a look commenting the last line: nextElem.remove() and check the new div html).

(要检查我在说什么,只需看一下评论最后一行:nextElem.remove()并检查新的div html)。

Live Demo: http://jsfiddle.net/oscarj24/t45MR/

现场演示:http://jsfiddle.net/oscarj24/t45MR/


HTML:

<div id="test">
    Lorem
    <span class="highlighted">ipsum</span>
    dolor sit amet,
    <span class="highlighted">consectetur</span>
    <span class="highlighted">adipiscing</span>
    elit. Sed massa.
</div>

jQuery:

$(document).ready(function () {

    var elem = $('#test');

    elem.contents().filter(function(index) {
        //Get index of an empty element
        if($.trim($(this).text()) === '') 
            //Merge the previous index span with the next index span texts
            mergeSpan(index);
    });

    //Print new inner html
    alert(elem.html());
});

function mergeSpan(index){

    //Get all 'div' elements
    var elems = $('#test').contents();

    //Get previous and next element according to index
    var prevElem = elems.eq(index - 1);
    var nextElem = elems.eq(index + 1);

    //Concat both texts
    var concatText = prevElem.text() + ' ' + nextElem.text();

    //Set the new text in the first span
    prevElem.text(concatText);
    //Remove other span that lasts
    nextElem.remove();
};

Result:

<div id="test">
    Lorem
    <span class="highlighted">ipsum</span>
    dolor sit amet,
    <span class="highlighted">consectetur adipiscing</span>
    elit. Sed massa.
<div>

#3


1  

I know you have already accepted a solution, but I wanted to take the challenge to provide a pure javascript solution which can be incorporated into your toolset. Here's what I came up with, and would like any help to make this better.

我知道你已经接受了一个解决方案,但是我想接受挑战来提供一个纯粹的javascript解决方案,它可以整合到你的工具集中。这是我想出来的,并希望有任何帮助,使这更好​​。

http://jsfiddle.net/ryanwheale/JhZPK/

function joinNeighborsByClassName( className ) {
    var items = document.getElementsByClassName(className),
        next = null,
        remove = [],
        append = '',
        i = 0;

    while( i < items.length && (next = items[i++]) ) {
        while( (next = next.nextSibling) && next !== null ) {
            if((next.nodeType === 3  && /^\s+$/.test(next.nodeValue)) ||     
               (new RegExp("(?:^|\s)" + className + "(?!\S)", "g")).test(next.className) ) {
                append += (next.innerHTML || next.nodeValue);

                if(next.nodeType !== 3) {
                    remove.push(next);
                }
            } else {
                break;
            }
        }

        if(append) items[i-1].innerHTML += append;
        for(var n = 0; n < remove.length; n++) {
            remove[n].parentNode.removeChild(remove[n]);
        }

        remove = [];
        append = '';
    }
}

joinNeighborsByClassName('highlighted');

#4


0  

As the title request it, here's a possible way to get text nodes between spans:

当标题请求它时,这是在跨度之间获取文本节点的可能方法:

var textNodes=$('#test').contents().filter(function(){
    return this.nodeType == 3; // text node
});

It is also possible to manually check for consecutive spans that have no empty text node between them by comparing each node with the precedent one. Something like this will do the trick:

通过将每个节点与先前节点进行比较,还可以手动检查它们之间没有空文本节点的连续跨距。像这样的东西可以解决这个问题:

function combineSpansIn(selector, spanClass) {
    // initialize precedent values
    var prec=null;
    var precNodeType;

    $(selector).contents().each(function(){
        if ($.trim( $(this).text() ) !== "") { // empty nodes will be useless here
            var nodeType = this.nodeType;

            // check if still a combinable span
            if (nodeType == 1 && this.className==spanClass && nodeType == precNodeType) {
                // append current node to precedent one
                $(prec).append(" "+ $(this).text() );

                // remove current node
                $(this).remove();
            } else {
                // update precedent values
                prec=this;
                precNodeType = nodeType;
            }
        }
    });
}

combineSpansIn('#test', 'highlighted');

Please take a look at this FIDDLE.

请看一下这个FIDDLE。

#5


0  

Heh . . . looks like Oscar Jara and I came up with similar ideas around using the JQuery .contents() method, but ended up with some considerably different implementations:

嘿。 。看起来像Oscar Jara和我在使用JQuery .contents()方法时提出了类似的想法,但最终得到了一些相当不同的实现:

$(document).ready(function () {
    $("#testDiv").contents().each(function() {
        var prevNode = this.previousSibling;
        var fillerText = "";
        while ((prevNode) && ($.trim($(prevNode).text()) === "")) {
            fillerText += prevNode.nodeValue;
            prevNode = prevNode.previousSibling;
        }

        if ((prevNode) && (this.nodeType === 1) && (prevNode.nodeType === 1)) {
            $(prevNode).text($(prevNode).text() + fillerText + $(this).text());
            $(this).remove();
        }
    });
});

I tested a few different sets of HTML data (three spans back-to-back, spans with spaces in between and without, etc.) all based on your original code, and it seems to work . . . the key was to skip over any "whitespace only" text nodes in between the <span> tags, while preserving any needed spacing that they may have contained.

我测试了一些不同的HTML数据集(三个背靠背,跨越空间和没有空间等)都基于您的原始代码,它似乎工作。 。 。关键是跳过标签之间的任何“仅空白”文本节点,同时保留它们可能包含的任何所需间距。

#6


-1  

For your last question "Given two tags, how can i find the text between them?"

对于您的上一个问题“给定两个标签,我如何在它们之间找到文本?”

Well, I have this solution for you.

好吧,我有这个解决方案给你。

var divData = $("#test").html(); // Getting html code inside div

Now, using preg_match() you can obtain the text between two words, in your case the text between spans, like this:

现在,使用preg_match()可以获得两个单词之间的文本,在您的情况下是跨越之间的文本,如下所示:

preg_match('/'.preg_quote($word1).'(.*?)'.preg_quote($word2).'/is', $html, $matches);

$word1 = '<span class="highlighted">';
$word2 = '<';
$html = $_POST['divData']; // Via post/get you will have to send the html code gotten in "var divData"

and for each match(with a for cycle) concat em in a variable adding whitespaces between them. Then do an echo your result and in your call back function add it to your div

并且对于每个匹配(使用for循环)concat em在变量中添加它们之间的空格。然后回显你的结果,并在你的回调函数中将它添加到你的div

This link could help you in how make a POST call in jquery jquery post

此链接可以帮助您在jquery jquery帖子中进行POST调用