检测文本中单击的单词

Cys*_*ack 38 html javascript parsing

我正在构建一个JS脚本,在某个点上,它可以在给定页面上允许用户单击任何单词并将该单词存储在变量中.

我有一个非常难看的解决方案,并使用jQuery进行类解析:我首先解析整个html,拆分每个空间的所有内容" ",并重新附加包含在a中的所有内容<span class="word">word</span>,然后我添加一个带有jQ的事件来检测点击次数这样一个类,并使用$(this).innerHTML我得到点击的单词.

这在很多方面都是缓慢而丑陋的,我希望有人知道另一种方法来实现这一目标.

PS:我可能会考虑将其作为浏览器扩展程序运行,所以如果单纯的JS听起来不可能,并且如果您知道允许的浏览器API,请随时提及它!

一个可能的owrkaround将是让用户突出显示单词而不是单击它,但我真的希望能够通过只需单击即可实现相同的功能!

ste*_*els 50

这是一个解决方案,可以在不向文档添加大量跨度的情况下工作(适用于Webkit和Mozilla和IE9 +):

http://jsfiddle.net/Vap7C/15/

<p class="clickable">some words</p>

$(".clickable").click(function(e) {
    s = window.getSelection();
    var range = s.getRangeAt(0);
    var node = s.anchorNode;
    while (range.toString().indexOf(' ') != 0) {
        range.setStart(node, (range.startOffset - 1));
    }
    range.setStart(node, range.startOffset + 1);
    do {
        range.setEnd(node, range.endOffset + 1);

    } while (range.toString().indexOf(' ') == -1 && range.toString().trim() != '' && range.endOffset < node.length);
    var str = range.toString().trim();
    alert(str);
});?
Run Code Online (Sandbox Code Playgroud)

在IE8中,由于getSelection,它有问题.这个链接(是否有针对getSelection()的跨浏览器解决方案?)可能有助于解决这些问题.我没有在Opera上测试过.

我从一个类似的问题中使用http://jsfiddle.net/Vap7C/1/作为起点.它使用了Selection.modify函数:

s.modify('extend','forward','word');
s.modify('extend','backward','word');
Run Code Online (Sandbox Code Playgroud)

不幸的是,他们并不总能得到全部的信息.作为一种解决方法,我获得了选择范围,并添加了两个循环来查找单词边界.第一个不断添加字符直到它到达空格.第二个循环到达单词的末尾,直到到达空格.

这也将抓住单词末尾的任何标点符号,因此如果需要,请确保将其修剪掉.

  • 一位匿名用户建议这个编辑:一个改进的解决方案,总是得到正确的单词,更简单,并在IE 4 +中工作:http://jsfiddle.net/Vap7C/80/ (11认同)
  • 我不是第一个字.至少在Chromium/Linux中 (3认同)

thi*_*dot 13

据我所知,span为每个单词添加一个是唯一的方法.

你可以考虑使用Lettering.js来处理你的分裂.虽然这不会真正影响性能,除非你的"分裂代码"效率低下.

然后,不是绑定.click()到每个span,而是将单个绑定.click()spans 的容器更有效,并检查event.target哪个span已被单击.


spi*_*ike 5

我知道的唯一跨浏览器(IE <8)方式是包装在span元素中。这很丑,但并不是那么慢。

该示例直接来自jQuery .css()函数文档,但有大量文本需要预处理:

http://jsfiddle.net/kMvYy/

这是在不需要换行的同一文本块上执行此操作的另一种方法(在此处给出:jquery捕获单词valuespanhttp://jsfiddle.net/Vap7C/1


lin*_*0ff 5

以下是可接受答案的改进:

$(".clickable").click(function (e) {
    var selection = window.getSelection();
    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);
    }

    var word = range.toString();
});?
Run Code Online (Sandbox Code Playgroud)


car*_*10m 5

另一个对@stevendaniel 的回答的看法:

$('.clickable').click(function(){
   var sel=window.getSelection();
   var str=sel.anchorNode.nodeValue,len=str.length, a=b=sel.anchorOffset;
   while(str[a]!=' '&&a--){}; if (str[a]==' ') a++; // start of word
   while(str[b]!=' '&&b++<len){};                   // end of word+1
   console.log(str.substring(a,b));
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<p class="clickable">The objective can also be achieved by simply analysing the
string you get from <code>sel=window.getSelection()</code>. Two simple searches for
the next blank before and after the word, pointed to by the current position
(<code>sel.anchorOffset</code>) and the work is done:</p>

<p>This second paragraph is <em>not</em> clickable. I tested this on Chrome and Internet explorer (IE11)</p>
Run Code Online (Sandbox Code Playgroud)