簡體   English   中英

在html內容之間插入標記

[英]Inserting tags in between html content

我的樣本低於mydiv中的內容

<div id="mydiv">
   sample text sample text sample text...
   ......
   <i>inner text </i> <i>sample text </i>
   ......
   <b>sample text </b> <i>sample text </i>
</div>

現在我想在mydiv內容之間添加突出顯示div。 樣品如下。

<div class="highlight">highlight text</div>

我想在每200個單詞中插入這個div,但問題是它不應該進入任何子標簽內。 例如,如果第200個單詞是內部的,它不應該追加

<div id="mydiv">
   sample text sample text sample text...
   ......
   <i>inner<div class="highlight">highlight text</div> text </i> <i>sample text </i>
   ......
   <b>sample text </b> <i>sample text </i>
</div>

它應該在內部標簽之后追加

<div id="mydiv">
   sample text sample text sample text...
   ......
   <i>inner text </i> <div class="highlight">highlight text</div> <i>sample text </i>
   ......
   <b>sample text </b> <i>sample text </i>
</div>

我嘗試使用子字符串,但它在子標簽內部。 有沒有辦法實現這個目標? 我們可以使用任何js庫。

最簡單的方法是遍歷div的內容並在正確的位置插入突出顯示。 這是代碼:

$(document).ready(function () {
    // count of characters (modulo the period) and selected period
    var count = 0, period = 200;

    // iterator and highlight
    var words = '', highlight = '<div class="highlight">highlight text</div>';

    // loop through the contents
    $('#mydiv').contents().each(function () {
        // we only care about text contents
        if (this.nodeType === 3) {
            // get the individual words
            words = $(this).text().split(' ');
            // loop through them
            for (var j = 0; j < words.length; j++) {
                // increase count except if the word is empty (mutiple spaces)
                if (words[j] && words[j] !== '\n') { count++; }
                // if the period is exceeded, add the highlight and reset the count
                if (count === period) {
                    words.splice(1 + j++, 0, highlight);
                    count = 0;
                }
            }
            // replace the text
            $(this).replaceWith(words.join(' '));
        }
    });
});

您可以after使用JQuery或insertAfter在目標之后插入元素。

