web-dev-qa-db-ja.com

contenteditableのプレースホルダー-フォーカスイベントの問題

バグが発生する実際の例を説明したり証明したりする運なしに、私はこれを以前に尋ねようとしました。だからここに別の試みがあります:

コンテンツ編集可能なDIVにプレースホルダー効果を複製しようとしています。コアコンセプトはシンプルです:

<div contenteditable><em>Edit me</em></div>

<script>
$('div').focus(function() {
    $(this).empty();
});
</script>

これは何らかの動作をしますが、プレースホルダーにHTMLが含まれている場合、または他の処理が行われている場合、編集可能なDIVのテキストキャレットは削除され、ユーザーは編集可能なDIVを再クリックして入力を開始する必要があります(たとえまだ焦点が合っている):

例: http://jsfiddle.net/hHLXr/6/

イベントループを作成するため、ハンドラーでフォーカストリガーを使用できません。そのため、編集可能なDIVでキャレットカーソルを再設定する方法、または他の方法で再フォーカスする方法が必要です。

60
David Hellsing

選択を手動で更新する必要がある場合があります。 IEでは、フォーカスイベントが遅すぎるため、代わりにactivateイベントを使用することをお勧めします。 IE <= 8(CSSのみの代替ではない)など、すべての主要なブラウザーでジョブを実行するコードを次に示します。

ライブデモ: http://jsfiddle.net/hHLXr/12/

コード:

$('div').on('activate', function() {
    $(this).empty();
    var range, sel;
    if ( (sel = document.selection) && document.body.createTextRange) {
        range = document.body.createTextRange();
        range.moveToElementText(this);
        range.select();
    }
});

$('div').focus(function() {
    if (this.hasChildNodes() && document.createRange && window.getSelection) {
        $(this).empty();
        var range = document.createRange();
        range.selectNodeContents(this);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    }
});
24
Tim Down

以下は、CSSのみのソリューションであり、他の回答の一部を補強しています。

<div contentEditable=true data-ph="My Placeholder String"></div>
<style>
    [contentEditable=true]:empty:not(:focus)::before{
        content:attr(data-ph)
    }
</style>

編集:ここにcodepenのスニペットがあります-> http://codepen.io/mrmoje/pen/lkLez

EDIT2:すべての行で<br>またはselect-all-cutを実行した後にdivにselect-all-delete要素が残っているため、この方法は複数行アプリケーションでは100%動作しません。クレジット:-@vsync
バックスペースは正常に動作するようです(少なくともwebkit/blinkで)

153
moje

このためのプラグインを公開しました

CSS3とJavaScriptの組み合わせを使用して、divのコンテンツに追加せずにプレースホルダーを表示します。

HTML:

<div contenteditable='true' data-placeholder='Enter some text'></div>

CSS:

div[data-placeholder]:not(:focus):not([data-div-placeholder-content]):before {
    content: attr(data-placeholder);
    float: left;
    margin-left: 5px;
    color: gray;
}

JS:

(function ($) {
    $('div[data-placeholder]').on('keydown keypress input', function() {
        if (this.textContent) {
            this.dataset.divPlaceholderContent = 'true';
        }
        else {
            delete(this.dataset.divPlaceholderContent);
        }
    });
})(jQuery);

以上です。

29
Craig Stuntz

css擬似クラスを使用してください。

span.spanclass:empty:before {content:"placeholder";}
22
amwinter

これを行う最良の方法は、通常のようにplaceholder属性を使用し、CSSを数行追加することであることがわかりました。

[〜#〜] html [〜#〜]

<div contenteditable placeholder="I am a placeholder"></div>

[〜#〜] css [〜#〜]

[contenteditable][placeholder]:empty:before {
    content: attr(placeholder);
    color: #bababa;
}

注:CSS :emptyセレクターは、開始タグと終了タグの間に文字通り何も存在しない場合にのみ機能します。これには、新しい行、タブ、空のスペースなどが含まれます。

Codepen

8
ramo

必要なのはこの小さなソリューションです

[contenteditable=true]:empty:before{
  content: attr(placeholder);
  display: block; /* For Firefox */
}

デモ:http://codepen.io/flesler/pen/AEIFc

7
wp student

私の方法は次のとおりです。

jQueryとCSS3の組み合わせを使用します。 html5プレースホルダー属性とまったく同じように機能します!

  • 最初の文字を入力するとすぐに非表示になります
  • 入力内容を削除すると再び表示されます

HTML:

<div class="placeholder" contenteditable="true"></div>

CSS3:

.placeholder:after {
    content: "Your placeholder"; /* this is where you assign the place holder */
    position: absolute;
    top: 10px;
    color: #a9a9a9;
}

jQuery:

$('.placeholder').on('input', function(){
    if ($(this).text().length > 0) {
        $(this).removeClass('placeholder');
    } else {
        $(this).addClass('placeholder');
    }
});

デモ: http://jsfiddle.net/Tomer123/D78X7/

4
surfs up

これが私が使用した修正です。

<div contenteditable><em>Edit me</em></div>
<script>
$('div').focus(function() {
    var target = $(this);
    window.setTimeout(function() { target.empty(); }, 10);
});
</script>

このためにjQueryプラグインを開発しました。ご覧ください https://github.com/phitha/editableDiv

1
Phitha

これはあなたの問題の正確な解決策ではありません..

summernoteオプションセット

airMode:true

プレースホルダーはこのように機能します。

0
Ganesh S
var curText = 'Edit me';
$('div').focusin(function() {
    if ($(this).text().toLowerCase() == curText.toLowerCase() || !$(this).text().length) {
        $(this).empty();
    }
}).focusout(function() {
    if ($(this).text().toLowerCase() == curText.toLowerCase() || !$(this).text().length) {
        $(this).html('<em>' + curText + '</em>');
    }
});
0
thecodeparadox