Выход из первого элемента в IHTMLTxtRange - PullRequest
0 голосов
/ 07 июня 2010

Я пытаюсь создать расширенный текстовый редактор для веб-приложения, и мне нужно иметь возможность пометить некоторые элементы в тексте как недоступные для редактирования пользователем. Причина этого в том, что они являются заполнителями для динамического контента (например, даты создания), для которого я хочу иметь предварительный просмотр в реальном времени.

В качестве примера возьмем следующий код - для облегчения нет панели инструментов или чего-либо еще, но текстовые области и HTML синхронизированы.

<!-- DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" -->
<html>
<head>
    <title>Hi</title>

    <script type="text/javascript" src="http://code.jquery.com/jquery-1.4.2.min.js"></script>

    <script>
        $(function() {
            g = {};

            g.iFrame = document.createElement("IFRAME");
            $("#frameContainer").append(g.iFrame);
            g.iDoc = g.iFrame.contentWindow.document;
            g.iDoc.designMode = "on";

            g.jTextArea = $("#textContainer textarea");

            setTimeout(function() {
                g.iDoc.body.innerHTML = "<b class=\"notype\">Cannot type here</b>";
                $(g.iDoc).trigger("keyup");
                $(g.iDoc.body).focus();
            }, 0);

            $(g.iDoc).keyup(function() {
                g.jTextArea.text(g.iDoc.body.innerHTML);
            });

            g.jTextArea.keyup(function() {
                g.iDoc.body.innerHTML = this.innerText;
            });

            var getSelection = function() {
                if (typeof g.iDoc.selection !== "undefined" && g.iDoc.selection.type !== "Text" && g.iDoc.selection.type !== "None") {
                    g.iDoc.selection.clear();
                }
                return g.iDoc.selection.createRange();
            };

            $(g.iDoc).keypress(function(event) {
                // If we're in a marked field, disable the operation.
                var sel = getSelection();

                if ($(sel.parentElement()).hasClass('notype')) {
                    sel.moveToElementText(sel.parentElement());
                    sel.collapse();
                    sel.move("character", -1);
                    sel.select();
                    $("#log").append("<div>outside of thing</div>");
                }
            });

            $(testLink).click(function() {
                // Try and insert stuff at the front
                $(g.iDoc.body).focus();
                var sel = getSelection();
                sel.moveToElementText(sel.parentElement());
                sel.collapse();
                sel.move("character", -100);
                sel.pasteHTML("Before html?");
                $(g.iDoc).trigger("keyup");
                $(g.iDoc.body).focus();
            });
        });
    </script>

</head>
<body id="#body">
    <div id="container">
        <div id="frameContainer">
            <h1>
                Frame</h1>
        </div>
        <div id="textContainer">
            <h1>
                Text</h1>
            <textarea rows="10" cols="80"></textarea>
        </div>
        <a href="#" id="testLink">Test</a>
        <div id="log">
        </div>
    </div>
</body>
</html>

В привязке keyup я могу успешно определить, находится ли я внутри другого элемента, и переместить курсор в начало текста, прежде чем вставлять его без проблем. Однако, поскольку перед элементом, помеченным как «notype», нет текста, он вставляется в тот же элемент.

Это вдвойне плохо, когда пользователь нажимает «enter», поскольку генерируется новый тег

, а тег «notype» дублируется, очевидно, не требуется.

Я хочу, чтобы поведение было следующим:

  • Если пользователь печатает, когда курсор находится в теге «notype», курсор перемещается вперед и текст идет туда
  • Если курсор находится на последней позиции внутри тега «notype», то текст появляется после тега
  • Если пользователь печатает где-либо еще, он вставляется как всегда.

Ссылка внизу пытается вручную поместить курсор вперед и вставить HTML. Очевидно, не удается. Я знаю, что это можно сделать, выполнив что-то вроде $ (g.iDoc.body) .prepend («раньше!»), Но, очевидно, это не сработает в реальном сценарии (с использованием keyup).

1 Ответ

0 голосов
/ 07 июня 2010

Я бы предложил использовать contenteditable вместо designMode. Он работает в IE начиная с версии 5.5, Firefox 3.0, Safari 1.2 и Opera 9:

<div id="contentContainer">
    <p contenteditable="true">An editable paragraph</p>
    <p>An uneditable paragraph</p>
    <p contenteditable="true">Another editable paragraph</p>
</div>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...