画面幅によって処理分けしているヘッダーメニューを画面リサイズ後も動作させたい


お世話になります。

jQueryで、画面幅によって処理分けしているヘッダーメニューがあります。  
1025px以上でドロップダウン型、かつスクロール時に縮小版ヘッダーに切り替えます。  
1024px以下でドロワー型、縮小版ヘッダーを表示します。

コードは以下の通りです。

[code]

    if ($(window).width() > 1024) {
        $('#main_header_nav li, #lower_header_nav li').hover(function() {
            $('>ul', this).stop(true, true).slideDown('fast');
        }, function() {
            $('>ul', this).stop(true, true).slideUp('fast');
        });
    }
    
    $('#sp_menu_open, #sp_menu_close').click(function() {
        $('#lower_header_nav').animate({ width: 'toggle' });
    });
    
    if ($(window).width() > 1024) {
        changeHeader();
        $(window).scroll(changeHeader);
    }
    
    function changeHeader() {
        var headerChangeHeight = 200; // 切り替わるタイミング
        if ($(window).scrollTop() >= headerChangeHeight) {
            $('#lower_header').slideDown('fast');
        } else {
            $('#lower_header').slideUp('fast');
        }
    }
    
[/code]

上のコードだと、画面をリサイズして1024pxをまたいだときに動かなくなってしまうので、以下のように書きかえました。

[code]

    dropDownMenu();
    $(window).resize(dropDownMenu);
    
    function dropDownMenu() {
        if ($(window).width() > 1024) {
            $('#main_header_nav li, #lower_header_nav li').hover(function() {
                $('>ul', this).stop(true, true).slideDown('fast');
            }, function() {
                $('>ul', this).stop(true, true).slideUp('fast');
            });
        }
    }
    
    drawerMenu();
    $(window).resize(drawerMenu);
    
    function drawerMenu() {
        if ($(window).width() <= 1024) {
            $('#sp_menu_open, #sp_menu_close').click(function() {
                $('#lower_header_nav').animate({ width: 'toggle' });
            });
        }
    }
    
    changeHeader();
    $(window).scroll(changeHeader);
    
    function changeHeader() {
        if ($(window).width() > 1024) {
            var headerChangeHeight = 200; // 切り替わるタイミング
            if ($(window).scrollTop() >= headerChangeHeight) {
                $('#lower_header').slideDown('fast');
            } else {
                $('#lower_header').slideUp('fast');
            }
        }
    }
    
[/code]

ですが、思うような結果が得られません。

1024px以下にリサイズすると、#lower_headerが表示されません。  
1025px以上にリサイズすると、#lower_header_navが表示されません。  
また、発生条件がわからないのですが、1024px以下にリサイズした後、ドロップダウンしてしまうことがあります。  
また同様に、1025px以上にリサイズした後、ドロップダウンが一瞬になる（スライドしない）ことがあります。

調べたり試したり、思いつく限りのことをしましたが、自力では解決できませんでした。  
だいぶ混乱しており恐縮ですが、どなたかご教示いただければ幸いです。  
よろしくお願いいたします。




質問者です。  
下記のコードで解決しました！

[code]

    // メニューにホバーしたとき
    $('#main_header_nav li, #lower_header_nav li').hover(function() {
        // カーソルがのったら開く
        $('>ul', this).stop(true, true).slideDown('fast');
    }, function() {
        // カーソルが外れたら、PCでは閉じ、タブレット・スマホでは開いたまま
        if ($(window).width() > 1024) {
            $('>ul', this).stop(true, true).slideUp('fast');
        } else {
            $('>ul', this).stop(true, true).slideDown(0);
        }
    });
    
    // ハンバーガーボタン・閉じるボタンをタップしたとき
    $('#sp_menu_open, #sp_menu_close').click(function() {
        $('#lower_header_nav').animate({ width: 'toggle' });
    });
    
    // 画面をリサイズしたとき
    $(window).resize(function() {
        showLowerHeader(); // #lower_header の表示/非表示
        if ($(window).width() > 1024) {
            // PCの場合
            // #lower_header_nav を表示
            $('#lower_header_nav').animate({ width: 'show' }, 0);
            // 上記だけだと display:block になってしまうので、本来の値を再指定
            $('#lower_header_nav').css({ display: 'inline-block' });
            // 子メニューを非表示 （ホバーで表示）
            $('#main_header_nav li > ul, #lower_header_nav li > ul').slideUp(0);
        } else {
            // タブレット・スマホの場合
            // #lower_header_nav を非表示 （ハンバーガーボタンタップで表示）
            $('#lower_header_nav').animate({ width: 'hide' }, 0);
            // 子メニューを表示
            $('#main_header_nav li > ul, #lower_header_nav li > ul').slideDown(0);
        }
    });
    
    // ページを読み込んだとき
    showLowerHeader();
    
    // スクロールしたとき
    $(window).scroll(showLowerHeader);
    
    // PCのみ、スクロール量に応じて #lower_header を表示/非表示
    function showLowerHeader() {
        if ($(window).width() > 1024) {
            var h = 200; // 切り替わるタイミング
            if ($(window).scrollTop() >= h) {
                $('#lower_header').slideDown('fast');
            } else {
                $('#lower_header').slideUp('fast');
            }
        } else {
            $('#lower_header').slideDown(0);
        }
    }
    
