jQuery解绑插件事件

时间:2012-04-29 12:49:29

标签: jquery binding

我之前从未需要“绑定”或“解除绑定”任何事情因此我感到困惑,因为我找不到与我想做的事情直接相关的例子。

当你到达页面here的某一点时,有一个滚动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 });
        }
    });

};

1 个答案:

答案 0 :(得分: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);
    
    })();
    

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

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