Javascript模块模式 - 我做错了什么?

时间:2012-11-12 08:14:28

标签: javascript design-patterns module

此处的工作版本位于:http://est.pagodabox.com/client/svedka

我有以下函数,我试图将其转换为模块模式,但是当我尝试使用我在底部返回的函数之一时,例如:

est_project.closeContent($html);

我得到一个错误,它不是一个功能。我在这里做错了吗?

谢谢!

var est_project = (function(){

    // Setup functions
    var flexDestroy,
        cloneCurrent,
        clonePosition,
        switchSlide,
        projectLayout,
        contentHeight,
        slidePos,
        slideClick,
        infoToggle,
        closeContent;

    // Destroy flexslider
    flexDestroy = function($slider,$cleanSlider, $projBg) {
        // Insert the clone of the un-initialized slide element, and remove the current flexslider
        // Effectively "destroys" the current slider

        var $curSlide = $slider.find('.flex-active-slide'),
            // Get the zero based index of current slide
            curSlideIndex = $curSlide.index() - 1,
            curBg = $curSlide.find('img').attr('src'),
            slideCount = $cleanSlider.data('count'),
            i = 0,
            $rearrange = $('');

        // When you switch projects, the current slide should stay put
        if(curSlideIndex !== 0 && slideCount > 1) { 
            // Cut from the current slide to the end, paste at the beginning
            for(i = 0 ; i < slideCount; i += 1) {
                if(curSlideIndex > i) {continue;}
                $rearrange = $rearrange.add( $cleanSlider.find('li:eq(' + i + ')') );
            }

            $rearrange.remove();
            $cleanSlider.find('li:first-child').before($rearrange)
            $cleanSlider.css({'background-image' : 'url(' + curBg + ')'});
        }

        $slider.after($cleanSlider).remove();
        clonePosition(slideheight);
    };

    return {
        // Clone current 
        cloneCurrent: function($el) {
            var $clean,
                slideCount = $el.find('li').length;

            $clean = $el.clone();
            $clean.removeClass('project-current').find('div').removeClass('img-loading');
            $clean.data('count',slideCount);
            return $clean;
        },

        // Set the clone position, for when we add it to the DOM or resize the window
        clonePosition: function(slideheight) {
            var n = $cleanSlider.index(),
                $myBg = $cleanSlider.find('div'),
                myPosition = n * slideheight;

            // Set the position of the inserted clone
            $cleanSlider
                .css({height: slideheight, top: myPosition, position : 'absolute'});

            $myBg
                .css({height: slideheight});
        },

        switchSlide: function($me, $slider) {
            $('.project-current').removeClass('project-current');
            $me.addClass('project-current');

            // Get rid of current flexslider
            flexDestroy($slider,$cleanSlider);

            // Clone the unitialized slider so we can add it back in later when it gets destroyed
            $cleanSlider = cloneCurrent($me);

            $me.addClass('flexslider').flexslider({
                animation: "slide",
                animationSpeed: 500,
                slideshow: false,
                manualControls: '.dot-nav li a'
            });

            // After the flexslider initializes, slide the content
            setTimeout(function(){
                slidePos($me, $slidewrap, slideheight, $win);
            },100);
        },

        // Custom "masonry" function, absolutely positions each project div according to the slide height
        projectLayout: function(slideheight,$proj,$projBg) {
            var n = 0;

            $proj.each(function(){
                var $me = $(this),
                    myPosition = n * slideheight;

                // Set all the heights
                $me
                    .css({top: myPosition, position : 'absolute'})
                    .add($projBg)
                    .css({height: slideheight});

                n++;
            });
        },

        // Set slide wrapper height to window height
        contentHeight: function($win, $slidewrap) {
            var winHeight = $win.height();
            $slidewrap.css({height: winHeight});
        },

        // Set slide wrapper position to slide to the clicked slide, and set content position
        slidePos: function($me, $slidewrap, slideheight, $win) {
            var $contentText = $('.project-content .text'),
                projNavHeight = Math.round( $win.height() * .1 ),
                curIndex = $me.index(),
                curTop = 0 - (curIndex * slideheight) + projNavHeight;

            $slidewrap.css({transform: 'translate(0,' + curTop.toString()  + 'px)'});
            $('.corner-btn').add($contentText).css({'padding-top' : projNavHeight});

            setTimeout(function(){
                $slidewrap.removeClass('tr-none movin').addClass('tr-all');
                $('.project').css({opacity: .4})
            }, 100);
        },

        // Click a project, slide to it
        slideClick: function($proj) {
            $('.project').live('click',function(){

                var $me = $(this),
                    myHref = $me.data('href'),
                    myTitle = $me.data('title'),
                    $slider = $('.flexslider'),
                    indexMy = $me.index(),
                    indexCur = $('.project-current').index(),
                    projDir;

                $me.css({opacity: 1});

                // Stop here if we click on the current project
                if($me.hasClass('project-current')) {
                    return false;
                }

                History.pushState(null,myTitle,myHref);     
            });
        },

        // Hide and show content
        infoToggle: function() {
            // Open content
            $('#corner-btn-info').on('click',function(){

                $html.addClass('show-content');

                if($('.project-content .text').height() <= $win.height()) {
                    $html.addClass('no-overflow');
                }

                $('.project-content-wrap').css({'z-index': 10});
            });

            // Close content
            $('#corner-btn-close').live('click',function(){
                closeContent($html);
            });
        },

        closeContent: function($html) {
            $html.removeClass('show-content');
            setTimeout(function(){
                $('.project-content-wrap').css({'z-index': -1});
                $html.removeClass('no-overflow');
                $('#classy').animate({scrollTop: 0})
            },300);
        }
    };
});

2 个答案:

答案 0 :(得分:4)

问题是你没有执行匿名函数,你的代码相当于:

var est_project = function() {};

如果希望它返回其中定义的函数,则需要执行该函数。

只需替换最后一行:

});

人:

}());

或者您可以保留代码并像这样调用closeContent函数:

est_project().closeContent();

但我猜这不是你想要的:-)每次调用est_project函数时都会实例化一个新对象。

答案 1 :(得分:0)

在文件的开头和结尾处,只需将对象附加到具有已执行函数的窗口,并将整个函数包装在自执行函数中。像这样

(function(global) {

   //your code goes here  
   global.est_project = est_project();

 })(this)
相关问题