430

divユーザーがwithcontenteditable属性のコンテンツを編集したときに関数を実行したいと考えています。onchangeイベントに相当するものは何ですか?

jQuery を使用しているため、jQuery を使用するソリューションが優先されます。ありがとう!

4

21 に答える 21

375

keydownコンテンツ自体が変更される前にkeypressイベントが発生することに注意する必要がありますが、編集可能な要素によって発生する主要なイベントにリスナーをアタッチすることをお勧めします。これは、コンテンツを変更するすべての手段を網羅しているわけではありません。ユーザーは編集またはコンテキスト ブラウザ メニューから切り取り、コピー、貼り付けを使用することもできるため、cut copyおよびpasteイベントも処理する必要があります。また、ユーザーはテキストやその他のコンテンツをドロップできるため、より多くのイベントがあります (mouseupたとえば、 )。フォールバックとして要素のコンテンツをポーリングすることができます。

2014 年 10 月 29 日更新

HTML5inputイベントは、長期的には答えです。執筆時点ではcontenteditable、現在の Mozilla (Firefox 14 以降) および WebKit/Blink ブラウザーの要素でサポートされていますが、IE ではサポートされていません。

デモ:

document.getElementById("editor").addEventListener("input", function() {
    console.log("input event fired");
}, false);
<div contenteditable="true" id="editor">Please type something in here</div>

デモ: http://jsfiddle.net/ch6yn/2691/

于 2009-09-11T14:39:53.277 に答える
207

onこれは、すべての contenteditablesを使用するより効率的なバージョンです。ここでの上位の回答に基づいています。

$('body').on('focus', '[contenteditable]', function() {
    const $this = $(this);
    $this.data('before', $this.html());
}).on('blur keyup paste input', '[contenteditable]', function() {
    const $this = $(this);
    if ($this.data('before') !== $this.html()) {
        $this.data('before', $this.html());
        $this.trigger('change');
    }
});

プロジェクトはこちら: https://github.com/balupton/html5edit

于 2011-06-07T09:54:30.617 に答える
59

MutationObserverの使用を検討してください。これらのオブザーバーは、DOMの変更に反応するように設計されており、ミューテーションイベントのパフォーマンスを向上させるものとして設計されています。

長所:

  • 他の回答で示唆されているように重要なイベントを聞くことでは達成が難しい変更が発生したときに発生します。たとえば、これらはすべてうまく機能します。ドラッグアンドドロップ、イタリック体、コンテキストメニューからのコピー/カット/貼り付け。
  • パフォーマンスを念頭に置いて設計されています。
  • シンプルでわかりやすいコード。10個のイベントをリッスンするコードよりも、1個のイベントをリッスンするコードの方が理解とデバッグがはるかに簡単です。
  • Googleには、MutationObserversの使用を非常に簡単にする優れたミューテーションサマリーライブラリがあります。

短所:

  • Firefox(14.0以降)、Chrome(18以降)、またはIE(11以降)の最新バージョンが必要です。
  • 理解するための新しいAPI
  • ベストプラクティスやケーススタディに関する情報はまだ多くありません

もっと詳しく知る:

  • MutationObserersを使用してさまざまなイベントを処理することを比較するための小さなスニペットを作成しました。彼の答えが最も賛成票を持っているので、私はバルプトンのコードを使用しました。
  • MozillaにはAPIに関する優れたページがあります
  • MutationSummaryライブラリを見てください
于 2012-12-26T17:24:42.060 に答える
22

私はlawwantsinの答えをそのように修正しました、そしてこれは私のために働きます。キープレスの代わりにキーアップイベントを使用します。

$('#editor').on('focus', function() {
  before = $(this).html();
}).on('blur keyup paste', function() { 
  if (before != $(this).html()) { $(this).trigger('change'); }
});

$('#editor').on('change', function() {alert('changed')});
于 2010-09-13T14:06:58.083 に答える
3

このスレッドは、私が主題を調査している間、非常に役に立ちました。

ここで利用可能なコードの一部を jQuery プラグインに変更して、主に私のニーズを満たすために再利用可能な形式にしましたが、contenteditable タグを使用してジャンプスタートするためのよりシンプルなインターフェイスを評価する人もいます。

https://gist.github.com/3410122

アップデート:

人気が高まっているため、このプラグインはMakesites.orgに採用されています。

ここから開発が続きます。

https://github.com/makesites/jquery-contenteditable

于 2012-08-21T07:36:32.400 に答える
3

