【问题标题】:how to get selected text, but can I get surrounding context in javascript?如何获取选定的文本,但我可以在 javascript 中获取周围的上下文吗?
【发布时间】:2011-05-18 23:30:48
【问题描述】:

我能够抓取用户在网页上选择的文本, 使用此代码:

function getSelected() {
  var userSelection;
  if (window.getSelection) {
      selection = window.getSelection();
  } else if (document.selection) {
      selection = document.selection.createRange();
  }

}

我有没有可能得到周围的词 选定的词。

以这些句子为例:“如果你需要 framglubble zartbox,那么你应该买红色的小部件。 否则,您可以购买蓝色小部件并节省一些钱。”

我的代码会告诉我该人是否选择了“小部件”一词。 但我想知道选择是在“红色”还是“蓝色”之后。是 这可能吗?我一直在网上搜索一些建议,并且 我很难找到答案。

感谢您的帮助

【问题讨论】:

  • @James Wiseman:我打算含糊地回答“仅在 IE 中可能”和“使用 move("word", +-1) 方法,但希望您的页面会被大部分用户打破”。但是范围对我来说是全新的。如果你知道更好的方法,我对这里很感兴趣。
  • @user495688 - 你的问题是好的和有效的,但我同意詹姆斯的意见,你应该接受答案,这就是这个地方的运作方式。
  • 对不起,我忘记检查答案了..:)

标签: javascript selectedtext


【解决方案1】:

在非 IE 浏览器中执行此操作的方法是从 selection 获取 Range 对象。范围有一个开始和结束边界,范围的每个边界都表示为一个节点内的偏移量;如果边界在文本节点内,则此偏移量将是字符偏移量。

例如,如果以下是一个文本节点并且选择由竖线分隔:

"red |widget| blue widget"

...那么您从选择中获得的范围将在文本节点内具有 4 的起始偏移量。

以下将为您提供一个表示选择的范围并提醒开始边界:

var sel = window.getSelection();
var selectedRange = sel.rangeCount ? sel.getRangeAt(0) : null;
if (range) {
    alert("Offset " + selectedRange.startOffset
        + " in node " + selectedRange.startContainer.nodeName);
}

范围可以与其他范围进行比较,因此如果您想知道,例如,如果当前选择出现在上述文本节点中的单词“blue”之后,您可以创建一个包含单词“blue”的 Range 和将其与所选范围进行比较:

// Assume the text node is stored in a variable called textNode
var blueRange = document.createRange();
blueRange.setStart(textNode, 11);
blueRange.setEnd(textNode, 15);

var selectionIsAfterBlue =
   (selectedRange.compareBoundaryPoints(Range.END_TO_START, blueRange) == 1);

在 IE 中,这些都不起作用,而且一切都以不同的方式完成,通常难度更大。要将其规范化为单一一致的接口,您可以使用我的 Rangy 库。

【讨论】:

    【解决方案2】:

    我已经编写了快速脚本,可以识别同一 DIV 元素中选择之前和选择之后的部分。

    但是,如果同一个 DIV 多次包含同一个单词并且您只选择了该单词,我编写的当前代码无法识别它是第一个还是第二个选择的单词,因此最重要的是它不会满足您的需求。

    无论如何,您可以在此处查看/复制/测试代码:http://jsfiddle.net/kvHxJ/ 只需选择一些内容并查看出现的警报。

    如果这足以满足您的需求,那么,接受这个答案并继续前进......否则我需要知道:我们可以假设用户将只选择整个单词,只选择一个单词吗? 如果答案是肯定的,我确实知道如何解决这个问题。

    【讨论】:

    • 我假设用户 akam 选择一个词,然后我得到所选词之前和之后的词。但字数限制在20字以内,即前10字后10字,或者可以灵活,如果前一个字只包含5个字,则取15个字后。
    • 是否可以在不同的DIV/段落中识别选择前后的部分??
    • @user495688 - 仍然不确定代码是否足够,或者您是否还必须在同一段落中支持多个相同的单词。关于“在不同的 DIV/段落中选择之前和之后的部分”这并不容易 - 你不能控制文本的设计吗?
    • 是的,我必须在所选单词周围加上 20 个单词。例如,在第一段中有 5 个单词,而其他段落中的其余 15 个单词可以。这个问题的解决方法是什么?
    【解决方案3】:

    IE 具有move 方法集,可将此问题减少到几行,从而将选择向前或向后扩展任意数量的单词(请参阅http://www.webreference.com/js/column12/trmethods.html)。从那里开始,只需将文本与任意值列表进行比较即可。其他浏览器没有此功能 AFAIK。浏览器大战的命运:一个人开发了一个被任何其​​他专利忽略或禁止的很棒的功能,因此该功能永远丢失并避免,因为所有这些创新的跨浏览器支持负担不可避免地落在了网站设计者身上。

    因此,下面是一个通用函数,仅获取所选文本的父元素的 ID。而且,要使用这种跨浏览器解决方案,您必须将每个单词包装在它自己的元素中,并使用唯一的 ID 或其他属性完成。使用此设置,前后查看同级或顺序 ID/命名元素应该是一个相对轻松的跳转。

    这里的问题是客户端必须从单词或短语的开头单击/拖动到结尾,并且绝对没有边界空格。即使双击一个单词也会导致它引用下一个元素(或者在 IE 的情况下,父 DIV)。此外,您应该添加代码以将选择边界限制为单个父 DIV,因为下面的代码也可能会将选择扩展到周围元素。但希望你能从这里解决这个问题。否则,就需要使用向量来确定文本相对于所有周围文本的坐标。

    猜你喜欢
    • 2011-02-19
    • 2011-05-20
    • 2012-08-25
    • 2020-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    相关资源
    最近更新 更多