簡體   English   中英

根據元素的高度和寬度在頁面上定位

[英]Position element on page based on its height and width

我在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();
            });

        });

這是問題的屏幕截圖(代碼應使菜單顯示在鏈接上方,因為其高度大於鏈接下方的偏移空間)

在此處輸入圖片說明

看起來問題出在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
        });
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM