【问题标题】:Text selection in div(contenteditable) when double click双击时div(contenteditable)中的文本选择
【发布时间】:2012-10-06 21:05:55
【问题描述】:

我有带有一些文本和 contenteditable="true" 的 div。当我单击此 div 时 - 运行我的一些脚本,它不是很重要。当我双击这个 div 时 - 需要在 div 中编辑文本。编辑文本只需要在双击之后,而不是在单击之后。并且非常重要,当我双击 div 时 - 插入符号需要停留在鼠标光标下。无需选择文本。我找到了一些单/双的脚本。但是有问题。当我双击 div - 文本是选择。选择不需要。在我点击的地方需要编辑插入符号。我不明白怎么做。 http://jsfiddle.net/X6auM/

【问题讨论】:

  • 单击编辑是contenteditable 元素的预期结果。如果要使用双击,请在元素被双击时设置contenteditableonly。一旦可编辑,将焦点放在元素上,然后根据双击事件中的鼠标位置设置插入符号。最后,当焦点丢失时,禁用contenteditable
  • 我不明白如何将光标准确地放在有点击的地方。这与 .focus()。但是插入符号转到行首。 jsfiddle.net/jupUh
  • 如果插入符号没有在div中,如何找到它的位置?
  • 我找到了获得插入符号位置的脚本。脚本有效,但在这种情况下无效。 jsfiddle.net/9Z3bp/1

标签: javascript jquery contenteditable textselection


【解决方案1】:

目前每个主流浏览器都提供了一个 API 来根据鼠标事件创建范围,尽管需要四个不同的代码分支。

这里有一些背景:

这是一个演示:http://jsfiddle.net/timdown/krtTD/10/

这里有一些代码:

function getMouseEventCaretRange(evt) {
    var range, x = evt.clientX, y = evt.clientY;

    // Try the simple IE way first
    if (document.body.createTextRange) {
        range = document.body.createTextRange();
        range.moveToPoint(x, y);
    }

    else if (typeof document.createRange != "undefined") {
        // Try Mozilla's rangeOffset and rangeParent properties,
        // which are exactly what we want
        if (typeof evt.rangeParent != "undefined") {
            range = document.createRange();
            range.setStart(evt.rangeParent, evt.rangeOffset);
            range.collapse(true);
        }

        // Try the standards-based way next
        else if (document.caretPositionFromPoint) {
            var pos = document.caretPositionFromPoint(x, y);
            range = document.createRange();
            range.setStart(pos.offsetNode, pos.offset);
            range.collapse(true);
        }

        // Next, the WebKit way
        else if (document.caretRangeFromPoint) {
            range = document.caretRangeFromPoint(x, y);
        }
    }

    return range;
}

function selectRange(range) {
    if (range) {
        if (typeof range.select != "undefined") {
            range.select();
        } else if (typeof window.getSelection != "undefined") {
            var sel = window.getSelection();
            sel.removeAllRanges();
            sel.addRange(range);
        }
    }
}

document.getElementById("editor").ondblclick = function(evt) {
    evt = evt || window.event;
    this.contentEditable = true;
    this.focus();
    var caretRange = getMouseEventCaretRange(evt);

    // Set a timer to allow the selection to happen and the dust settle first
    window.setTimeout(function() {
        selectRange(caretRange);
    }, 10);
    return false;
};

【讨论】:

  • 太棒了!昨天我做了一些其他的方法。但效果不是很好。你的版本工作正常。谢谢!
【解决方案2】:
$('p').dblclick(function(event) {
  $this = $(this);
  $this.attr('contenteditable', "true");
  $this.blur();
  $this.focus();
});

http://jsfiddle.net/krtTD/90/

【讨论】:

  • 一个建议,如果你也解释了你在做什么,你的答案就是完整的。
【解决方案3】:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <!-- <link rel="stylesheet" href="../tailwind.css" /> -->
</head>

<body>
    <div id="editor" style="user-select:none;" contenteditable="false">Some editableasa text. Double click to eadsit</div>
    <script>
        function getMouseEventCaretRange(evt) {
            var range, x = evt.clientX, y = evt.clientY;

            // Try the simple IE way first
            if (document.body.createTextRange) {
                range = document.body.createTextRange();
                range.moveToPoint(x, y);
            }

            else if (typeof document.createRange != "undefined") {
                // Try Mozilla's rangeOffset and rangeParent properties, which are exactly what we want

                if (typeof evt.rangeParent != "undefined") {
                    range = document.createRange();
                    range.setStart(evt.rangeParent, evt.rangeOffset);
                    range.collapse(true);
                }

                // Try the standards-based way next
                else if (document.caretPositionFromPoint) {
                    var pos = document.caretPositionFromPoint(x, y);
                    range = document.createRange();
                    range.setStart(pos.offsetNode, pos.offset);
                    range.collapse(true);
                }

                // Next, the WebKit way
                else if (document.caretRangeFromPoint) {
                    range = document.caretRangeFromPoint(x, y);
                }
            }

            return range;
        }

        function selectRange(range) {
            if (range) {
                if (typeof range.select != "undefined") {
                    range.select();
                } else if (typeof window.getSelection != "undefined") {
                    var sel = window.getSelection();
                    sel.removeAllRanges();
                    sel.addRange(range);
                }
            }
        }


        document.getElementById("editor").ondblclick = function (evt) {
            evt = evt || window.event;
            this.contentEditable = true;

            this.focus();
            var caretRange = getMouseEventCaretRange(evt);
            selectRange(caretRange);
            this.style = ""
        };

    </script>
</body>

</html>

对已接受答案的改进,它不会创建临时闪存,它使用 css 用户选择属性来获得优势

【讨论】:

    猜你喜欢
    • 2011-04-17
    • 2012-08-27
    • 1970-01-01
    • 2012-08-25
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多