Выбор текста в div (contenteditable) при двойном щелчке

У меня есть div с текстом и contenteditable="true". Когда я один раз нажимаю на этот div - работают некоторые мои скрипты, это не очень важно. И когда я дважды щелкаю по этому div - нужно редактировать текст в div. Редактировать текст нужно только после двойного клика, а не после одинарного. И очень важно, когда я дважды щелкаю по div - курсор должен оставаться под курсором мыши. Текст выделения не нужен. Я нашел какой-то скрипт для одинарного/двойного. Но есть проблема. Когда я дважды щелкаю по div, текст выделяется. Отбор не нужен. Нужен редактор каретки там, где я нажал. Я не понимаю как. http://jsfiddle.net/X6auM/


person Alex-cr    schedule 16.10.2012    source источник
comment
Редактирование в один клик — это ожидаемый результат для contenteditable элемента. Если вы хотите использовать двойной щелчок, установите contenteditable только при двойном щелчке элемента. После редактирования сфокусируйтесь на элементе, а затем установите курсор в зависимости от положения мыши в результате двойного щелчка. Наконец, когда фокус потерян, отключите функцию contenteditable.   -  person Jay    schedule 16.10.2012
comment
Я не понимаю, как поставить курсор именно на то место, где был щелчок. Это с .focus(). Но курсор переходит к началу строки. jsfiddle.net/jupUh   -  person Alex-cr    schedule 16.10.2012
comment
Как я могу найти положение курсора, если его не было в div?   -  person Alex-cr    schedule 16.10.2012
comment
Я нашел скрипт, который получает позицию каретки. Скрипт работает, но не в этой ситуации. jsfiddle.net/9Z3bp/1   -  person Alex-cr    schedule 16.10.2012


Ответы (3)


Каждый современный основной браузер предоставляет 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;
};
person Tim Down    schedule 16.10.2012
comment
Это потрясающе! Вчера я сделал несколько других методов. Но работает не очень хорошо. Ваша версия работает нормально. Спасибо! - person Alex-cr; 17.10.2012

$('p').dblclick(function(event) {
  $this = $(this);
  $this.attr('contenteditable', "true");
  $this.blur();
  $this.focus();
});

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

person Cihad    schedule 01.07.2015
comment
Предложение, ваш ответ будет полным, если вы объясните, что вы делаете. - person Rohit Gupta; 01.07.2015

<!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 user-select в своих интересах.

person Chetan Jain    schedule 23.07.2021