簡體   English   中英

如何從父節點獲取文本節點,並使用 jQuery/JS 將它們插入 div/span

[英]How to get text nodes from a parent node, and insert them in a div/span using jQuery/JS

我有這個 HTML 代碼:

<div class="testoorig">
  <h3>Testo originale</h3>
  <div id="pag_10"></div>
  <br><span class="lineNumb"><b>1</b></span>
  <orig>d</orig> sometext sometext
  <span class="term" id="#formes">formes</span> sometext sometext <span class="term" id="#memoire">mémoire</span>;
  <mentioned><u>punirai</u></mentioned>,
  <mentioned><u>punir</u></mentioned>

  <!-- Next line (totally 31) -->

  <br><span class="lineNumb"><b>2</b></span> .....

</div>
<!-- #testoorig -->

無法在 DOM 中添加任何內容,因為它是由 XSLT 生成的 HTML,並且由於許多原因我無法對其進行編輯

我有這個 jQuery:

jQuery.fn.getParent = function (num) {
  var last = this[0];
  for (var i = 0; i < num; i++) {
    last = last.parentNode;
  }
  return jQuery(last);
};
  $(document).on("mouseover", ".lineNumb", function(g){
    target = $(this);
    target.css("background", "antiquewhite");
    arr = target.getParent(0).nextUntil(".lineNumb");

    for(i=0;i<arr.length;i++) {
      $(arr[i]).css("background", "antiquewhite");
    }
  });

所以我希望當你將鼠標懸停在每一行上時,整行變成“背景:古色古香”,簡而言之就是必須選擇和標記的行。 只需要標記當前行(這就是我使用 nextUntil(".lineNumber") 的原因)