append方法將指定的內容作為jQuery集合中每個元素的last child 節點插入

 $(function(){ // your logic to find position goes here... // append text after an element $("#mydiv i:first-child").after("<div class='highlight'>highlight text</div>"); }); 
 .highlight{ color: red; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="mydiv"> sample1 text1 sample1 text1 sample1 text1sample1 tex1 sample1 text1 sample text1 sample2 text2 sample2 text sample2 textsample2 text2 sample2 text2 sample2 text2 sample3 text3 sample3 text3 sample3 textsample3 text3 sample3 text3 sample3 text3 sample 3 text 3sample 3text sample3 textsample3 text4 sample 4text sample4 text <i>1inner text 1 </i> <i>sample text 1</i> <i>2inner text 2</i> <i>sample text2 </i> <i>3inner text 3</i> <i>sample text 3</i> <i>4inner text 4</i> <i>sample text4 </i> <i>5inner text 5</i> <i>sample text5 </i> <i>6inner text 6</i> <i>sample text6 </i> <i>7inner text 7</i> <i>sample text 7</i> <b>8sample text 8</b> <i>sample text 8</i> <b>9sample text 9</b> <i>sample text 9</i> <b>10sample text 10</b> <i>sample text10 </i> <b>11sample text 11</b> <i>sample text 11</i> <b>12sample text 12</b> <i>sample text 12</i> </div> 

更新我將在每第二個單詞后添加的div。

var some_div = '<div style="display:inline-block;color:red;">some_text</div>';

var text = $('#mydiv').text().match(/\w+/g);

其次,遍歷所有單詞並在div的html中使用唯一標識符文本作為前綴。

在這里,我添加一個字符串<index>$$ ,其中<index>在每次遍歷時遞增。

var i = 1;
var count = 1;
var html = $('#mydiv').html();

text.forEach(function(word, index) {

  var offset = html.indexOf(word);
  while (html[offset - 1] == '$' && html[offset - 2] == '$') {
    offset = html.indexOf(word, offset + 1);
  }

  if ((count % up_index) == 0) {
    html = html.slice(0, offset) + (i++) + '$$' + html.slice(offset)
    $('#mydiv').html(html);
  }

  count++;
});

最后,遍歷所有獨特的令牌並用你的html替換它們。

找到令牌使用$('#mydiv').find(':contains(' + j + '$$)'); 的jquery。

for (var j = 1; j < i; j++) {
  var elm = $('#mydiv').find(':contains(' + j + '$$)');
  if (elm.length == 0) {
    console.log('inroot>>' + ':contains(' + j + '$$)');
    var offset = $(':contains(' + j + '$$)').last().html().indexOf(j + '$$');
    var t_html = $(':contains(' + j + '$$)').last().html().slice(0, (offset + (("" + j + '$$').length))).replace(/[0-9]\$\$/ig, '');
    t_html += some_div;
    t_html += $(':contains(' + j + '$$)').last().html().slice(offset + (("" + j + '$$').length));
    $('#mydiv').html(t_html);

  } else {
    console.log('not inroot>>' + ':contains(' + j + '$$)');
    $(some_div).insertAfter(elm.last());
  }
}

這是一個示例,其中我在每2nd word后面添加了div

首先,我正在獲取感興趣的容器內的所有單詞,如下所示,

 var some_div = '<div style="display:inline-block;color:red;">some text</div>'; var up_index = 2; // Word index that will be updated every 2nd word. var text = $('#mydiv').text().match(/\\w+/g); var i = 1; var count = 1; var html = $('#mydiv').html(); text.forEach(function(word, index) { var offset = html.indexOf(word); while (html[offset - 1] == '$' && html[offset - 2] == '$') { offset = html.indexOf(word, offset + 1); } if ((count % up_index) == 0) { html = html.slice(0, offset) + (i++) + '$$' + html.slice(offset) $('#mydiv').html(html); } count++; }); for (var j = 1; j < i; j++) { var elm = $('#mydiv').find(':contains(' + j + '$$)'); if (elm.length == 0) { console.log('inroot>>' + ':contains(' + j + '$$)'); var offset = $(':contains(' + j + '$$)').last().html().indexOf(j + '$$'); var t_html = $(':contains(' + j + '$$)').last().html().slice(0, (offset + (("" + j + '$$').length))).replace(/[0-9]\\$\\$/ig, ''); t_html += some_div; t_html += $(':contains(' + j + '$$)').last().html().slice(offset + (("" + j + '$$').length)); $('#mydiv').html(t_html); } else { console.log('not inroot>>' + ':contains(' + j + '$$)'); $(some_div).insertAfter(elm.last()); } } $('#mydiv').html($('#mydiv').html().replace(/[0-9]\\$\\$/ig, '')); 
 .highlight { color: red; display: inline-block; } b { background-color: blue; } i { background-color: yellow; } i, b { border: 1px solid green; } 
 <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div id="mydiv"> sample text <b><a>sample text</a></b> <i>sample text </i> ...... <i>inner text </i> <i>sample text </i> ...... <b>sample text </b> <i>sample text </i> </div> 

您沒有詳細說明如何到達DOM中的文本(我假設您正在使用DOM)。 但是如果文本節點包含感興趣的單詞,那么應該這樣做。 為方便起見,我使用的是最小量的jQuery,幾乎沒有必要。

// use jQuery to find the text node "inner text" from your example
let textNode = $("#mydiv i")
    .first()
    .contents()
    .filter(function () {
        return this.nodeType == 3; /* text node */
    }).get(0);

// find the parent element of the text node
let el = textNode;
while (el.parentNode) {
    if (el.nodeType == 1) break; /* element */
    el = el.parentNode;
}
// append the html after the parent of the text node.
 $(el).after(`<div class="highlight">highlight text</div>`);

你可以在這個plnkr看到這個。

基本上,代碼獲取第N個感興趣的單詞的文本節點,找到它的父元素,然后插入所需的html作為父元素的第一個右兄弟。

無論如何,我希望這會有所幫助。

注意:使用的HTML是給定的示例內容
嘗試拆分你的div內容並從中開始工作。 請參閱注釋以獲得解釋:

        //1.Get mydiv content
        //2. Split spaces and newlines
        //3. Remove empty array values
        var div =     $("#mydiv").html().toString().split(/[\s+\n]/).filter(String);

        var allowAdd = true, appendNow;
        for(var a=0; a < div.length ; a++){
            if(div[a].match(/^</) && div[a].match(/>$/)){ //search for end tags ie. </i>, </b>
                if(div[a].match(/<\//)){ //if end tag, 
                    allowAdd = true;    //allow append
                }
            }else if (div[a].match(/</)){ //if start stag,
                allowAdd = false;   //disallow append (inside block)

            }

            if((a+1)%200 == 0){
                //every 200 words
                appendNow = true;
            }

            //append if 200th word and end tag is passed
            if(appendNow && allowAdd){
                div[a] += ' <div class="highlight">highlight text </div> ';
                appendNow = false;
            }
        }

        //join array values and assign value to mydiv content
        $("#mydiv").html(div.join(" ")); 

這是一個代碼,可以為您提供所需的結果。 這段代碼的優點是它不檢查每個元素是否是標記,檢查它是否包含<</ ,在我看來這是好的,因為我們的代碼並不像它那樣復雜,並且我們不需要檢查所有值,無論它們是否包含<</ (減少計算,理論上應該運行得更快。)

var elements = $("#mydiv").contents(); //Get all contents of #mydiv
$("#mydiv").html(null); //Delete all elements from #mydiv

var count = 0; //This will be counting our elements

for(var i = 0; i < elements.length; i++){ //Go through all elements of #mydiv
    if(elements[i].nodeName == "#text"){ //If the element is a text block, then:

        var textElements = $(elements[i]).text().split(/\s+/g); //Split the text by all the spaces

        for(var j = 0; j < textElements.length; j++){ //Go through all elements inside the text block

            if(textElements[j] == "") continue; //The splitting of the text-block elements is not perfect, so we have to skip some elements manually

            count++; //Add to our count

            $("#mydiv").append(textElements[j] + " "); //Add this element to our cleared #mydiv

            if(count != 0 && count % 200 == 0){ //Every 200 elements, do this:
                $("#mydiv").append(" <span class='highlight'>highlight</span> "); //Add our highlight
            }
        }
    }else{ //If the element is not a text block, then:

        $("#mydiv").append(elements[i]); //Add the non-text element

        count++; //Add to our counter

        if(count != 0 && count % 200 == 0){ //Every 200 elements, do this:
            $("#mydiv").append(" <span class='highlight'>highlight</span> "); //Add our highlight

        }
    }
}

如果您可以將#mydiv的HTML作為字符串進行操作,一種解決方案是使用帶有正則表達式和替換函數的string.replace ,例如:

function insertInHTMLEveryNWords(n, htmlString, insertString) {
  var wordCounter = 0,
      tagDepth = 0;
  return htmlString.replace(
    /<(\/?)([^>]+)>|[^<\s]+/g,
    function(match, forwardSlash, tagContent) {
      if (tagContent) { //matched a tag
        tagDepth += forwardSlash ? -1 : 1;
      } else { //matched a word
        wordCounter++;
      }
      if (!tagDepth && wordCounter >= n) {
        //if not inside tag and words are at least n,
        wordCounter = 0;
        return match + insertString;
      } else {
        return match;
      }
    });
}

以下代碼段包含該方法的工作演示,簡化為每2個字后插入(如果不在任何標記中,或直接在下一個可能的結束標記之后,如OP所述):

 var htmlOriginal = document.getElementById('mydiv').innerHTML; var htmlWithInsertions = insertInHTMLEveryNWords( 2, htmlOriginal, '<div>[Inserted DIV after every 2 words or when not in any tag]</div>' ); //inspect result in console console.log(htmlWithInsertions); //replace html in #mydiv document.getElementById('mydiv').innerHTML = htmlWithInsertions; function insertInHTMLEveryNWords(n, htmlString, insertString) { var wordCounter = 0, tagDepth = 0; return htmlString.replace( /<(\\/?)([^>]+)>|[^<\\s]+/g, function(match, forwardSlash, tagContent) { if (tagContent) { //matched a tag tagDepth += forwardSlash ? -1 : 1; } else { //matched a word wordCounter++; } if (!tagDepth && wordCounter >= n) { //if not inside tag and words are at least n, wordCounter = 0; return match + insertString; } else { return match; } }); } 
 <div id="mydiv"> Some text, word3, <em>emphasized and <strong>strong</strong></em> text. </div> 

一個潛在的限制是,操縱HTML會替換#mydiv的現有DOM元素,並打破以前對它們的任何引用。 如果這不會造成任何問題,這是一個簡單易用的解決方案。

i標記是內聯元素,不能在其中插入塊元素(如div )。 並且“突出顯示”不是div的有效屬性。

要實現插入,請使用span而不是div 並檢查您的目標需要哪個屬性。 結果將是( id為屬性):

<div id="mydiv">
   sample text sample text sample text...
   ......
   <i>inner<span id="highlight">highlight text</span> text </i> <i>sample text </i>
   ......
   <b>sample text </b> <i>sample text </i>
</div>

我假設你已經找到了200這個詞並在它之后追加你的div,這樣的事可能嗎?

varUntilSpace200 + '<div "highlight">highlight text</div>' + restOfInnerHTML;

然后,您需要做的就是檢查restOfInnerHTML,如果在空格200之后有一個

"</"

如果是這樣,只需將該位置的所有內容附加到第一個位置

">"

var indof1 = restOfInnerHTML.indexOf("</");
var indof2 = restOfInnerHTML.indexOf("<");
var indof3 = restOfInnerHTML.indexOf(">");

if (indof1 < indof2) {
  varUntilSpace200 += restOfInnerHTML.substring(indof1,indof3);
  restOfInnerHTML = restOfInnerHTML.substring(indof3+1,restOfInnerHTML.length);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM