Jquery驱动菜单展示退化行为如何调试?包括代码示例

时间:2013-05-24 16:04:33

标签: jquery runtime-error modx submenu

好的我要编辑这个问题而不是打开一个新问题。

您好我将最初构建为cloud平台上的平面HTML网站的网站转换为ModX,该菜单是该网站的主要功能,由Jquery定义组成,由单个JQuery文件处理

You can see a preview version of the menu here

这一切几乎完美!我遇到的问题是访问了一个部分,如果我移动到另一个部分,然后返回到第一个,其子页面已停止响应,没有输出控制台错误,我无法找出问题所在。

处理菜单所涉及的代码很长而且很可怕但是生成链接和子链接的例子和示例

menu_2 = {
    id: 'menu2',
    title: '1',
    colour: '#A70335',
    hoverColour: '#D80550',
    click: function() {
                    $('#introduction_jplayer').jPlayer("play", 0);
        MENU.show_page_content('nb/index.php?id=2');
    }
}
MENU.add_menu(menu_2);
sub_menu_42 = {
    id: 'sub_menu42',
    title: '',
    colour: '#A70335',
    hoverColour: '#D80550',
    click: function() {
        MENU.show_page_content('nb/http://');
    }
}

勇敢的是这里的JS处理所有事情 - 抱歉:)

(function($) {
$.fn.fade_in_sequence = function(fade_in_time, time_between) {
    /*
     * @brief Animate fade ins one after the other as a squence
     */
    time_between = typeof(time_between) == 'undefined' ? 0 : time_between;
    fade_in_time = typeof(fade_in_time) == 'undefined' ? 500 : fade_in_time;

    // The amount of remaining time until the animation is complete is initially 
    // set to the value of the entire animation duration
    var remaining_time = $(this).size() * (fade_in_time + time_between);

    var i = 0;
    return $(this).each(function() {
        // wait until previous element has finished fading and time_between has elapsed
        $(this).delay(i++ * (fade_in_time + time_between));
        remaining_time -= (fade_in_time + time_between);

        // only fade this item in if it's not on our skip list
        if ($(this).attr('id').substring(0,8) != 'not_fade') {
            $(this).fadeIn(fade_in_time, function() {
                $(".visible_arrow").filter(":first").fadeOut().removeClass("visible_arrow");
            });
        } else {                
            // we still need to keep account of the time we didn't use up fading then
            $(this).delay(fade_in_time);
        }

        // wait until the animation is over to fill up the queue.
        $(this).delay(remaining_time + time_between);
    });
};
})(jQuery);

