Find text between two tags/nodes

后端 未结 6 1145
北荒
北荒 2021-02-20 00:32

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.

Basical

相关标签:
6条回答
  • 2021-02-20 00:44

    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:

    $(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.

    0 讨论(0)
  • 2021-02-20 00:49

    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.

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

    Live Demo: 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>
    
    0 讨论(0)
  • 2021-02-20 00:51

    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.

    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');
    
    0 讨论(0)
  • 2021-02-20 00:52

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

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

    0 讨论(0)
  • 2021-02-20 00:56

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

    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.

    0 讨论(0)
  • 2021-02-20 00:58

    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.

    0 讨论(0)
提交回复
热议问题