jQuery 解绑插件事件



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

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

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

(顺便说一下,#contact 表单是我正在滚动的容器,其中包含您猜对了的联系表单(

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 });
        }
    });

};

插件

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. 通过取消绑定删除所有事件处理程序(包括不是由该插件创建的事件处理程序(来解决此问题。

    不是一个真正的选择,因为滚动事件处理程序位于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 可能是最好的(如果它有效(。

最新更新