2012-03-26 107 views
0

我已经在此处构建了一个下拉菜单http://dev.driz.co.uk/jsonmenu/,它使用JSON动态构建菜单。将HTML放入页面本身的原因是为了提高性能(只加载你需要的),以便我可以将菜单放在表格外。页面上的位置元素根据其高度和宽度

我已经开始实施一种方法来根据它的高度和邻近窗口(浏览器窗口而不是可滚动容器)来定位菜单。问题是,当菜单的高度大于链接和视口下方的空间时,它应该移动上面的菜单,反之亦然。它的一部分工作不完全正确。

注意:如果用户移动窗口等,插入HTML后定位完成的原因而不是回调,这是因为如果用户滚动或者类似的东西,菜单将被删除,所以它将毫无意义然后。根据要求

代码:

 $(document).ready(function() { 

      $('a.buildMenu').click(function (event) { 

       // Prevent normal behaviour 
       event.preventDefault(); 

       // Stops it bubbling to the document 
       event.stopPropagation(); 

       var link = $(this); 

       // If the menu already exists remove it and exit the request 
       if($(document).find('div#' + $(link).data('id')).length){ 
        $('.buildMenu').removeClass('selected'); 
        $('.menu').remove(); 
        return false; 
       } 

       // Remove any other menus from the DOM 
       $('.buildMenu').removeClass('selected'); 
       $('.menu').remove(); 

       // Get the position of the link 
       var offset = link.offset(); 
       var top = offset.top; 
       var left = offset.left; 
       var bottom = top + link.height(); 
       var right = $(window).width() - link.width(); 

       top = top + link.height(); 

       bottom = bottom + link.height(); 

       // Append the menu to the DOM in position 
       var menuInstance = $('<div class="menu loading">loading...</div>').appendTo('body').css({'position':'absolute','top':top,'left':left}); 

       // Add the instance id 
       $(menuInstance).attr('id', $(link).data('id')); 

       // Add class of selected to clicked link 
       $(this).addClass('selected'); 

       // Request JSON data   
       $.ajax({ 
        url: 'menu.json', 
        timeout: 5000, 
        dataType: 'JSON', 
        success: function (data) { 

         // Build the menu 
         var ul = $("<ul/>").attr("id", data.menu.id).addClass(data.menu.class); 

         // For each menu item 
         $.each(data.menu.content.menuitem, function() { 
          var li = $("<li/>").appendTo(ul).addClass(this.liClass); 
          var anchor = $("<a/>").appendTo(li).attr("href", this.href).attr("title", this.title); 
          var span = $("<span/>").appendTo(anchor).addClass(this.icon).html(this.text) 
         }); 

         // Remove the loading class and insert menu into instance 
         $(menuInstance).removeClass('loading').html(ul); 

         // If the menu is taller than the bottom space 
         if(menuInstance.height() > bottom) { 
          menuInstance.css({'top':'auto','bottom':bottom,'left':left}); 
         } 
         // If the menu is taller than the top space 
         else if(menuInstance.height() > top) { 
          menuInstance.css({'top':top,'left':left}); 
         } 
         // Default position... 
         else { 
          menuInstance.css({'top':top,'left':left}); 
         } 

        }, 
        error: function (jqXHR, textStatus, errorThrown) { 
         console.log(jqXHR, textStatus, errorThrown); 
        } 
       }); 

      }); 

      // Remove menu from DOM if anything except the menu is clicked 
      $(document).bind('click', function (event) { 
       var clicked = $(event.target); 
       if (!clicked.parents().hasClass('menu')) { 
        $('.buildMenu').removeClass('selected'); 
        $('.menu').remove(); 
       } 
      }); 

      // Remove menu if user scrolls panel 
      $(window).bind('resize', function() { 
       $('.buildMenu').removeClass('selected'); 
       $('.menu').remove(); 
      }); 

      $('div').bind('scroll', function() {  
       $('.buildMenu').removeClass('selected'); 
       $('.menu').remove(); 
      }); 

     }); 

这是问题的一个屏幕截图(代码应该作出这样的菜单出现上面的链接,因为它的高度比下面的链接偏置空间更大)

enter image description here

+0

这是更好,如果你在这里复制你的代码。 – ShankarSangoli 2012-03-26 13:17:33

+0

我会但它太长了。 – Cameron 2012-03-26 13:18:13

回答

1

看起来问题是71-74行。

// If the menu is taller than the bottom space 
if(menuInstance.height() > bottom) { 
     menuInstance.css({'top':'auto','bottom':bottom,'left':left}); 
} 

bottom被计算为窗口的菜单链接的底部顶部的距离......和你说“如果菜单高度比这更大”。

我想你想检查的是菜单高度是否大于从菜单链接底部到窗口底部的距离。所以...

if(menuInstance.height() > ($(window).height() - bottom)) 

这应该从链接的底部到窗口底部的距离,并将其与菜单的高度进行比较。

然后你需要纠正你的位置menuInstance

'bottom': ($(window).height() - top) + link.height() 

下面是完整的代码...

// If the menu is taller than the bottom space 
    if (menuInstance.height() > ($(window).height() - bottom)) { 
     menuInstance.css({ 
      'top': 'auto', 
      'bottom': ($(window).height() - top) + link.height(), 
      'left': left 
     }); 
    } 
+0

我对容器div的位置不感兴趣。因为菜单可以并且应该能够坐在其外面。更多的是菜单是否可以放在链接下方的屏幕上,还是需要移动。所以它应该与窗口而不是容器有关。 – Cameron 2012-03-26 13:46:37

+0

虽然,我不得不说,你使用AJAX菜单来进行“性能”和“在窗口外定位”......这是相同的菜单,每次链接被点击时,它必须重新加载相同的菜单。这真的是一个性能优势? (而不是这个请求的要点,所以你可以保持菜单“在表格内”? – 2012-03-26 13:48:26

+0

哦,我明白你现在说的话 – 2012-03-26 13:49:17

相关问题