Don't understand how this calls the fadeIn method in jQuery

There is a line from the plugin that I use to try to understand:

$self.hide().attr("src", $self.data(settings.data_attribute))[settings.effect](settings.effect_speed);

self is the jquery object, which in this code is an img dom element, it hides it, and then sets the src attribute of this img object to the html5 data attribute. but now its accessing the property in the jquery object returned by .attr (which is "fadeIn" in this, but I donโ€™t understand if the jquery objects have built-in functions, where the effect property function is built into the jquery object? im confused how does this translate to calling .fadeIn (900). I can't find this document anywhere on the jquery website. If anyone can shed some light on this, thanks.

Sorry, here is the full code, this is from mika tuupola lazy loading jquery plugin:

(function($, window, document, undefined) {
var $window = $jq191(window);

$jq191.fn.lazyload = function(options) {
    var elements = this;
    var $container;
    var settings = {
        threshold       : 0,
        failure_limit   : 0,
        event           : "scroll",
        effect          : "show",
        container       : window,
        data_attribute  : "original",
        skip_invisible  : true,
        appear          : null,
        load            : null
    };

    function update() {
        var counter = 0;

        elements.each(function() {
            var $this = $jq191(this);
            if (settings.skip_invisible && !$this.is(":visible")) {
                return;
            }
            if ($jq191.abovethetop(this, settings) ||
                $jq191.leftofbegin(this, settings)) {
                    /* Nothing. */
            } else if (!$jq191.belowthefold(this, settings) &&
                !$jq191.rightoffold(this, settings)) {
                    $this.trigger("appear");
                    /* if we found an image we'll load, reset the counter */
                    counter = 0;
            } else {
                if (++counter > settings.failure_limit) {
                    return false;
                }
            }
        });

    }

    if(options) {
        /* Maintain BC for a couple of versions. */
        if (undefined !== options.failurelimit) {
            options.failure_limit = options.failurelimit; 
            delete options.failurelimit;
        }
        if (undefined !== options.effectspeed) {
            options.effect_speed = options.effectspeed; 
            delete options.effectspeed;
        }

        $jq191.extend(settings, options);
    }

    /* Cache container as jQuery as object. */
    $container = (settings.container === undefined ||
                  settings.container === window) ? $window : $jq191(settings.container);

    /* Fire one scroll event per scroll. Not one scroll event per image. */
    if (0 === settings.event.indexOf("scroll")) {
        $container.bind(settings.event, function(event) {
            return update();
        });
    }

    this.each(function() {
        var self = this;
        var $self = $jq191(self);

        self.loaded = false;

        /* When appear is triggered load original image. */
        $self.one("appear", function() {
            if (!this.loaded) {
                if (settings.appear) {
                    var elements_left = elements.length;
                    settings.appear.call(self, elements_left, settings);
                }
                $jq191("<img />")
                    .bind("load", function() {
                        $self
                            .hide()
                            .attr("src", $self.data(settings.data_attribute))
                            [settings.effect](settings.effect_speed);
                        self.loaded = true;

                        /* Remove image from array so it is not looped next time. */
                        var temp = $jq191.grep(elements, function(element) {
                            return !element.loaded;
                        });
                        elements = $jq191(temp);

                        if (settings.load) {
                            var elements_left = elements.length;
                            settings.load.call(self, elements_left, settings);
                        }
                    })
                    .attr("src", $self.data(settings.data_attribute));
            }
        });

        /* When wanted event is triggered load original image */
        /* by triggering appear.                              */
        if (0 !== settings.event.indexOf("scroll")) {
            $self.bind(settings.event, function(event) {
                if (!self.loaded) {
                    $self.trigger("appear");
                }
            });
        }
    });

    /* Check if something appears when window is resized. */
    $window.bind("resize", function(event) {
        update();
    });

    /* With IOS5 force loading images when navigating with back button. */
    /* Non optimal workaround. */
    if ((/iphone|ipod|ipad.*os 5/gi).test(navigator.appVersion)) {
        $window.bind("pageshow", function(event) {
            if (event.originalEvent.persisted) {
                elements.each(function() {
                    $jq191(this).trigger("appear");
                });
            }
        });
    }

    /* Force initial check if images should appear. */
    $jq191(window).load(function() {
        update();
    });

    return this;
};

/* Convenience methods in jQuery namespace.           */
/* Use as  $jq191.belowthefold(element, {threshold : 100, container : window}) */

$jq191.belowthefold = function(element, settings) {
    var fold;

    if (settings.container === undefined || settings.container === window) {
        fold = $window.height() + $window.scrollTop();
    } else {
        fold = $jq191(settings.container).offset().top + $jq191(settings.container).height();
    }

    return fold <= $jq191(element).offset().top - settings.threshold;
};

$jq191.rightoffold = function(element, settings) {
    var fold;

    if (settings.container === undefined || settings.container === window) {
        fold = $window.width() + $window.scrollLeft();
    } else {
        fold = $jq191(settings.container).offset().left + $jq191(settings.container).width();
    }

    return fold <= $jq191(element).offset().left - settings.threshold;
};

$jq191.abovethetop = function(element, settings) {
    var fold;

    if (settings.container === undefined || settings.container === window) {
        fold = $window.scrollTop();
    } else {
        fold = $jq191(settings.container).offset().top;
    }

    return fold >= $jq191(element).offset().top + settings.threshold  + $jq191(element).height();
};

$jq191.leftofbegin = function(element, settings) {
    var fold;

    if (settings.container === undefined || settings.container === window) {
        fold = $window.scrollLeft();
    } else {
        fold = $jq191(settings.container).offset().left;
    }

    return fold >= $jq191(element).offset().left + settings.threshold + $jq191(element).width();
};

$jq191.inviewport = function(element, settings) {
     return !$jq191.rightoffold(element, settings) && !$jq191.leftofbegin(element, settings) &&
            !$jq191.belowthefold(element, settings) && !$jq191.abovethetop(element, settings);
 };

/* Custom selectors for your convenience.   */
/* Use as $jq191("img:below-the-fold").something() or */
/* $jq191("img").filter(":below-the-fold").something() which is faster */

$jq191.extend($jq191.expr[':'], {
    "below-the-fold" : function(a) { return $jq191.belowthefold(a, {threshold : 0}); },
    "above-the-top"  : function(a) { return !$jq191.belowthefold(a, {threshold : 0}); },
    "right-of-screen": function(a) { return $jq191.rightoffold(a, {threshold : 0}); },
    "left-of-screen" : function(a) { return !$jq191.rightoffold(a, {threshold : 0}); },
    "in-viewport"    : function(a) { return $jq191.inviewport(a, {threshold : 0}); },
    /* Maintain BC for couple of versions. */
    "above-the-fold" : function(a) { return !$jq191.belowthefold(a, {threshold : 0}); },
    "right-of-fold"  : function(a) { return $jq191.rightoffold(a, {threshold : 0}); },
    "left-of-fold"   : function(a) { return !$jq191.rightoffold(a, {threshold : 0}); }
});

}) ($ jq191, window, document);

+5
2

, jQuery - . , , ., []. Ergo, :

$("#foo").fadeIn(2000);
$("#foo")['fadeIn'](2000);

, settings.effect settings.effect_speed, , , .

var settings = {
    effect: 'fadeIn',
    effect_speed: 2000
}
+6

.

jQuery .hide() .attr(name,value) this jQuery, . , , :

$self[settings.effect](settings.effect_speed);

. settings.effect - "fadeIn", ?

, :

$self["fadeIn"](settings.effect_speed);

JavaScript object["methodName"] , object.methodName. , , :

$self.fadeIn(settings.effect_speed);

fadeIn.

+1

All Articles