Home get index of a searched word in a page jquery
Reply: 1

get index of a searched word in a page jquery

Ravi Prakash Awasthi
1#
Ravi Prakash Awasthi Published in 2018-01-13 11:20:41Z

I have a div containg following text. I want to search like an editor. I have tried many time to solve my problem but I didn't found any solution.Please guide me how can I resolve my problem.

  <div id="content">
        <p>
            Lorem Ipsum is simply dummy text of the printing and typesetting industry.
            Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
            when an unknown printer took a galley of type and scrambled it to make a type specimen book.
            It has survived not only five centuries, but also the leap into electronic typesetting,
            remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset
            sheets containing Lorem Ipsum passages, and more recently with desktop publishing software
            like Aldus PageMaker including versions of Lorem Ipsum.
        </p>
        <p>
            Lorem Ipsum is simply dummy text of the printing and typesetting industry.
            Lorem Ipsum has been the industry's standard dummy text ever since the 1500s,
            when an unknown printer took a galley of type and scrambled it to make a type specimen book.
            It has survived not only five centuries, but also the leap into electronic typesetting,
            remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset
            sheets containing Lorem Ipsum passages, and more recently with desktop publishing software
            like Aldus PageMaker including versions of Lorem Ipsum.
        </p>
    </div>

Now I have selected a word for example first dummy in first paragraph, it should return 1 out of 4.Right now it alerts only 4(total count of dummy in div)

Thanx in anticipation.My jquery is

 $(document).ready(function () {
            $('#content').mouseup(function () {
                var sel = window.getSelection().toString();
                wordCount = occurrences(sel);
                alert(wordCount);
            })
        })
        function occurrences(subString, allowOverlapping) {
            string = $('#content').text();
            subString += "";
            if (subString.length <= 0)
                return (string.length + 1);
            var n = 0,
                    pos = 0,
                    step = allowOverlapping ? 1 : subString.length;
            while (true) {
                pos = string.indexOf(subString, pos);
                if (pos >= 0) {
                    ++n;
                    pos += step;
                } else
                    break;
            }
            return n;
        }
some
2#
some Reply to 2018-01-13 14:44:39Z

To be able to find which occurrence you have selected, you need to find the position of the selection in the text. And since the haystack where you are searching have nodes, you first need to convert that to text, but when it is converted to text you have lost the position...

To solve this, I created the function getTextAndFindOffset. With the container element as input, and the selected text node and offset in that text node, it will concatenate all text of the container element in a way where it can find the position of the selected node.

getSelection returns a Selection-object with a lot of properties. I'm going to use anchorNode since that have the node where the selection starts, and anchorOffset since that have the offset where the selection start in that node.

I use an object to store the current state, since I'm using recursion to solve the problem of how to get the text from child nodes.

When getTextAndFindOffset has been executed, I can get the text and offset from the state-variable.

When the text has been concatenated and the offset of the selection is found, I used your method to find the selected text. If the offset of the currently found text is the same as the state.offset you have found the selected text, and therefore just need to copy the counter. Notice the index is 0-based, so the first occurrence is 0, therefore you need to add one to this value when you are displaying it to the user.

$(document).ready(function() {
  $('#content').mouseup(function() {
    var result = find(document.getElementById('content'), window.getSelection(), true);

    if (result) {
      alert(`${result.index + 1} of ${result.count}`);
    }
  })
})

// This function concatenates all text from node, and find the
// offset of findNode.
//  state = {
//    findNode   : text node to find
//    findOffset : offset in findNode
//    text       : concatenated text
//    offset     : offset in text
//  }
function getTextAndFindOffset(state, node) {
  if (node === state.findNode) {
    // If this is the node we are looking for, set the offset
    // to the correct position and then add the text.
    state.offset = state.text.length + state.findOffset;
    state.text += node.textContent;
  } else {
    // Iterate over all child nodes
    for (let idx = 0, len = node.childNodes.length; idx < len; idx += 1) {
      let child = node.childNodes[idx];
      if (child === state.findNode) {
        // If this is the node we are looking for, set the offset
        // to the correct position and then add the text.
        state.offset = state.text.length + state.findOffset;
        state.text += child.textContent;
      } else if (child.contains(state.findNode)) {
        // If the node we are searching for is contained in the child
        // node, recursively call this function, but now with the child.
        getTextAndFindOffset(state, child);
      } else {
        // If the node we are searching for isn't contained in the child
        // node, just add the text contents.
        state.text += child.textContent;
      }
    }
  }
}

// context : the container node.
// selection : the result from getSelection
function find(context, selection, allowOverlapping) {
  var state = {
    findNode: selection.anchorNode, // start node
    findOffset: selection.anchorOffset, // offset in start node
    offset: -1,
    text: ''
  }
  // concate text and get position
  getTextAndFindOffset(state, context);

  var result = {
    text: state.text,
    findText: selection.toString(), // text to find
    count: 0,
    index: null // index of findText
  }

  if (result.findText.length === 0) return null;

  var step = allowOverlapping ? 1 : result.findText.length;
  var pos;
  while ((pos = result.text.indexOf(result.findText, pos)) >= 0) {
    if (pos === state.offset) result.index = result.count;
    result.count += 1;
    pos += step;
  }
  return result;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="content">
  <p>
    Lorem Ipsum is simply <span>dummy</span> text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen
    book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with
    desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. xaxaxaxa
  </p>
  <p>
    Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has
    survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing
    software like Aldus PageMaker including versions of Lorem Ipsum. xaxaxaxa
  </p>
</div>

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.319502 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO