1

这个 (jQuery) 函数在jQuery(document).ready和上调用jQuery(document).resize。它在条件下运行良好,ready但在resize事件上有点麻烦。它们要么继承功能,要么在每次调整大小时似乎都会触发 slideToggle 的情况。

(function(jQuery){
    jQuery.fn.responsive = function() {
        // Vars
        var menuButton = jQuery('nav #menu-button');
        var menuItems = jQuery('nav ul');
        var menuLinks = jQuery('nav ul li a.scroll');
        var viewportW = jQuery(window).width(); 
        var viewportH = jQuery(window).height();  
        // Menu links
        menuLinks.click(function(e){
            if (viewportW > 800) {
                e.preventDefault();
                e.stopPropagation();
                var pos = jQuery(this.hash).offset().top;
                jQuery('html,body').animate({scrollTop: pos}, 1000);
            } else if (viewportW < 799) {
                e.stopPropagation();
                menuItems.slideUp('fast'); // Hide menu on click
            }
        });
        // Menu button
        menuButton.click(function(e){
            menuItems.slideToggle('fast');
            //e.stopPropagation();
            //e.preventDefault();
        });
    }
})(jQuery);

我究竟做错了什么?我试图终止事件传播,但无济于事。

编辑:

这在以下运行:

// Doc ready
jQuery(document).ready(function() {
    // Run functions
    jQuery().responsive();
});


// On resize
jQuery(window).resize(function(){  
    jQuery().responsive();
});
4

2 回答 2

1

抱歉,我之前误解了你的问题。

如我所见,每次调整大小都不需要评估$.responsive()

只是

$.fn.responsive = function(){
    //Vars
    var menuButton = $('nav #menu-button');
    var menuItems = $('nav ul');
    var menuLinks = $('nav ul li a.scroll');
    //Menu links
    menuLinks.click(function(event){
        //**move width&height inside
        var viewportW = $(window).width(); 
        var viewportH = $(window).height();
        if(viewportW > 800){
            event.preventDefault();
            event.stopPropagation();
            var pos = $(this.hash).offset().top;
            $('html,body').animate({scrollTop: pos}, 1000);
        }else if(viewportW < 799){
            event.stopPropagation();
            menuItems.slideUp('fast');// Hide menu on click
        }
    });
    //Menu button
    menuButton.click(function(event){
        menuItems.slideToggle('fast');
        //event.stopPropagation();
        //event.preventDefault();
    });
}

然后

$(document).ready(function(){
    //just once
    $.fn.responsive();
});
于 2012-04-16T03:16:33.770 回答
0

当您调用其中一个回调注册函数 like$(someElement).click(...)时,您实际上是在为该事件添加一个处理程序。如果您使用相同的方法调用该函数两次,则处理程序将被调用两次。做演示,试试这个 html 页面(与 jquery.js 在同一页面中):

<html>
<head>
<script src="jquery.js"></script>
<script>
    function addhook() {
        $("div").click(function(e) {
            console.info("click!");
            $("body").append($("<div>click!</div>"));
            return false;
        });
    }

    $(function() {
        addhook();
        $(window).resize(addhook);
    });
</script>
</head>
<body>
<div><a href="#">Click me</a></div>
</body>
</html>

在第一次加载页面时,它的行为符合预期,但在调整窗口大小后,单击“单击我”会获得不止一次“单击!”。

重新注册处理程序的唯一原因是各个元素是否已被销毁并重新创建。

如果发生这种情况,并且在必要时尝试可靠地重新注册处理程序并不方便,请考虑使用委托事件.live()

还要注意.off() 函数,它可以删除一组元素上的所有处理程序。

最后,你可能应该改变

jQuery.fn.responsive = function() {

jQuery.responsive = function() {

添加到jQuery.fn添加可以从 jQuery 对象调用的函数,即允许,比如说,

$("div").responsive();

出于某种原因,这些函数也被添加到jQuery对象本身,所以它仍然有效,但后者使函数的目的更加清晰,并保持 jQuery 类的清洁。

于 2012-04-16T05:13:43.013 回答