[/code]

ポイントは下記の三点でした。

  1. イベントハンドラを1回だけ登録するよう記述する（resizeの中にclickやhoverを書かない）
  2. ifの分岐は各イベントハンドラ内に記述する
  3. 操作対象の要素を条件ごとに確実に表示・非表示する

今のところ問題なさそうですが、処理が重くなった場合、必要に応じてthrottleを行おうと思います。  
回答くださったgochoさん、本当にありがとうございます。




質問者です。  
下記のコードで解決しました！

[code]

    // メニューにホバーしたとき
    $('#main_header_nav li, #lower_header_nav li').hover(function() {
        // カーソルがのったら開く
        $('>ul', this).stop(true, true).slideDown('fast');
    }, function() {
        // カーソルが外れたら、PCでは閉じ、タブレット・スマホでは開いたまま
        if ($(window).width() > 1024) {
            $('>ul', this).stop(true, true).slideUp('fast');
        } else {
            $('>ul', this).stop(true, true).slideDown(0);
        }
    });
    
    // ハンバーガーボタン・閉じるボタンをタップしたとき
    $('#sp_menu_open, #sp_menu_close').click(function() {
        $('#lower_header_nav').animate({ width: 'toggle' });
    });
    
    // 画面をリサイズしたとき
    $(window).resize(function() {
        showLowerHeader(); // #lower_header の表示/非表示
        if ($(window).width() > 1024) {
            // PCの場合
            // #lower_header_nav を表示
            $('#lower_header_nav').animate({ width: 'show' }, 0);
            // 上記だけだと display:block になってしまうので、本来の値を再指定
            $('#lower_header_nav').css({ display: 'inline-block' });
            // 子メニューを非表示 （ホバーで表示）
            $('#main_header_nav li > ul, #lower_header_nav li > ul').slideUp(0);
        } else {
            // タブレット・スマホの場合
            // #lower_header_nav を非表示 （ハンバーガーボタンタップで表示）
            $('#lower_header_nav').animate({ width: 'hide' }, 0);
            // 子メニューを表示
            $('#main_header_nav li > ul, #lower_header_nav li > ul').slideDown(0);
        }
    });
    
    // ページを読み込んだとき
    showLowerHeader();
    
    // スクロールしたとき
    $(window).scroll(showLowerHeader);
    
    // PCのみ、スクロール量に応じて #lower_header を表示/非表示
    function showLowerHeader() {
        if ($(window).width() > 1024) {
            var h = 200; // 切り替わるタイミング
            if ($(window).scrollTop() >= h) {
                $('#lower_header').slideDown('fast');
            } else {
                $('#lower_header').slideUp('fast');
            }
        } else {
            $('#lower_header').slideDown(0);
        }
    }
    
[/code]

ポイントは下記の三点でした。

  1. イベントハンドラを1回だけ登録するよう記述する（resizeの中にclickやhoverを書かない）
  2. ifの分岐は各イベントハンドラ内に記述する
  3. 操作対象の要素を条件ごとに確実に表示・非表示する

今のところ問題なさそうですが、処理が重くなった場合、必要に応じてthrottleを行おうと思います。  
回答くださったgochoさん、本当にありがとうございます。

