Webアプリケーション用のリッチテキストエディターを実行しようとしていますが、テキスト内の一部の要素をユーザーが編集できないものとしてマークできるようにする必要があります。この理由は、ライブプレビューが必要な動的コンテンツ(作成日など)のプレースホルダーであるためです。
例として次のコードを取り上げます。軽量化のために、このコードにはツールバーなどはありませんが、textareaと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>
キーアップバインディングでは、別の要素内にいるかどうかを正常に検出し、問題なく挿入する前にカーソルをテキストの前に移動できます。ただし、「notype」とマークされた要素の前にテキストがないため、同じ要素内に挿入されます。
これは、ユーザーが「Enter」を押すと、新しいものとして2倍悪いです。
タグが生成され、「notype」タグが複製されます。明らかに必須ではありません。
次のような動作が必要です。
- カーソルが「notype」タグにあるときにユーザーが入力すると、カーソルが前に移動し、テキストがそこに移動します
- カーソルが「notype」タグ内の最後の位置にある場合、テキストはタグの後に表示されます
- ユーザーが他の場所に入力すると、通常どおり挿入されます。
下部のリンクは、手動でカーソルを前面に置き、htmlを挿入しようとします。明らかに失敗します。これは$(g.iDoc.body).prepend( "before!")のようなことで機能することはわかっていますが、実際のシナリオ(キーアップを使用)では明らかに機能しません。