1

この(jQuery)関数はとで呼び出されjQuery(document).readyますjQuery(document).resizeready条件では問題なく動作しますが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

のようなコールバック登録関数の1つを呼び出すと、$(someElement).click(...)実際にはそのイベントのハンドラーが追加されます。同じ関数で関数を2回呼び出すと、ハンドラーが2回呼び出されます。デモンストレーションを行い、この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 に答える