但是,我只得到風格化的 d(在<orig>中)、1(在<b>中)、formes、mèmoire(在<span>中)punirai、punir(在<mentioned>

看來我的代碼無法獲得“sometext”,我怎樣才能獲得它並對其進行風格化? (也許將它包裝在一個 div 或一個跨度中,像這樣)

 jQuery.fn.getParent = function(num) { var last = this[0]; for (var i = 0; i < num; i++) { last = last.parentNode; } return jQuery(last); }; $(document).on("mouseover", ".lineNumb", function(g) { target = $(this); target.css("background", "pink"); arr = target.getParent(0).nextUntil(".lineNumb"); for (i = 0; i < arr.length; i++) { $(arr[i]).css("background", "lightblue"); } });
 <div class="testoorig"> <h3>Testo originale</h3> <div id="pag_10"></div> <br><span class="lineNumb"><b>1</b></span> <orig>d</orig> sometext sometext <span class="term" id="#formes">formes</span> sometext sometext <span class="term" id="#memoire">mémoire</span>; <mentioned><u>punirai</u></mentioned>, <mentioned><u>punir</u></mentioned> <br><span class="lineNumb"><b>2</b></span> </div> <!-- #testoorig --> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

將背景顏色應用於一個元素 (div) 中的一組文本節點和元素實際上是不可能的。 因此,我建議您操作div.testooriginnerHTML :將您想要具有共同背景顏色的所有元素組合在一個div.row中。 之后,可以使用單個.on("mouseover mouseout",".row",function(ev){...})輕松地將懸停事件分配給這些.row div:

 const divStart='<div class="row">',divEnd='</div>'; $(".testoorig") .html((_,html)=>{ let arr=html.split("<br>"); return arr.shift()+divStart+arr.join(divEnd+divStart)+divEnd; }) .on("mouseover mouseout",".row",function(ev){ $(this).toggleClass("hilite",ev.type=="mouseover"); });
 .hilite {background-color:pink}
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <div class="testoorig"> <h3>Testo originale</h3> <div id="pag_10"></div> <br><span class="lineNumb"><b>1</b></span> <orig>d</orig> first text sometext <span class="term" id="#formes">formes</span> sometext sometext <span class="term" id="#memoire">mémoire</span>; <mentioned><u>punirai</u></mentioned>, <mentioned><u>punir</u></mentioned> <br><span class="lineNumb"><b>2</b></span> <orig>d</orig> second text sometext <span class="term" id="#formes">formes</span> sometext sometext <span class="term" id="#memoire">mémoire</span>; <mentioned><u>punirai</u></mentioned>, <mentioned><u>punir</u></mentioned> <br><span class="lineNumb"><b>3</b></span> <orig>d</orig> third text sometext <span class="term" id="#formes">formes</span> sometext sometext <span class="term" id="#memoire">mémoire</span>; <mentioned><u>punirai</u></mentioned>, <mentioned><u>punir</u></mentioned> </div>

這是@isherwood 方法的一種變體,它將響應鼠標懸停在由.lineNum跨度分隔的部分的任何元素上:

 $(function() { const $div=$('.testoorig'); $div.contents().filter((i, c) =>c.nodeType===3).wrap('<span/>'); $(".lineNumb",$div).each((i,el)=>{ const $grp=$(el).nextUntil(".lineNumb").addBack(); $grp.on("mouseover mouseout",ev=> $grp.toggleClass("hilite",ev.type=="mouseover") ); }); });
 .hilite {background-color:pink}
 <div class="testoorig"> <h3>Testo originale</h3> <div id="pag_10"></div> <br> <span class="lineNumb"><b>1</b></span> <orig>d</orig> sometext sometext <span class="term" id="#formes">formes</span> sometext sometext <span class="term" id="#memoire">mémoire</span>; <mentioned><u>punirai</u></mentioned>, <mentioned><u>punir</u></mentioned> <br> <span class="lineNumb"><b>2</b></span> <orig>d</orig> sometext sometext <span class="term" id="#formes2">formes</span> sometext sometext <span class="term" id="#memoire2">mémoire</span>; <mentioned><u>punirai</u></mentioned>, <mentioned><u>punir</u></mentioned> <br> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

好的,對於一個奇怪的問題 - 一個奇怪的解決方案。 為了達到最高性能,我們可以使用絕對定位的背景 div,並使用 css 完成所有事情(我們只需要計算正確的 div 高度)。

 window.onload = () => [...document.getElementsByClassName('lineNumb')].forEach(insertDivBefore); function insertDivBefore(element) { const rect = element.getBoundingClientRect(); const height = rect.bottom - rect.top; const newDiv = document.createElement("div"); newDiv.className = 'fillDiv'; newDiv.style.height = `${height}px`; document.getElementsByClassName('testoorig')[0].insertBefore(newDiv, element); }
 .fillDiv { opacity: .2; width: 100%; position: absolute; } .fillDiv:hover { background-color: coral; }
 <div class="testoorig"> <h3>Testo originale</h3> <div id="pag_10"></div> <br> <span class="lineNumb"><b>1</b></span> <orig>d</orig> sometext sometext <span class="term" id="#formes">formes</span> sometext sometext <span class="term" id="#memoire">mémoire</span>; <mentioned><u>punirai</u></mentioned>, <mentioned><u>punir</u></mentioned> <br> <span class="lineNumb"><b>2</b></span> <orig>d</orig> sometext sometext <span class="term" id="#formes2">formes</span> sometext sometext <span class="term" id="#memoire2">mémoire</span>; <mentioned><u>punirai</u></mentioned>, <mentioned><u>punir</u></mentioned> <br> </div>

首先,我將所有文本節點包裝在文檔准備好的跨度中。 然后我只需使用nextUntil()一行之前的所有元素,並使用add()來包含行號元素。

一些注意事項:

  • 您正在創建幾個全局變量。 根據需要使用letconst
  • 您在 jQuery 已經為您完成的地方手動循環。
  • 你似乎不需要g ,不管那是什么。
  • jQuery 提供了一個父方法 無需自己編寫。
  • 我喜歡 JavaScript 中的單引號,這樣里面的任何 HTML 都可以使用雙引號。

 $(function() { $('.testoorig').contents().each((i, c) => { // wrap text content nodes with a span if (c.nodeType === 3) { $(c).wrap('<span class="new-span" />'); } }); }); $(document).on('mouseover', '.lineNumb', function() { const target = $(this); const lineEls = target.nextUntil('.lineNumb').add(target); lineEls.css('background', 'pink'); }) .on('mouseout', '.lineNumb', function() { $('.testoorig').children().css('background', ''); });
 <div class="testoorig"> <h3>Testo originale</h3> <div id="pag_10"></div> <br> <span class="lineNumb"><b>1</b></span> <orig>d</orig> sometext sometext <span class="term" id="#formes">formes</span> sometext sometext <span class="term" id="#memoire">mémoire</span>; <mentioned><u>punirai</u></mentioned>, <mentioned><u>punir</u></mentioned> <br> <span class="lineNumb"><b>2</b></span> <orig>d</orig> sometext sometext <span class="term" id="#formes2">formes</span> sometext sometext <span class="term" id="#memoire2">mémoire</span>; <mentioned><u>punirai</u></mentioned>, <mentioned><u>punir</u></mentioned> <br> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

我建議用 javascript 重寫這些塊,這對於您將來需要的任何編輯都很有用。

所以,

  • 使用正則表達式獲取塊
  • 用標簽包裝塊

因此,您可以直接使用 HTML 塊,並且不需要偵聽器(您可以使用 CSS 懸停代替)。

此解決方案在頁面加載時使用了一些資源,但在頁面使用時節省了資源。

我選擇用“li”包裝輸出,因為它是一個列表

 // This regex extract all linesNum blocks, separated in an array, so it's easy to manipulate them // From lineNumb, included, to the second-mentioned, included. // If the input format will change will be easy to change the regex, it's quite intuitive const rex=new RegExp(/<span class="lineNumb">(.+?)(?=<\/mentioned>)(.+?)(?=<\/mentioned>)/g); function wrapOriginalText() { /// Exec thus code on page load, when text is already in the DOM const testoOrig = document.querySelector('.testoorig'); const arr = testoOrig.innerHTML.toString().replace(/\n/g, '').match(rex); /// This will substitute testoorig, can add a classlist or an id const testoCopiato = document.createElement("div"); const ul = document.createElement("ul"); testoCopiato.classList.add('testocopiato'); // wrap each line with li tags arr.forEach(function(lineEl){ /// create new block let el = document.createElement('li'); /// insert HTML extracted with the regex el.innerHTML=lineEl; /// append the new div in the new parent element ul.appendChild(el); }); // append the UL to the main div testoCopiato.appendChild(ul); // DOM was not modified yet, next 2 commands will write the DOM // Now remove the original testorig, testoOrig.parentNode.removeChild(testoOrig); // and substitute with testocopiato // I select "body" as a target, but you can chose where to put it document.querySelector("body").appendChild(testoCopiato); } wrapOriginalText();
 .testocopiato li:hover{ background-color: aquamarine; }
 <div class="testoorig"> <h3>Testo originale</h3> <div id="pag_10"></div> <br><span class="lineNumb"><b>1</b></span> <orig>d</orig> sometext sometext <span class="term" id="#formes">formes</span> sometext sometext <span class="term" id="#memoire">mémoire</span>; <mentioned><u>punirai</u></mentioned>, <mentioned><u>punir</u></mentioned> <!-- Next line (totally 31) --> <br><span class="lineNumb"><b>2</b></span> <orig>d</orig> some other text sometext <span class="term" id="#formes">formes</span> some new T some ... text <span class="term" id="#cesoir">ce soir</span>; <mentioned><u>dormirai</u></mentioned>, <mentioned><u>dormir</u></mentioned> </div> <!-- #testoorig -->

這足以突出整行

暫無
暫無

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

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