var MENU = (function($) {
var _menu = {};
_menu.menu_items = [];
_menu.render = function() {
    /*
     * @brief draws menu on the screen
     */

    // find the menu div and add the items to it
    $.each(this.menu_items, function(index, this_menu) {
        var menu_div = '<div id="' + this_menu.id + '" class="menu_item not-selected" ' +
            'style="background-color:' + this_menu.colour + ';"> ' +
            '<div style="position: relative; top: 2.2em;">' + this_menu.title + '</div>' +
            '<span class="visible_arrow" style="position: absolute; top: 2px; left: -14px; background-color:' + this_menu.colour + ';"><img src="images/arrow.png"></span>' +
            '</div>';

        $('#menu-test').append(menu_div);

        // sort out the hover
        $('#'+this_menu.id).hover(
            function () {
                $(this).css({'background-color': this_menu.hoverColour});
            }, 
            function () {
                $(this).css({'background-color': this_menu.colour});
            }
        );

        // create a click event for the menu item
        $('#'+this_menu.id).bind('click', {click_function: this_menu.click, id: this_menu.id, sub_menu: this_menu.sub_menu}, function(event) {
            // NB-92 weirdness happens if we redraw the same menus.
            if ($('#'+this_menu.id).hasClass('selected'))
            {
                return;
            }

            // stop any previous animations
            $('.menu_item').stop(true, true).css({
                left: 0
            });

            // fade out and prepare removal of any previous sub-menu that's showing
            $('.menu_sub_item').addClass('goodbye').fadeOut(1000);
            $('.menu_sub_item').children().addClass('goodbye').fadeOut(1000);
            $('#sub_menu_image').remove();

            // mark the menu item as selected and the rest as not-selected
            $('.selected').removeClass('selected').addClass('not-selected');
            $('#'+this_menu.id).addClass('selected').removeClass('not-selected');

            // bounce out the selected menu item so the user gets some feedback
            $('.selected').animate({
                    left: '+=120'
                    }, 2000, 'easeOutBounce');

            if ( !jQuery.browser.msie ) 
            { 
                $('.selected').fadeTo(700, 1.0); 
            }
            else
            {
                // *TODO internet explorer friendly fade out
            }

            $('.selected').css({
                'background-image': 'url(images/transparent.png)'
                    });
            $('.selected').animate({
                left: 0
            }, 2000, 'easeOutBounce');

            // darken out the not-selected menu items
            if ( !jQuery.browser.msie ) 
            { 
                $('.not-selected').fadeTo(700, 0.65); 
            }
            else
            {
                // *TODO internet explorer friendly fade out
            }

            $('.not-selected').css({
                'background-image': 'url(images/semitrans.png)'
            });

            // render the new sub-menu
            $.each(event.data.sub_menu, function(index, sub_menu) {
                var menu_div = '<div id="' + sub_menu.id + '" class="menu_sub_item" ' +
                    'style="background-color:' + sub_menu.colour + '"> ' +
                    '<div style="position: relative; top: 2.2em;">' + sub_menu.title + '</div>' +
                    '</div>';

                $('#menu-test').append(menu_div);

                // sort out the hover
                $('#'+sub_menu.id).hover(
                    function () {
                        $(this).css({'background-color': sub_menu.hoverColour});
                    }, 
                    function () {
                        $(this).css({'background-color': sub_menu.colour});
                    }
                );

                // where is our top level menu item positioned?
                var position =  $('#menu-test').children(':eq(' + index + ')').position();

                // put this menu item into the right place
                $('#menu-test').children(':last').css({
                    left: position.left + 120,
                    top: position.top
                });


                // add the on click event for this sub-menu item -- much easier than the top level menus!
                $('#'+sub_menu.id).bind('click', {click_function: sub_menu.click}, function(event) {
                    if($.isFunction(event.data.click_function)) {
                        event.data.click_function();
                    }
                });

            });

            // add the arrow
            $("div[id*='not_fade']").not('.goodbye').append('<div id="sub_menu_arrow" style="position: absolute; z-index: -1; top: 2px; left: -11px; background-color:' + this_menu.colour + ';"><img id="sub_menu_image" src="images/arrow.png"></div>');

            // now fade the sub menus in (delay it a bit first!)
            $('.menu_sub_item').not('.goodbye').delay(500).fade_in_sequence(400, 10);

            // and fade in the one we skipped over, and finally remove the old ones
            $("div[id*='not_fade']").delay(1200).fadeIn(1000, function() {
                $('.goodbye').remove();
            });

            // remove the next and prior buttons in case they've been left over from previous content
            $('#next').fadeOut();
            $('#prior').fadeOut();

            // and finally call the click, but only call it if it's actually a function
            if ($.isFunction(event.data.click_function)) {
                event.data.click_function();
            }

        });

    });

var width = $(window).width();
var resize_timeout = null;
    // make sure if the user re-sizes the browser, we reset
    $(window).resize(function() {
    var on_resize = function() {
        $('.selected').removeClass('selected').addClass('not-selected');
        $(window.location.reload());
    }

            var new_width = $(window).width();
    // check if the new width is actually different. Internet explorer tells you when anything has resized!!!
    if ((width != new_width) && !jQuery.browser.msie)
    {
        if (resize_timeout)
                {
        window.clearTimeout(resize_timeout);
        }
        resize_timeout = window.setTimeout(on_resize, 10);
    }
    width = new_width;
    });
};


_menu.animate_intro = function() {
    /*
     * @brief show the animated intro.  This will only be seen once!
     */
    if (jQuery.browser.msie)
{
    // disable menu clicking in internet explorer, it just can't handle it!
    $('#menu-test').children().attr('disabled', 'true');
    }
    $('#main_jplayer').jPlayer("play");
    $('#menu-test').children().fade_in_sequence(500);

$('#menu-test').children(':first').animate( {left:0 }, 1, function() {
    if (jQuery.browser.msie)
    {
    // reenable menu clicking in internet explorer once the main menu is rendered
            $('#menu-test').children().removeAttr('disabled');
    }
    }).animate({
            left: '+=120'
        }, 2000, 'easeOutBounce').animate({
            left: 0
    }, 2000, 'easeOutBounce');
};

_menu.animate = function(menu_item) {
    /*
     * @brief animates the menu so that menu_item is opened
     */
};

_menu.add_menu = function(menu_item, parent_id) {
    /*
     * @brief add a new menu item
     */
    if (parent_id == null) {
        // by default, we'll add to the top level menu
        // first, add a sub-menu that we can take advantage of later
        menu_item['sub_menu'] = menu_item['sub_menu'] || [];
        this.menu_items.push(menu_item);
    } else {
        // find the parent_id in the menu, and add to the contents
        $.each(this.menu_items, function(index, this_menu) {
            if (this_menu.id == parent_id) {
                this_menu.sub_menu.push(menu_item);
            }
        });
    }
};

_menu.show_page_content = function(page_content_name) {
    /*
     * @brief Grab content from the server and shove it into the content area
     */
    $.ajax({
        type: 'GET',
        url: '/' + page_content_name,
        dataType: 'html',
        success: function(html) {
            $('#page_content').fadeTo(
                700, 0, function() {
                $(this).html(html).fadeTo(
                    700, 1
                );
            });
        }
    });
};

return _menu;
})(jQuery);

1 个答案:

答案 0 :(得分:0)

好的,我发现了问题所在,

基本上我错过了第一个菜单项上的ID,这意味着该行从未执行过:

// and fade in the one we skipped over, and finally remove the old ones
        $("div[id*='not_fade']").delay(1200).fadeIn(1000, function() {
            $('.goodbye').remove();
        });

这意味着旧的菜单项永远不会从页面流中删除,并且仍会干扰用户点击。目前我修改了代码如下:

// and fade in the one we skipped over, and finally remove the old ones
            $('.goodbye').fadeOut().delay(1000).remove();

这并没有淡化带有一类再见的物品,但它至少会删除它们,因此菜单是可用的。