0

我以前从来不需要“绑定”或“取消绑定”任何东西,所以我很困惑,因为我找不到与我想做的事情直接相关的例子。

当您到达此处页面的某个点时,有一个插件可以滚动 div - 您都见过这种事情,对吧?

我只希望插件在窗口达到一定宽度时触发,然后如果窗口再次低于该宽度,则“取消触发”/取消绑定,例如......

(顺便说一下,#contact-form 是我正在滚动的容器,你猜对了,它包含一个联系表单)

function contactForm() {
    windowWidth = $(window).width();
    if (windowWidth >= 1024) {
        jQuery('#contact-form').containedStickyScroll();
    } else {
        jQuery('#contact-form').unbind(); // I don't want the plugin to fire
    }
};    


// Standard stuff...

$(document).ready(function() {
    contactForm();
});

$(window).resize(function() {   
    contactForm();
});

这个包含的粘性滚动功能如下所示:

  $.fn.containedStickyScroll = function( options ) {

    var defaults = {  
        oSelector : this.selector,
        unstick : true,
        easing: 'linear',
        duration: 500,
        queue: false,
        closeChar: '^',
        closeTop: 0,
        closeRight: 0  
    }  

    var options =  $.extend(defaults, options);

    if(options.unstick == true){  
        this.css('position','relative');
        this.append('<a class="scrollFixIt">' + options.closeChar + '</a>');
        jQuery(options.oSelector + ' .scrollFixIt').css('position','absolute');
        jQuery(options.oSelector + ' .scrollFixIt').css('top',options.closeTop + 'px');
        jQuery(options.oSelector + ' .scrollFixIt').css('right',options.closeTop + 'px');
        jQuery(options.oSelector + ' .scrollFixIt').css('cursor','pointer');
        jQuery(options.oSelector + ' .scrollFixIt').click(function() {
            getObject = options.oSelector;
            jQuery(getObject).animate({ top: "0px" },
                { queue: options.queue, easing: options.easing, duration: options.duration });
            jQuery(window).unbind();
            jQuery('.scrollFixIt').remove();
        });
    } 
    jQuery(window).scroll(function() {
        getObject = options.oSelector;
        if(jQuery(window).scrollTop() > (jQuery(getObject).parent().offset().top) &&
           (jQuery(getObject).parent().height() + jQuery(getObject).parent().position().top - 30) > (jQuery(window).scrollTop() + jQuery(getObject).height())){
            jQuery(getObject).animate({ top: (jQuery(window).scrollTop() - jQuery(getObject).parent().offset().top) + "px" }, 
            { queue: options.queue, easing: options.easing, duration: options.duration });
        }
        else if(jQuery(window).scrollTop() < (jQuery(getObject).parent().offset().top)){
            jQuery(getObject).animate({ top: "0px" },
            { queue: options.queue, easing: options.easing, duration: options.duration });
        }
    });

};

4

1 回答 1

1

该插件containedStickyScroll写得不是很好,因为它没有删除处理程序。

这给您留下了 3 个选择:

  1. 分叉插件。

    $.fn.containedStickyScroll = function( options ) {
    
       return this.each(function() {
    
       var self = this;
    
       function remove() {
            getObject = options.oSelector;
            jQuery(getObject).animate({ top: "0px" }, { queue: options.queue, easing: options.easing, duration: options.duration });
            jQuery(window).unbind("scroll", $self.data("containedStickyScroll").scrollHandler);
            jQuery('.scrollFixIt').remove();
    
            $(self).data("containedStickyScroll", false);
       }
    
        if (options == "remove") {
            remove();
            return;
        }
    
        // Make sure that this is only done once.
        if (this.data("containedStickyScroll"))
            return;
    
        var defaults = {  
            oSelector : this.selector,
            unstick : true,
            easing: 'linear',
            duration: 500,
            queue: false,
            closeChar: '^',
            closeTop: 0,
            closeRight: 0  
        }  
    
        var options =  $.extend(defaults, options);
    
        if(options.unstick == true){  
            $(this).css('position','relative');
            $(this).append('<a class="scrollFixIt">' + options.closeChar + '</a>');
            jQuery(options.oSelector + ' .scrollFixIt').css('position','absolute');
            jQuery(options.oSelector + ' .scrollFixIt').css('top',options.closeTop + 'px');
            jQuery(options.oSelector + ' .scrollFixIt').css('right',options.closeTop + 'px');
            jQuery(options.oSelector + ' .scrollFixIt').css('cursor','pointer');
            jQuery(options.oSelector + ' .scrollFixIt').click(remove);
        } 
    
        options.scrollHandler = function () {
            getObject = options.oSelector;
            if(jQuery(window).scrollTop() > (jQuery(getObject).parent().offset().top) &&
               (jQuery(getObject).parent().height() + jQuery(getObject).parent().position().top - 30) > (jQuery(window).scrollTop() + jQuery(getObject).height())){
                jQuery(getObject).animate({ top: (jQuery(window).scrollTop() - jQuery(getObject).parent().offset().top) + "px" }, 
                { queue: options.queue, easing: options.easing, duration: options.duration });
            }
            else if(jQuery(window).scrollTop() < (jQuery(getObject).parent().offset().top)){
                jQuery(getObject).animate({ top: "0px" },
                { queue: options.queue, easing: options.easing, duration: options.duration });
            }
        };
    
        jQuery(window).scroll(options.scrollHandler);
    
        $(this).data("containedStickyScroll", options);
    };};
    

    现在你可以这样做:

    (function($) {
    
        function contactForm() {
            windowWidth = $(window).width();
            if (windowWidth >= 1024)
                $('#contact-form').containedStickyScroll();
            else
                $('#contact-form').containedStickyScroll("remove");
        };    
    
        // Standard stuff...
    
        $(document).ready(contactForm);
    
        $(window).resize(contactForm);
    
    })(jQuery);
    

    我还删除了从窗口对象中解除绑定所有事件处理程序的可怕做法,这比选项 2 还要糟糕。

  2. 通过使用 unbind 删除所有事件处理程序(包括那些不是由该插件创建的事件处理程序)来解决此问题。

    不是一个真正的选择,因为滚动事件处理程序位于window对象上,其他插件等很可能使用相同的事件处理程序。

    $(window).unbind("scroll");
    
  3. 重置 DOM 上的整个元素。

    (function() {
    
        var hasContactForm = false,
            $contactForm = $("#contact-form").clone();
    
        function contactForm() {
            windowWidth = $(window).width();
            if (!hasContactForm && windowWidth >= 1024) {
                hasContactForm = true;
                jQuery('#contact-form').containedStickyScroll();
            } else if (hasContactForm && windowWidth < 1024)
                hasContactForm = false;
                $('#contact-form').replaceWith($contactForm);
            }
        };    
    
        // Standard stuff...
    
        $(document).ready(contactForm);
    
        $(window).resize(contactForm);
    
    })();
    

    这也可能不是一个可行的解决方案,因为它还会重置任何用户输入。但是,您可以添加额外的逻辑来将用户输入携带到恢复的联系表单中。

考虑到每个选项的许多缺点,我强烈建议要么找到更好的插件,要么自己编写。否则选项 1 可能是最好的(如果可行的话)。

于 2012-04-29T13:57:05.673 回答