0

So I have a large JS file I've inherited from a previous developer and I am trying to get my head around some main parts. Here is the entire code:

$(function () {

    var homepage = (function () {

        var startNewsTicker = function () {

            var news = $('#newsSlider div'),
                idx = 0,
                isHovered = false,
                TIMEOUT = 6000;

            news.mouseenter(function () {
                isHovered = true;
            });

            news.mouseleave(function () {
                isHovered = false;
            });

            setInterval(function () {
                if (!isHovered) {
                    news.eq(idx).fadeOut(500);
                    idx = (idx + 1 <= news.length - 1) ? idx + 1 : 0;
                    news.eq(idx).fadeIn(500);
                }
            }, TIMEOUT);
            news.eq(idx).fadeIn(500);
        };

        var slides = {
                wrapper: $('#slideWrapper'),
                slide: $('#slideWrapper li'),
                imageWrapper: {},
                image: {},
                paginatorWrapper: {},
                paginator: {},
                prev: -1,
                next: -1,
                arrows: {
                    left: $('#arwLeft'),
                    right: $('#arwRight')
                }
            },
            centerSlideWrapper = function () {
                slides.wrapper.css({
                    marginTop: ((window.innerHeight - slides.wrapper.height()) / 2) + 'px',
                    opacity: 1
                });
            },
            buildSlider = function () {
                slides.prev = slides.length - 1;
                slides.next = 1;
                slides.wrapper.before('<div id="homepageBackgroundImages" />').after('<div id="homepagePagination" />');
                slides.imageWrapper = $('#homepageBackgroundImages');
                slides.paginatorWrapper = $('#homepagePagination');
                slides.paginatorWrapper.css('width', 36 * slides.slide.length + 'px')
                slides.slide.each(function () {
                    var $t = $(this);
                    slides.imageWrapper.append('<div><img src="' + $t.attr('data-img') + '" /></div>');
                    slides.paginatorWrapper.append('<a href="#"><span>' + $t.attr('data-tagline') + '</span></a>');
                });
                slides.image = slides.imageWrapper.find('div');
                slides.image.find('img').fullscreenBackground();
                slides.paginator = slides.paginatorWrapper.find('a');
                slides.imageWrapper.prepend('<div class="mask"></div>');

                //create offset margin left to auto center spans
                slides.paginator.find('span').each(function () {
                    var $t = $(this);
                    $t.css({
                        top: "-9999px",
                        display: "block"
                    });
                    $t.css({
                        marginLeft: -(($t.width() + parseFloat($t.css('paddingLeft')) + parseFloat($t.css('paddingRight'))) / 2) + 2 + 'px',
                        display: "none",
                        top: "-56px"
                    })
                });

            },
            startSlider = function () {
                var slideIdx = -1,
                    currentSlide,
                    isHovered = false,
                    interval = {
                        delay: 8000,
                        timer: {},
                        start: function () {
                            interval.timer = setInterval(function () {
                                if(!isHovered)
                                    switchSlide(slideIdx + 1);
                            }, interval.delay);
                        },
                        stop: function () {
                            clearInterval(interval.timer);
                        }
                    },
                    switchSlide = function (idx) {
                        if (slideIdx > -1) {
                            slides.image.eq(slideIdx).stop(true, true).fadeOut(500);
                            slides.slide.eq(slideIdx).stop(true, true).fadeOut(500);

                        }
                        idx = (idx <= slides.slide.length - 1) ? idx : 0;
                        slides.image.eq(idx).stop(true, true).fadeIn(500);
                        slides.slide.eq(idx).stop(true, true).fadeIn(500);
                        slideIdx = idx;
                        slides.paginator.removeClass('current').eq(idx).addClass('current');
                        slides.prev = (slideIdx - 1 >= 0) ? slideIdx - 1 : slides.slide.length-1;
                        slides.next = (slideIdx + 1 <= slides.slide.length - 1) ? slideIdx + 1 : 0;
                        slides.arrows.left.find('span').text(slides.slide.eq(slides.prev).attr('data-tagline'));
                        slides.arrows.right.find('span').text(slides.slide.eq(slides.next).attr('data-tagline'));
                    }

                slides.paginator.click(function (e) {
                    e.preventDefault();
                    interval.stop();
                    switchSlide($(this).index());
                    interval.start();
                });

                slides.arrows.left.click(function (e) {
                    e.preventDefault();
                    interval.stop();
                    switchSlide(slides.prev);
                    interval.start();
                });

                slides.arrows.right.click(function (e) {
                    e.preventDefault();
                    interval.stop();
                    switchSlide(slides.next);
                    interval.start();
                });

                slides.arrows.left.mouseenter(function (e) {
                    e.preventDefault();
                    isHovered = true;
                });
                slides.arrows.right.mouseenter(function (e) {
                    e.preventDefault();
                    isHovered = true;
                });

                slides.arrows.left.mouseleave(function (e) {
                    e.preventDefault();
                    isHovered = false;
                });

                slides.arrows.right.mouseleave(function (e) {
                    e.preventDefault();
                    isHovered = false;
                });

                slides.slide.find('strong').mouseenter(function () {
                    isHovered = true;
                });

                slides.slide.find('strong').mouseleave(function () {
                    isHovered = false;
                });

                switchSlide(0);
                interval.start();
            }

        return {
            init: function () {
                centerSlideWrapper();
                $(window).resize(function () {
                    centerSlideWrapper();
                });
                buildSlider();
                startSlider();
                startNewsTicker();
            }
        }

    })();
    homepage.init();
});

In this instance, what I am trying to figure out is what is going on with this chunk:

var homepage = (function () {

...

    return {
        init: function () {
            centerSlideWrapper();
            $(window).resize(function () {
                centerSlideWrapper();
            });
            buildSlider();
            startSlider();
            startNewsTicker();
        }
    }
})();
homepage.init();

What I am confused on is:

1) Why would creating this homepage function in this fashion would be benefitial.

2) Also, waht I do not understand is how the function is returning an object that contains another JS function init and then later being run by using homepage.init();. Does this homepage.init(); call invoke both the homepage and init functions to run?

Thanks for all your help!

2 Answers 2

2

1) Why would creating this homepage function in this fashion would be benefitial.

It's commonly called the "Revealing Module Pattern" and is usually used to create private static members that can only be accessed using "public" properties/methods (encapsulation).

For more information on this pattern see: Why embed the JavaScript class in an anonymous function() call?

Or: Google/Bing/Yahoo "Revealing Module Pattern"

2) Also, waht I do not understand is how the function is returning an object that contains another JS function init and then later being run by using homepage.init();. Does this homepage.init(); call invoke both the homepage and init functions to run?

Yes, it calls the init method of the homepage object reference.

Sign up to request clarification or add additional context in comments.

1 Comment

Very informative! Thanks for the information! I will definitely be looking into that Revealing Module Pattern.
2

In javascript, classes are created through functions. So this code is creating an anonymous function and calling it, immediately returning its value to homepage. What is returned to homepage is a function/object with one property -- in this case the init function.

The object homepage is then used to access the init function.

Why do it this way? It hides all the stuff you ...'d in your example from the global scope. But they are still accessible to the init function when homepage.init() is called. Why? Because they're in the same scope (or one higher scope in this case) as the init function. So you can call homepage.int(); but you can't call homepage.startSlider() for example.

1 Comment

Thanks so much for the info! The narrative way that you've described this information is very helpful!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.