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

到目前为止,这工作得很好..

现在,我想要做的,但不知道如何,如果隐藏的输入值发生变化,则使 div 文本发生变化。
意味着,如果我这样做$('#editable').val('new text')div 应该改变..

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

4

3 回答 3

3

看看这个,在您的插件中,您可以像这样扩展 val 函数,以便在使用 val 函数更改值时触发更改事件。

如何扩展 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

我建议您按照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...
})

高温高压

于 2012-06-15T15:01:05.180 回答