获取页面jquery中搜索单词的索引

时间:2018-01-13 11:20:42

标签: javascript jquery html

我有一个包含以下文字的div。我想像编辑一样搜索。我已经尝试了很多时间来解决我的问题,但我没有找到任何解决方案。请指导我如何解决我的问题。

  <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>

现在我在第一段中选择了一个单词,例如第一个虚拟,它应该返回 4个中的1个。现在它仅警告4个(总计数<在div中强>虚拟

Thanx期待。我的jquery是

 $(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;
        }

1 个答案:

答案 0 :(得分:0)

为了能够找到您选择的事件,您需要在文本中找到选择的位置。由于你正在搜索的干草堆有节点,你首先需要将其转换为文本,但是当它转换为文本时你就失去了位置......

为了解决这个问题,我创建了函数 getTextAndFindOffset 。使用容器元素作为输入,以及该文本节点中选定的文本节点和偏移量,它将以能够找到所选节点位置的方式连接容器元素的所有文本。

getSelection返回一个包含大量属性的Selection - 对象。我将使用 anchorNode ,因为它具有选择开始的节点,以及 anchorOffset ,因为它具有选择从该节点开始的偏移量。

我使用一个对象来存储当前状态,因为我使用recursion来解决如何从子节点获取文本的问题。

当执行 getTextAndFindOffset 时,我可以从状态变量获取文本和偏移量。

当连接文本并找到选择的偏移量时,我使用您的方法查找所选文本。如果当前找到的文本的偏移量与 state.offset 相同,则表示您找到了所选文本,因此只需要复制计数器。 注意索引从0开始,因此第一次出现为0,因此在向用户显示时,需要向此值添加一个。

&#13;
&#13;
$(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;
}
&#13;
<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>
&#13;
&#13;
&#13;