代码之家  ›  专栏  ›  技术社区  ›  asanas

突出显示句子中单击时的单词

  •  0
  • asanas  · 技术社区  · 5 年前

    在Javascript中,我编写了一个脚本,在用户单击某个单词时将其突出显示。

    这个问题在有些地方已经有了答案。我已经使用了这些解决方案中的答案来创建这个脚本,它工作得非常好。

    $(".clickable").click(function(e){
          var selectedVocabPhrase = null
          var matchedVocabPhrase = null
          var selection = window.getSelection()
    
          if (selection.anchorNode.parentNode.nodeName === 'STRONG') {
            selectedVocabPhrase = selection.anchorNode.parentNode.innerText
          }
          if (!selection || selection.rangeCount < 1) return true;
          var range = selection.getRangeAt(0);
          var node = selection.anchorNode;
    
          var word_regexp = /^\w*$/;
    
          // Extend the range backward until it matches word beginning
          while ((range.startOffset > 0) && range.toString().match(word_regexp)) {
            range.setStart(node, (range.startOffset - 1));
          }
          // Restore the valid word match after overshooting
          if (!range.toString().match(word_regexp)) {
            range.setStart(node, range.startOffset + 1);
          }
    
          // Extend the range forward until it matches word ending
          while ((range.endOffset < node.length) && range.toString().match(word_regexp)) {
            range.setEnd(node, range.endOffset + 1);
          }
          // Restore the valid word match after overshooting
          if (!range.toString().match(word_regexp)) {
            range.setEnd(node, range.endOffset - 1);
          }
      console.log(range.toString().trim());
    });
    

    https://jsbin.com/faxibolebu/edit?html,js,console,output

    但是,也有一些问题/例如,如果一个单词有hypth-例如co-worker,那么如果co被单击,那么co只被高亮显示。如果单击“worker”,则只突出显示“worker”。类似的问题是单词包含撇号,比如不能。单词被拆分。

    我无法解决这个问题。如有任何帮助,我们将不胜感激。

    1 回复  |  直到 5 年前
        1
  •  3
  •   CertainPerformance    5 年前

    而不是匹配 \w* \S* ,它匹配任何非空格字符。

    . s和 , s、 添加 (?![.,])\S . ,然后匹配任何非空格字符)。

    另外,如果用户 故意的 单击和拖动以选择文本,您可能会考虑将现有的突出显示为IS(这是更为用户友好的,并避免奇怪和/或模糊的行为,如当选择多个单词)。通过检查 startOffset 等于 endOffset :

    $(".clickable").click(function(e) {
      var selectedVocabPhrase = null
      var matchedVocabPhrase = null
      var selection = window.getSelection()
    
      if (selection.anchorNode.parentNode.nodeName === 'STRONG') {
        selectedVocabPhrase = selection.anchorNode.parentNode.innerText
      }
      if (!selection || selection.rangeCount < 1) return true;
      var range = selection.getRangeAt(0);
      if (range.startOffset !== range.endOffset) {
        // User selected at least one character themselves; don't change anything
        return;
      }
      var node = selection.anchorNode;
    
      var word_regexp = /^(?:|\S*(?![.,])\S)$/;
    
      // Extend the range backward until it matches word beginning
      while ((range.startOffset > 0) && range.toString().match(word_regexp)) {
        range.setStart(node, (range.startOffset - 1));
      }
      // Restore the valid word match after overshooting
      if (!range.toString().match(word_regexp)) {
        range.setStart(node, range.startOffset + 1);
      }
    
      // Extend the range forward until it matches word ending
      while ((range.endOffset < node.length) && range.toString().match(word_regexp)) {
        range.setEnd(node, range.endOffset + 1);
      }
      // Restore the valid word match after overshooting
      if (!range.toString().match(word_regexp)) {
        range.setEnd(node, range.endOffset - 1);
      }
      console.log(range.toString().trim());
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div class="clickable">
      <div>
        <div>
          <div class="v-popover">
            <span aria-describedby="popover_8k4slo118o" tabindex="-1" class="trigger" style="display: inline-block;">
                <span>When office worker Laura Garzón visited a butcher's shop in Bogota, she <strong>couldn't believe her eyes</strong>.
                </span>
            </span>
          </div>
          <div class="v-popover">
            <span aria-describedby="popover_tb8xft1vhg" tabindex="-1" class="trigger" style="display: inline-block;">
                <span> Standing behind the counter was her co-worker, Jorge Castro.
                </span>
            </span>
          </div>
          <div class="v-popover"><span aria-describedby="popover_1b3s8fw9ee" tabindex="-1" class="trigger" style="display: inline-block;">
              <span style="cursor: pointer; display: inline !important;"> But instead of wearing a suit and tie, he was wearing a bloodstained butcher's apron and white cap.
              </span>
            </span>
          </div>
        </div>
      </div>
    </div>