Adding jQuery callback function when expanding library

Short version: I am expanding the jQuery object object, which is designed to accept arguments 0-3 and pass them as second-fourth arguments to jQuery.animate. In addition, I want to isolate the callback and insert another function call into it.


I am expanding the jQuery library in the usual way, through jQuery.fn.newfunction = .... This is a custom animation function, in particular, that extends the object so that its external width, including fields, is equal to the internal width of the parent node.

jQuery.fn.expand_to_parent_container = function() {
  var args = Array.prototype.slice.call(arguments);

  return this.each(function(){
    var parent = $(this).parent();
    parent.inner_width = parent.innerWidth();

    var inner_outer_differential = $(this).outerWidth(true) - $(this).width();

    // store original width for reversion later
    $(this).data('original_width', $(this).width());

    args.unshift({ width: parent.inner_width - inner_outer_differential });

    $.fn.animate.apply($(this), args );
  });
}

. arguments, "" , properties .animate (API ). .expand_to_parent_container duration, easing, callback, jQuery (, , ). , jQuery.speed , / , /, jQuery, 'd .animate.

.

jQuery.fn.contract_to_original_size = function() {
  var args = Array.prototype.slice.call(arguments);

  var callback_with_width_reset = function(){
    callback();
    $(this).width('auto');
  }

  args.unshift({ width: $(this).data('original_width') });

  if($(this).data('original_width')) {
    $.fn.animate.apply($(this), args );
  } else {
    $(this).width('auto');
  }
}

var callback_with_width_reset ..., , width reset auto, - , . , arguments args.

+3
2

, :

  • expand_to_parent_container , {width: ...} args .
  • contract_to_original_size this.each() return this, .
  • , original-width , , ( / , !)
  • $.map() , , , .

:

jQuery.fn.expand_to_parent_container = function() {
  // instead of Array.prototype, we can grab slice from an empty array []
  var args = [].slice.call(arguments);

  return this.each(function(){
    var parent = $(this).parent();
    parent.inner_width = parent.innerWidth();

    var inner_outer_differential = $(this).outerWidth(true) - $(this).width();
    // store original width for reversion later
    if (!$(this).data('original_width'))
    {
      $(this).data('original_width', $(this).width());      
    }

    args.unshift({ width: parent.inner_width - inner_outer_differential });
    $.fn.animate.apply($(this), args );
    args.shift(); // push the width object back off in case we have multiples
  });
}

jQuery.fn.contract_to_original_size = function() {
  var args = Array.prototype.slice.call(arguments);
  var callback;

  var callback_with_width_reset = function(){
    if (callback) callback.apply(this,arguments);
    // do something else like:
    // $(this).width('auto');
    // you may want to $(this).data('original-width', null); here as well?
  }

  args = $.map(args, function(param) {
    // if the parameter is a function, replace it with our callback
    if ($.isFunction(param)) {
      // and save the original callback to be called.
      callback = param;
      return callback_with_width_reset;
    }
    // don't change the other params
    return param;
  });

  // we didn't find a callback already in the arguments
  if (!callback) { 
    args.push(callback_with_width_reset);
  }


  return this.each(function() {
    // rather than shift() the new value off after each loop
    // this is another technique you could use:

    // create another copy so we can mess with it and keep our template
    var localArgs = [].slice.call(args); 
    // also - storing $(this) is going to save a few function calls here:
    var $this = $(this);

    if($this.data('original_width')) {
      localArgs.unshift({ width: $this.data('original_width') });
      $.fn.animate.apply($this, localArgs );
    } else {
      $this.width('auto');
    }    
  });
}

jsFiddle

+1

, , , , - , :

var arguments_length = arguments.length;
for(var i = 0; i < arguments_length; i++) {
  if(typeof arguments[i] == 'function') {
    var temp = arguments[i];
    arguments[i] = function(){
      temp();
      $(this).width('auto');
    }
  }
}

huh Array.prototype.slice.call(arguments); , . arguments args, for(arg in args). . , , .

, , , , .

  • "" , , .
  • arguments[i] , . , .animate , , , .
0

Source: https://habr.com/ru/post/1752666/


All Articles