jquery - 根据元素的高度和宽度在页面上定位元素

标签 jquery css

我在这里建立了一个下拉菜单http://dev.driz.co.uk/jsonmenu/使用 JSON 动态构建菜单。这样做而不是将 HTML 放在页面本身中的原因是为了提高性能(只加载您需要的内容),这样我就可以将菜单放在表格之外。

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

注意:定位是在插入 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

最佳答案

看起来问题出在第 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
        });
    }

关于jquery - 根据元素的高度和宽度在页面上定位元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9872735/

相关文章:

jquery - 获取更改时输入文本的值

javascript - 无法使用 jquery 获取背景框以打开和关闭显示

html - 如何始终将页面的中心保持在调整大小的屏幕的中心

css - 问题 : CSS for a window of a web application

javascript - 提交后重置我的表格

用于检测失败选择器的 JQuery 插件

php - 如何阻止 cURL 使用 100 Continue?

javascript - IE 中的不透明度属性

jquery - 为什么说 $ 未定义?

css - 使用 CSS 设置某些字符的样式