2012-06-15 136 views
5

我正在寫一個jQuery插件來模擬可編輯的div。
這裏是我的代碼:處理輸入文本更改事件

(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); 

到目前爲止,this works不錯..

現在,我想做的事,而且不知道如何,是使格文本變化如果隱藏輸入值改變。
手段,如果我做$('#editable').val('new text')股利應改變..

我不能觸發變化事件手動,因爲輸入的變化將是我無法控制其它插件內發生..

+0

你能你如何指望擴大'$( '#可編輯')。VAL()'工作?爲什麼'val()'而不是'html()'?哪些元素可以編輯? – 2012-06-15 14:59:16

+0

@palintropos更新了我的jsFiddle – skafandri

+1

另外,你看過'contenteEditable'嗎?我相信它是非常全面的支持 – 2012-06-15 15:14:34

回答

3

看看這個,在你的插件中,你可以像這樣擴展val函數,以便在使用val函數更改值時觸發change事件。

How to extend the val method so that the change event is triggered when val is called?

+0

這會在'.val()'之後觸發雙'.change()'事件,以便正確調用'.change()'的插件。該技術可以與輸入列表組合,因此(在本例中)只有$(「#editable」).val(「new value」)會觸發一個變化。 (「正確」取決於插件的用途,我猜。) –

+0

可以請你解釋一下還是給我一些樣品? –

+0

下面是一個示例http://jsfiddle.net/joelpurra/Emyk2/ –

-2

我建議你讓你的jQuery插件的支持方式上Plugins/Authoring - Namespacing描述:

然後,你將有這樣的事情:

(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('...')` 

我強烈建議你閱讀Plugins/Authoring - Namespacing的jQuery的文章。


UPDATE因爲我犯了一個錯誤理解的問題,我想出了下面提出的解決方案。這不是最好的辦法。

我強烈建議您檢查一下您的插件設計,因爲這是我個人認爲無法訪問的。

但是,因爲我不能看到整個場景中,下面的代碼段會做的伎倆

(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

+0

我可以添加'.trigger('change')'是不是更容易?但輸入將被其他插件使用,因此,它將只是'.val('new text')' – skafandri

+0

問題不是:如何編寫jQuery插件.. – skafandri

+0

爲了消極點,我將嘗試用你描述的行爲來使用JSFiddle來提出我的建議答案。我已經寫了我的jQuery可編輯插件,我已經遇到了這個_common_情況,我很確定這樣做會做你想做的事情。 –

2

當你雙擊<div>編輯<input>,要覆蓋該行的輸入值爲:

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

如果.change()事件沒有被觸發(如您所指示的),這意味着您正在覆蓋外部插件與div的「舊」內容所做的更改。刪除.val()以避免該問題。

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

作爲替代依靠外部插件觸發.change(),可以通過輪詢檢查值。雖然這不建議如果事件可用,如果您合理設置輪詢間隔,它不會產生巨大的影響。由於您正在處理人類在表單中輸入數據,因此我猜測您無需每隔250毫秒進行一次輪詢。

請參閱$("#editable").changePolling();檢查當前值的包裝,如果它已更改則觸發.change()。有關基於您的代碼的示例,請參閱the forked jsfiddle

+0

jsFiddle不工作..單擊按鈕什麼也不做。 – skafandri

+0

@sonia:你在IE中測試嗎? IE瀏覽器(可能還有其他瀏覽器)對包含沒有使用正確內容類型的腳本進行挑剔。 I'v –

+0

@sonia:正確的內容類型是['application/javascript'或'text/javascript'](http://en.wikipedia.org/wiki/JavaScript)。我[鏈接從我的要點原始腳本](https://gist.github.com/raw/2944926/d87c96c1529d7f5e8c8c4015c7b9100a5f6a8db8/changepolling.joelpurra.js)不提供正確的內容類型。出於測試目的,您可以將整個'.changePolling()'源代碼複製粘貼到jsFiddle中,然後運行它。 –