处理输入文本更改事件

时间:2012-06-15 14:43:27

标签: jquery jquery-ui jquery-plugins

我正在编写一个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很好......

现在,我想做的,并且不知道怎样,如果隐藏的输入值发生变化,则div文本会发生变化。
意思是,如果我做$('#editable').val('new text') div应该改变..

我无法手动触发更改事件,因为输入更改将发生在我无法控制的其他插件中。

3 个答案:

答案 0 :(得分:3)

看看这个,在你的插件中你可以像这样扩展val函数,这样当使用val函数改变值时会触发change事件。

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

答案 1 :(得分: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

答案 2 :(得分:-2)

我建议您按照Plugins/Authoring - Namespacing中所述制作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('...')`

我强烈建议您阅读Plugins/Authoring - Namespacing关于jQuery的文章。


更新由于我在理解问题时犯了一个错误,因此我提出了以下建议的解决方案。这不是最好的方法。

我强烈建议您检查一下您的插件设计,因为我个人认为无法访问它。

但是,由于我看不到整个场景,下面的一段代码就可以解决这个问题

(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