5

編集可能なdivをシミュレートするjQueryプラグインを作成しています。
これが私のコードです:

(function($){
    $.fn.editable = function(){
        return this.each(function(){
            var $this = $(this).hide();
            var div = $('<div>'+$this.val()+'</div>').show().insertAfter($this).data('input',$this);

            $this.data('div',div);

            div.dblclick(function(){
                $(this).hide();
                $(this).data('input').val($(this).text()).show();
            });
            $this.blur(function(){
                $(this).hide();
                $(this).data('div').html($(this).val()).show();                
            });

            $this.change(function(){
                $(this).data('div').html($(this).val());    
            });
        });
    };

})(jQuery);

これまでのところ、これはかなりうまく機能します。

さて、私がやりたいことは、どのようにすればよいのかわかりませんが、非表示の入力値が変更された場合にdivテキストを変更することです。
つまり、私が行う場合$('#editable').val('new text')、divは変更する必要があります。

入力の変更は、私が制御していない他のプラグイン内で発生するため、変更イベントを手動でトリガーすることはできません。

4

3 に答える 3

3

これを見てください。プラグインでこのようにval関数を拡張して、val関数を使用して値が変更されたときにchangeイベントがトリガーされるようにすることができます。

valメソッドを拡張して、valが呼び出されたときにchangeイベントがトリガーされるようにするにはどうすればよいですか?

于 2012-06-20T06:48:19.243 に答える
2

をダブルクリックし<div>て編集する<input>と、入力の値が次の行で上書きされます。

$(this).data('input').val($(this).text()).show();

イベントがトリガーされていない場合.change()(ご指摘のとおり)、外部プラグインによって行われた変更をdivの「古い」コンテンツで上書きしていることを意味します。.val()その問題を回避するために削除します。

$(this).data('input').show();

外部プラグインのトリガーに依存する代わりに.change()、ポーリングによって値を確認できます。イベントが利用可能な場合、これは推奨されませんが、ポーリング間隔を適切に設定すれば、大きな影響はありません。フォームにデータを入力する人間を扱っているので、250ミリ秒ごとより頻繁にポーリングする必要はないと思います。

$("#editable").changePolling();現在の値をチェックし、変更された場合にトリガーするラッパーについては、を参照してください.change()。コードに基づく例については、フォークされたjsfiddleを参照してください。

于 2012-06-17T16:23:24.987 に答える
-2

プラグイン/オーサリング-名前空間で説明されているように、jQueryプラグインサポートメソッドを作成することをお勧めします。

次に、次のようなものになります。

(function( $ ){

  var methods = {

    init : function( options ) { 
      return this.each(function() {
        var $this = $(this).hide();
        var div = $('<div>'+$this.val()+'</div>').show().insertAfter($this).data('input',$this);

        $this.data('div',div);

        div.dblclick(function(){
            $(this).hide();
            $(this).data('input').val($(this).text()).show();
        });
        $this.blur(function(){
            $(this).hide();
            $(this).data('div').html($(this).val()).show();                
        });
    },

    value : function( str ) {
      return this.each(function(){
        $(this).val(str);
        $(this).data('div').html($(this).val());
      });
    }
  };

  $.fn.editable = function( method ) {

    // Method calling logic
    if ( methods[method] ) {
      return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.editable' );
    }    

  };

})( jQuery );

次に、次のように使用します。

$('#editable').editable('new value that will sync the related div');
// instead of `$('#editable').value('...')`

プラグイン/オーサリング-jQueryに関するNamespacingの記事を読むことを強くお勧めします。


更新質問を理解するのを間違えたので、私は以下の提案された解決策を思いつきました。それはそれを行うための最良の方法ではありません。

私の個人的な意見ではアクセスできないため、プラグインの設計を確認することを強くお勧めします。

しかし、シナリオ全体を見ることができないので、次のコードでうまくいきます

(function() {

    // Store the original jQuery.val()
    var $$val = $.fn.val;

    // Add a hook.
    $.fn.val = function(s) {

      // Call your plugin change event.
      $(this).editable('change');

      // Delegate to the original jQuery.val function.
      return $$val.apply(this, Array.prototype.slice.call(arguments));
    };

  // Your plugin stuff...
})

HTH

于 2012-06-15T15:01:05.180 に答える