Javascript を学習するために、WYSIWYG コード エディターを実装しようとしています。content-editablediv
やを実装する代わりにtextarea
、私は Ajax.org の ACE の本から 1 枚 (というより、たくさんの 1 枚) を取り出しました。
すべての入力イベントを処理するために、0 に設定されdiv
たリスナーがあります。tabIndex
テキスト領域、カーソル、ガターなど、エディターのすべてのコンポーネントは、このリスナーの子です。マウス イベント ハンドラーを実装して以来、イベントにフォーカスが失われるという問題がありましたmousedown
。どうやら、リスナーでイベントが発生したblur
場合でも、イベントが発生しています。mousedown
特定のメソッド呼び出しをコメントアウトし、問題の原因を正確に調べようとした後、原因はrender
メソッドにあることに気付きました。さて、このメソッドは入力ごとに呼び出すので、特にmousedown
イベントで呼び出したときにフォーカスがずれてしまうのは非常に奇妙です。render
メソッドをコメントアウトすると、blur
イベントがあるときにイベントが発生しませんmousedown
。
さらに進んでいくと、テキスト コンテナの を置き換えた部分をコメント アウトするとinnerHTML
、問題が解消されることがわかりました。replaceInnerHTML
関数内のさまざまな場所で関数を使用しているため、これも非常に奇妙ですrender
が、特にテキストを更新した場合にのみ問題が発生するようですdiv
。
これは replaceInnerHTML メソッドです (ここで発見しました):
function replaceInnerHTML(el, html) {
var newEl = el.cloneNode(false);
newEl.innerHTML = html;
el.parentNode.replaceChild(newEl, el);
return newEl;
}
そして、これはテキストレイヤーの更新機能であり、省略してもこの問題は発生しません。
TextLayer.prototype.update = function(config) {
html = [];
var top = config.topRow;
var last = config.lastRow;
for(var i=top; i<=last; i++) {
var line = this._session.getLine(i);
if(line) {
html.push('<div class="line" style="height:'+this.$characterSize.height+'px;">');
this.renderLine(html, line);
html.push('</div>');
}
}
this._text = replaceInnerHTML(this._text, html.join(''));
this.setSize(config.totalWidth, config.scrollHeight);
};
innerHTML
特定のノードのを置き換えるだけでフォーカスがぼやけるのはなぜですか? また、mousedown
イベントの場合に呼び出されたときにのみフォーカスがぼやけるのはなぜですか?
それとも、これをデバッグしようとして完全に間違った方向に進んでいますか?この問題は別の原因によるものですか?
編集:
pimvdb のおかげで、ここに問題を再現するフィドルがあります。http://jsfiddle.net/wG4Yy/39/
blur
イベントのノードを再構築することにより、イベントが発生するようですmousedown
。問題の解決方法がわかりません。innerHTML の代わりにドキュメント フラグメントを使用しようとしsetTimeout
ました。
問題を解決するにはどうすればよいですか?