[英]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.testoorig
的innerHTML
:將您想要具有共同背景顏色的所有元素組合在一個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()
來包含行號元素。
一些注意事項:
let
或const
。g
,不管那是什么。 $(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.