javascriptchild-nodes

How to find the visible text from a div


I want to find the text that is visible on screen from a div (i.e. that is not clipped by the scrollbar regions). Is there a way to see if a child node part is visible on screen? I can't find anywhere to even find the node coordinates, let alone how to see coords of the word parts of a node.

function doTest() {
  var elem = document.getElementById('mydiv');
  var nodes = elem.childNodes;
  for (var n = 0; n < nodes.length; n++) {
    console.log(nodes[n].textContent + isNodeVisible(nodes[n]));
    var words = nodes[n].textContent.split(' ');
    for (var w = 0; w < words.length; w++) {
      console.log(nodes[n].textContent + isNodeWordVisible(nodes[n], w));
      if (w > 10) break; // give up
    }
    if (n > 100) break;
  }
}

function isNodeVisible(node) {
  return 'who knows';
}

function isNodeWordVisible(node, wordN) {
  return 'who knows';
}
div {
  margin: 20px;
  border: solid 1px grey;
  padding: 10px;
  width: 200px;
  height: 200px;
  overflow: scroll
}
<div id='mydiv' onScroll='doTest()'>Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nunc eget lorem dolor sed viverra ipsum. Quis varius quam quisque id diam vel quam elementum pulvinar. Turpis egestas sed tempus
  urna et pharetra pharetra massa. Sed risus pretium quam vulputate dignissim suspendisse in. Quis hendrerit dolor magna eget est. Augue neque gravida in fermentum et sollicitudin. Nec sagittis aliquam malesuada bibendum arcu vitae elementum. Nibh tortor
  id aliquet lectus. Volutpat diam ut venenatis tellus in metus vulputate. Massa vitae tortor condimentum lacinia quis vel. Nec ultrices dui sapien eget mi proin sed. Augue neque gravida in fermentum et.Consectetur lorem donec massa sapien. Quis imperdiet
  massa tincidunt nunc pulvinar sapien et ligula ullamcorper. Fringilla est ullamcorper eget nulla. Sagittis id consectetur purus ut faucibus. Consequat ac felis donec et. Tellus orci ac auctor augue mauris augue neque gravida. Ut pharetra sit amet aliquam.
  A diam maecenas sed enim ut. Cras pulvinar mattis nunc sed blandit libero. Facilisi nullam vehicula ipsum a. Viverra tellus in hac habitasse.Neque gravida in fermentum et sollicitudin ac orci phasellus egestas. Tellus at urna condimentum mattis pellentesque
  id nibh. Lorem donec massa sapien faucibus et molestie ac. Aliquam malesuada bibendum arcu vitae. Fermentum et sollicitudin ac orci phasellus egestas tellus rutrum. Pharetra vel turpis nunc eget. Vitae elementum curabitur vitae nunc. Venenatis lectus
  magna fringilla urna porttitor rhoncus dolor purus non. Enim ut sem viverra aliquet eget sit amet. Sem nulla pharetra diam sit amet nisl suscipit. Amet massa vitae tortor condimentum lacinia quis vel. Erat pellentesque adipiscing commodo elit at imperdiet.
  Tortor id aliquet lectus proin nibh nisl condimentum id venenatis. A iaculis at erat pellentesque adipiscing. Porta lorem mollis aliquam ut porttitor leo.Tincidunt augue interdum velit euismod in pellentesque massa placerat duis. Bibendum neque egestas
  congue quisque. Adipiscing vitae proin sagittis nisl rhoncus mattis. Sem nulla pharetra diam sit amet nisl suscipit adipiscing. Sodales ut eu sem integer. Accumsan lacus vel facilisis volutpat. Adipiscing tristique risus nec feugiat in fermentum posuere
  urna nec. Malesuada fames ac turpis egestas sed tempus urna et pharetra. Bibendum est ultricies integer quis auctor elit. Sagittis nisl rhoncus mattis rhoncus urna. Amet facilisis magna etiam tempor orci eu.Fusce ut placerat orci nulla. Suscipit adipiscing
  bibendum est ultricies integer quis auctor elit sed. Platea dictumst quisque sagittis purus sit amet volutpat. Ac orci phasellus egestas tellus rutrum tellus pellentesque. Aenean et tortor at risus viverra adipiscing at. Nullam eget felis eget nunc
  lobortis mattis aliquam faucibus. Orci dapibus ultrices in iaculis nunc sed. Etiam erat velit scelerisque in dictum non consectetur a. Morbi tristique senectus et netus et malesuada fames ac. Urna duis convallis convallis tellus id interdum velit. Nam
  at lectus urna duis convallis convallis tellus id. Nullam eget felis eget nunc lobortis mattis aliquam. Faucibus turpis in eu mi bibendum neque. Orci porta non pulvinar neque laoreet suspendisse interdum consectetur. Sed augue lacus viverra vitae congue.
  Fermentum posuere urna nec tincidunt praesent semper feugiat nibh. Vel facilisis volutpat est velit. Dignissim diam quis enim lobortis scelerisque fermentum dui. Neque ornare aenean euismod elementum. At urna condimentum mattis pellentesque id.Massa
  eget egestas purus viverra accumsan in nisl nisi. Arcu cursus vitae congue mauris. Phasellus faucibus scelerisque eleifend donec pretium. Odio facilisis mauris sit amet massa vitae. Amet commodo nulla facilisi nullam vehicula ipsum a. Est velit egestas
  dui id ornare arcu odio. Enim lobortis scelerisque fermentum dui. Natoque penatibus et magnis dis parturient montes nascetur ridiculus. Morbi tristique senectus et netus et malesuada fames ac turpis. Nec tincidunt praesent semper feugiat nibh sed pulvinar.
  Consequat semper viverra nam libero. Non curabitur gravida arcu ac tortor dignissim convallis aenean. Dignissim suspendisse in est ante in nibh mauris cursus.Tellus in metus vulputate eu scelerisque. In massa tempor nec feugiat nisl pretium fusce id.
  Eget velit aliquet sagittis id consectetur. Dictumst quisque sagittis purus sit. Eget sit amet tellus cras adipiscing enim. Non enim praesent elementum facilisis leo vel fringilla est. Aliquet eget sit amet tellus cras adipiscing enim eu. Pellentesque
  id nibh tortor id aliquet lectus proin nibh. Imperdiet massa tincidunt nunc pulvinar sapien et. Leo integer malesuada nunc vel risus commodo. Feugiat sed lectus vestibulum mattis. Eu feugiat pretium nibh ipsum consequat nisl. Maecenas accumsan lacus
  vel facilisis volutpat est velit egestas.Orci phasellus egestas tellus rutrum tellus pellentesque eu tincidunt tortor. Nunc pulvinar sapien et ligula ullamcorper. Nullam vehicula ipsum a arcu cursus vitae congue mauris. Erat imperdiet sed euismod nisi
  porta lorem mollis. In vitae turpis massa sed elementum tempus egestas sed. Sit amet venenatis urna cursus eget nunc scelerisque viverra mauris. Tortor vitae purus faucibus ornare suspendisse. Eget magna fermentum iaculis eu non diam. Dui id ornare
  arcu odio ut sem nulla pharetra. Viverra vitae congue eu consequat ac felis donec et odio. Aliquam sem et tortor consequat id porta nibh venenatis. Consequat semper viverra nam libero justo laoreet. Purus faucibus ornare suspendisse sed nisi lacus.
  In arcu cursus euismod quis viverra. Tortor id aliquet lectus proin nibh nisl condimentum. Egestas congue quisque egestas diam in arcu. Sed risus ultricies tristique nulla aliquet enim tortor. Amet luctus venenatis lectus magna. Est placerat in egestas
  erat imperdiet sed euismod.Leo integer malesuada nunc vel risus commodo viverra maecenas. Mi proin sed libero enim sed faucibus turpis. Ac turpis egestas maecenas pharetra convallis posuere morbi leo urna. Vel risus commodo