これが私のために働いたものです:

   var clicked = {} 
   $("[contenteditable='true']").each(function(){       
        var id = $(this).attr("id");
        $(this).bind('focus', function() {
            // store the original value of element first time it gets focus
            if(!(id in clicked)){
                clicked[id] = $(this).html()
            }
        });
   });

   // then once the user clicks on save
   $("#save").click(function(){
            for(var id in clicked){
                var original = clicked[id];
                var current = $("#"+id).html();
                // check if value changed
                if(original != current) save(id,current);
            }
   });
于 2011-01-28T21:09:04.207 に答える
2

タイマーと「保存」ボタンを回避するには、要素がフォーカスを失ったときに発生するぼかしイベントを使用できます。ただし、要素が実際に変更されたことを確認するには (フォーカスとデフォーカスだけでなく)、そのコンテンツを最後のバージョンと比較する必要があります。または、keydown イベントを使用して、この要素に「ダーティ」フラグを設定します。

于 2010-05-09T06:19:14.917 に答える
2

非 JQuery の回答...

function makeEditable(elem){
    elem.setAttribute('contenteditable', 'true');
    elem.addEventListener('blur', function (evt) {
        elem.removeAttribute('contenteditable');
        elem.removeEventListener('blur', evt.target);
    });
    elem.focus();
}

これを使用するには、id="myHeader" を使用してヘッダー要素を (たとえば) 呼び出します。

makeEditable(document.getElementById('myHeader'))

その要素は、フォーカスを失うまでユーザーが編集できるようになります。

于 2016-05-17T09:09:51.107 に答える
2

これが私が最終的に使用し、素晴らしく機能するソリューションです。コンテンツが編集可能な 1 行の div を使用しているだけなので、代わりに $(this).text() を使用します。ただし、この方法で .html() を使用することもできます。グローバル/非グローバル変数のスコープについて心配する必要はなく、before は実際にはエディターの div にアタッチされます。

$('body').delegate('#editor', 'focus', function(){
    $(this).data('before', $(this).html());
});
$('#client_tasks').delegate('.task_text', 'blur', function(){
    if($(this).data('before') != $(this).html()){
        /* do your stuff here - like ajax save */
        alert('I promise, I have changed!');
    }
});
于 2011-05-05T17:22:51.800 に答える
2

Angular 2+で

<div contentEditable (input)="type($event)">
   Value
</div>

@Component({
  ...
})
export class ContentEditableComponent {

 ...

 type(event) {
   console.log(event.data) // <-- The pressed key
   console.log(event.path[0].innerHTML) // <-- The content of the div 
 }
}


于 2019-11-17T17:15:02.213 に答える
1

入力イベントタイプを使用する必要があります

デモ

HTML

<div id="editor" contenteditable="true" >Some text here</div>

JS

const input = document.getElementById('editor');


input.addEventListener('input', updateValue);

function updateValue(e) {
  console.log(e.target);
}

もっと知る

于 2021-04-01T01:36:50.490 に答える
0

MutationEvents の下で DOMCharacterDataModifiedを使用すると、同じ結果になります。タイムアウトは、誤った値の送信を防ぐために設定されています (たとえば、Chrome ではスペース キーに問題がありました)。

var timeoutID;
$('[contenteditable]').bind('DOMCharacterDataModified', function() {
    clearTimeout(timeoutID);
    $that = $(this);
    timeoutID = setTimeout(function() {
        $that.trigger('change')
    }, 50)
});
$('[contentEditable]').bind('change', function() {
    console.log($(this).text());
})

JSFIDDLE の例

于 2012-02-28T14:33:57.770 に答える
0

contentEditable 属性を持つ要素が変更された場合、onchange イベントは発生しません。推奨される方法は、ボタンを追加してエディションを「保存」することです。

そのように問題を処理するこのプラグインを確認してください。

于 2009-09-07T23:56:10.700 に答える
0

これを行うために jQuery プラグインを作成しました。

(function ($) {
    $.fn.wysiwygEvt = function () {
        return this.each(function () {
            var $this = $(this);
            var htmlold = $this.html();
            $this.bind('blur keyup paste copy cut mouseup', function () {
                var htmlnew = $this.html();
                if (htmlold !== htmlnew) {
                    $this.trigger('change')
                }
            })
        })
    }
})(jQuery);

あなたは単に呼び出すことができます$('.wysiwyg').wysiwygEvt();

必要に応じてイベントを削除/追加することもできます

于 2013-06-04T16:22:53.730 に答える
-1

このアイデアをチェックしてください。 http://pastie.org/1096892

近いと思います。HTML 5 では、変更イベントを仕様に追加する必要があります。唯一の問題は、コンテンツが $(this).html() で実際に更新される前に、コールバック関数が if (before == $(this).html()) を評価することです。setTimeout がうまくいかず、悲しいです。どう考えているか教えてください。

于 2010-08-17T03:14:52.677 に答える