javascript - 如何使用 JavaScript 将选择范围扩展到字边界,仅一次?

标签 javascript html dom selection

我正在使用 this answer 中所示的技术将网页的选择扩展到单词边界:

function snapSelectionToWord() {
    var sel;

    // Check for existence of window.getSelection() and that it has a
    // modify() method. IE 9 has both selection APIs but no modify() method.
    if (window.getSelection && (sel = window.getSelection()).modify) {
        sel = window.getSelection();
        if (!sel.isCollapsed) {

            // Detect if selection is backwards
            var range = document.createRange();
            range.setStart(sel.anchorNode, sel.anchorOffset);
            range.setEnd(sel.focusNode, sel.focusOffset);
            var backwards = range.collapsed;
            range.detach();

            // modify() works on the focus of the selection
            var endNode = sel.focusNode, endOffset = sel.focusOffset;
            sel.collapse(sel.anchorNode, sel.anchorOffset);
            if (backwards) {
                sel.modify("move", "forward", "word");
                sel.extend(endNode, endOffset);
                sel.modify("extend", "backward", "word");

            } else {
                sel.modify("move", "backward", "word");
                sel.extend(endNode, endOffset);
                sel.modify("extend", "forward", "word");
            }
        }
    } else if ( (sel = document.selection) && sel.type != "Control") {
        var textRange = sel.createRange();
        if (textRange.text) {
            textRange.expand("word");
            // Move the end back to not include the word's trailing space(s),
            // if necessary
            while (/\s$/.test(textRange.text)) {
                textRange.moveEnd("character", -1);
            }
            textRange.select();
        }
    }
}​

到目前为止,还不错。但是,如果您在选择上多次调用 snapSelectionToWord 函数,每次调用时它都会在两个方向上向外扩展一个单词,如果您想在文本显示时多次调用它,这就不好了已选中。

这是一个 live jsFiddle example允许您重复单击“捕捉”按钮,这表明了问题。

如果原始解决方案已经在单词边界上,那么如何修复原始解决方案,使其不扩展选择?

  • 我想在 original solution 上发表评论但是,遗憾的是,我还没有被 StackOverflow 业力大队赋予足够的业力——否则,我就去那里问问。而且我不确定如何解决这个问题,所以我不会编辑原始解决方案。

编辑:为每个请求添加代码片段

最佳答案

我写了那个样本。由于您指出的原因,我一直对它不满意,也因为它不能在所有浏览器(或在 Opera 中)中始终如一地工作。

我一直在为我的 Rangy 开发一个跨浏览器的解决方案图书馆。当前版本被描述为 alpha,但它运行良好。这是一个演示:

http://rangy.googlecode.com/svn/trunk/demos/textrange.html

这是您的演示,已修改为使用 Rangy:

http://jsfiddle.net/timdown/RgZ8r/

关键的一行是

rangy.getSelection().expand("word");

如果您不想使用像 Rangy 这样重量级的东西(使用 TextRange 模块大约需要 50KB 的代码),那么可以改进原始代码(正如 Matt M 在他的回答中所做的那样),但它仍然会有局限性。

关于javascript - 如何使用 JavaScript 将选择范围扩展到字边界,仅一次?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10964016/

相关文章:

javascript - 使用 createDocumentFragment 插入嵌套的 div 结构

javascript - 是 var db = window.openDatabase && openDatabase();避免错误的好方法?

javascript - PHP 下拉列表所选值未插入数据库

javascript - 连续设置4张图片而不是2张图片

javascript - 如何在数据数组的每次迭代中创建内容为 "i+1"的新 HTML 元素

javascript - 如何在 IE6 中使用带有原型(prototype)的元素添加 <table>?

javascript - 如何使用 javascript 或 jquery 爬取 DOM,仅查看直系 parent ,而不查看叔叔/阿姨?

javascript - 使用 gmail api 发送电子邮件错误 : This API does not support parsing form-encoded input

javascript - ExecJS::RuntimeUnavailable 在 Rails 4.1.4 中

javascript - AngularJS 元素指令上的 CSS 样式未呈现