</div>

Any thoughts?


Solution

  • Ok - I think I've come up with a work around -

    1. Insert some invisible tags (<a class='split'></a>) every 200 visible (non-tag) characters

    2. Use a lazy-load technique to scan for the "splits" and ask if they are visible

    3. Then using the knowledge of which splits are visible and which aren't I can guess which words are likely to be in the visible section of the container (within 200 characters).

       function doAddSplits() {
           var elem=document.getElementById('mydiv');
           var intag=false;
           var c;
           var step=100;
           var splitElemTx='<a class=\'split\'></a>';
           var n=0;
           elem.innerHTML=splitElemTx+elem.innerHTML;
           for(var p=0; p<elem.innerHTML.length; p++) {
               c=elem.innerHTML.substr(p,1);
               if ( c=='<' ) intag=true;
               else if ( c=='>' ) intag=false;
               else {
                   n++;
                   if ( n>=step && !isAlphabetic(c)) {
                       elem.innerHTML=elem.innerHTML.substr(0,p)+splitElemTx+elem.innerHTML.substr(p);
                       p=p+splitElemTx.length;
                       n=0;
                   }
               }
           }
       }
      
      
       function doScrollDiv(){
           var splits=document.getElementsByClassName('split');
           var container=document.getElementById('mydiv');
           for(var s=0; s<splits.length; s++){
               removeClassName(splits[s],'onscreen');
               if(isInViewport(splits[s], container)){
                   addClassName(splits[s],'onscreen');
               }
           }
       }
      
      
       function isInViewport(el, containerElem){
           var rect = el.getBoundingClientRect();
           var container = containerElem.getBoundingClientRect();
      
           return (
               rect.bottom >= container.top &&
               rect.right >= container.left &&
               rect.top <= (container.bottom) &&
               rect.left <= (container.right)
           );
       }