Home > Software engineering >  How to get text nodes from a parent node, and insert them in a div/span using jQuery/JS
How to get text nodes from a parent node, and insert them in a div/span using jQuery/JS

Time:06-14

I have this HTML code:

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

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

  <br><span ><b>2</b></span> .....

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

I can't add anything in the DOM, because it's HTML produced by XSLT and for many reasons I can't edit it

I have this 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");
    }
  });

So I would like that when you are mousing over each line, the entire line became "background: antiquewhite", in short words the line it has to be selected and marked. Only the current line has to be marked (that's why I use nextUntil(".lineNumber"))

But, I only get stylized d (in <orig>), 1 (in <b>), formes, mèmoire(in <span>) punirai, punir (in <mentioned>)

It seems my code can't get "sometext", how can I get this and stylize it? (maybe wrapping it in a div or a span, something like this)

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 >
  <h3>Testo originale</h3>
  <div id="pag_10"></div>
  <br><span ><b>1</b></span>
  <orig>d</orig> sometext sometext
  <span  id="#formes">formes</span> sometext sometext <span  id="#memoire">mémoire</span>;
  <mentioned><u>punirai</u></mentioned>,
  <mentioned><u>punir</u></mentioned>
  <br><span ><b>2</b></span>
</div>
<!-- #testoorig -->


<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

CodePudding user response:

First I'd wrap all text nodes in spans on document ready. Then I'd just use nextUntil() to grab all elements before the next line, along with add() to include the line number element.

Some notes:

  • You were creating several global variables. Use let or const as appropriate.
  • You were looping manually where jQuery already does it for you.
  • You don't seem to need g, whatever that was.
  • jQuery provides a parent method. No need to write your own.
  • I like single quotes in JavaScript, so that any HTML inside can use double quotes.

$(function() {
  $('.testoorig').contents().each((i, c) => {
    // wrap text content nodes with a span
    if (c.nodeType === 3) {
      $(c).wrap('<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 >
  <h3>Testo originale</h3>
  <div id="pag_10"></div>
  <br>

  <span ><b>1</b></span>
  <orig>d</orig> sometext sometext
  <span  id="#formes">formes</span> sometext sometext <span  id="#memoire">mémoire</span>;
  <mentioned><u>punirai</u></mentioned>,
  <mentioned><u>punir</u></mentioned>
  <br>

  <span ><b>2</b></span>
  <orig>d</orig> sometext sometext
  <span  id="#formes2">formes</span> sometext sometext <span  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>

CodePudding user response:

Applying a background color to a collection of text-nodes and elements within one element (div) is not really possible as such. I therefore suggest, you manipulate the innerHTML of the div.testoorig: group all the elements you want to have a common background color together in one div.row. After that the hover-event can be easily assigned to these .row divs with a single .on("mouseover mouseout",".row",function(ev){...}):

const a='<div >',b='</div>';
$(".testoorig")
 .html((_,html)=>{
   let arr=html.split("<br>");
   return arr.shift() a arr.join(b a) b;
 })
 .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 >
   <h3>Testo originale</h3>
   <div id="pag_10"></div>
   <br><span ><b>1</b></span>
   <orig>d</orig>  first text sometext
   <span  id="#formes">formes</span>
   sometext sometext
   <span  id="#memoire">mémoire</span>;
   <mentioned><u>punirai</u></mentioned>, 
   <mentioned><u>punir</u></mentioned>

   <br><span ><b>2</b></span>
   <orig>d</orig>  second text sometext
   <span  id="#formes">formes</span>
   sometext sometext
   <span  id="#memoire">mémoire</span>;
   <mentioned><u>punirai</u></mentioned>, 
   <mentioned><u>punir</u></mentioned>

   <br><span ><b>3</b></span>
   <orig>d</orig>  third text sometext
   <span  id="#formes">formes</span>
   sometext sometext
   <span  id="#memoire">mémoire</span>;
   <mentioned><u>punirai</u></mentioned>, 
   <mentioned><u>punir</u></mentioned>
</div>

  • Related