javascript - 下拉方向根据可用空间而变化

标签 javascript drop-down-menu

我刚刚开始编程,我需要你的帮助。

我的下拉子菜单-s有问题。我的标题上有一个简单的下拉菜单,但仅在这种情况下它距离窗口边框太近(取决于权限)。

因此,子菜单在窗口边框之外打开到右侧,用户看不到它的内容。

我希望它检测右侧是否有足够的空间可以打开。如果是,请从右侧打开。如果左侧打不开。您能帮我解决这个问题吗?

enter image description here

当有足够的空间时,这就是它的工作原理。 enter image description here

这是我的 html:

<ul class="main-menu-list">
        <li class="header-dropdown-item">
            <span class="header-dropdown-item-title">Admin</span>
            <img src="../Layout/images//arrow-down.svg" alt="">
            <ul class="sub-menu-list">
                <li class="header-dropdown-item">
                    <a class="arrow-right header-dropdown-item-title">Users</a>
                    <ul class="sub-menu-list-right">
                        <li>
                            <a class="header-sub-menu-item">New
                                users</a>
                        </li>
                        <li>
                            <a class="header-sub-menu-item">Users
                                management</a>
                        </li>
                        <li>
                            <a class="header-sub-menu-item" >Contacts List</a>
                        </li>
                    </ul>
                </li>
                <li class="header-dropdown-item">
                    <a class="arrow-right header-dropdown-item-title">Security</a>
                    <ul class="sub-menu-list-right">
                        <li>
                            <a class="header-sub-menu-item" >Roles</a>
                        </li>
                        <li>
                            <a class="header-sub-menu-item" >Roles and
                                Permissions</a>
                        </li>
                        <li>
                            <a class="header-sub-menu-item" >Column Based
                                Security</a>
                        </li>
                    </ul>
                </li>
                <li class="header-dropdown-item">
                    <a class="arrow-right header-dropdown-item-title">Notifications Management</a>
                    <ul class="sub-menu-list-right">
                        <li>
                            <a class="header-sub-menu-item"
                               >Email Notifications</a>
                        </li>
                        <li>
                            <a class="header-sub-menu-item" >Sent Email
                                Notifications</a>
                        </li>
                    </ul>
                </li>
                <li class="header-dropdown-item">
                    <a class="arrow-right header-dropdown-item-title">Source Data Analysis</a>
                    <ul class="sub-menu-list-right">
                        <li>
                            <a class="header-sub-menu-item" >Automated
                                Error Logging</a>
                        </li>
                    </ul>
                </li>
                <li class="header-dropdown-item">
                    <a class="arrow-right header-dropdown-item-title">Technical Services</a>
                    <ul class="sub-menu-list-right">
                        <li>
                            <a class="header-sub-menu-item" >Dropdown Lists</a>
                        </li>
                        <li>
                            <a class="header-sub-menu-item" >Unconventional
                                Tags</a>
                        </li>
                        <li>
                            <a class="header-sub-menu-item"
                                >Tag Matching Duplicates</a>
                        </li>
                        <li>
                            <a class="header-sub-menu-item" >3 Digit Code
                                Register</a>
                        </li>
                    </ul>
                </li>
            </ul>
        </li>
    </ul>

这是我的 CSS:

.sub-menu
        background-color: header-sub-menu-background-color;
        color: header-sub-menu-color;
        display: flex;
        justify-content: flex-end;
        height: header-sub-menu-height;
        padding-right: page-side-padding;
        span
          margin: 10px 0;
          display: inline-block;
          cursor: pointer;
        ul
            margin: 0;
            list-style: none;
            display: flex;
            align-items: center;
            justify-content: space-between;
            font-family: font-default-content;
            font-size: font-size-ssm;
            font-weight: bold;
            text-transform: uppercase;
            padding: 0;
            li
                & + li
                    margin-left: 30px;
            a
                cursor: pointer;
        ul
            & > li:hover
                & > a,
                & > span
                    color: header-menu-active-color;

                > .arrow-right:after
                        border-left-color: header-menu-active-color;

                > .sub-menu-list
                    shown()

                > .sub-menu-list-right
                    showImmediately()
            li

                .arrow-right
                    cursor: default;

                    &:after
                        pointer-events: none;
                        position: absolute;
                        content: "";
                        width: 0;
                        height: 0;
                        border-top: 3px solid transparent;
                        border-bottom: 3px solid transparent;
                        border-left: 3px solid gray-color-3;
                        display: inline-block;
                        vertical-align: middle;
                        right: 12px;
                        top: 0;
                        bottom: 0;
                        margin: auto;
                a:hover, span:hover
                    color: header-menu-active-color;

        .main-menu-list li
            position: relative;
            .sub-menu-list, .sub-menu-list-right
                hidden()
                display: inline-block;
                list-style: none;
                position: absolute;
                background-color: black-color-1;
                top: 31px;
                left: -15px;
                z-index: $main-menu-sub-menu-list-zindex;
                -webkit-box-sizing: border-box;
                box-sizing: border-box;
                padding: 0;
                li
                    position: relative;
                    white-space:nowrap;
                    margin-left: 0;
                    :hover > .sub-menu-list-right
                        shown()
                a
                    width: 100%;
                    font-family: font-default-content;
                    font-size: 10px;
                    font-weight: 700;
                    padding: 10px 32px 10px 15px;
                    display: inline-block;
                &:hover
                    color: header-menu-active-color;
                p:hover
                    color: header-menu-active-color;
            .sub-menu-list
                min-width: 100%;
                hideWithDelay()
            a
                text-decoration: none;
                display: inline-block;
                color: gray-color-3;
            .active
                color: header-menu-active-color;
            .sub-menu-list-right
                top: 0;
                left: 100%;
            &:hover
                .sub-menu-list
                    shown()
                    &:hover
                        shown()
                        .sub-menu-list-right
                            &:hover
                                shown()
                span
                    background-color: black-color-1
        .main-menu-list
            li:first-child:nth-last-child(2)
            li:first-child:nth-last-child(3)
                .sub-menu-list-right
                    left: auto;
                    right: 100%;

和纯 JS:

<script type="text/javascript">
    (function () {
        handleMenuItems();

        // functions:

        function handleMenuItems() {
            var menuEl = document.querySelector(".menu"),
                userLinksList = menuEl && menuEl.querySelector(".user-links"),
                recentlyItemListEl = menuEl && menuEl.querySelector(".recently-visited-item"),
                favoriteItemListEl = menuEl && menuEl.querySelector(".favorites-item");

            if (userLinksList) {
                userLinksList.addEventListener("mouseover", function (evt) {
                    var options = {
                        url: "/api/userlinks",
                        method: "GET",
                        successCallback: onloadUserLinks
                    };

                    function onloadUserLinks(result) {
                        if (!window.__RAPMD__) {
                            window.__RAPMD__ = {};
                        }

                        window.__RAPMD__.lastUserLinks = result;
                        createMenuList(result.RecentLinks, recentlyItemListEl, "No recently visited pages");
                        createMenuList(result.Favorites, favoriteItemListEl, "No favorite pages");
                    }

                    if (!window.__RAPMD__ || !window.__RAPMD__.lastUserLinks) {
                        ajax(options);
                    }
                });

                userLinksList.addEventListener("mouseleave", function (evt) {
                    if (!window.__RAPMD__) {
                        return;
                    }

                    window.__RAPMD__.lastUserLinks = null;
                });
            }
        }

        function createMenuList(items, menuItemEl, emptyListTitle) {
            if (!menuItemEl) {
                return;
            }

            var df = document.createDocumentFragment();

            (items.length ? items : [{ Title: emptyListTitle }]).forEach(function (item) {
                var li = document.createElement("li"),
                    a = document.createElement("a");

                if (item.Url) {
                    a.href = item.Url;
                } else {
                    a.classList.add("empty-link-item");
                }
                a.innerHTML = item.Title;
                li.appendChild(a);
                df.appendChild(li);
            });

            menuItemEl.textContent = "";
            menuItemEl.appendChild(df);
        }

        function ajax(options) {
            var url = options.url,
                method = options.method,
                successCallback = options.successCallback,
                failureCallback = options.failureCallback,
                xhr = new XMLHttpRequest();

            xhr.open(method, url);
            xhr.onload = function () {
                if (xhr.status === 200 && successCallback) {
                    var response = JSON.parse(xhr.responseText);
                    successCallback(response);
                } else if (failureCallback) {
                    failureCallback();
                }
            };
            xhr.send();
        }
    })();
</script> 

最佳答案

我认为没有简单的 CSS 方法可以解决这个问题。如果空间不够,我能想到的唯一选择就是将其向左对齐。您可以使用 document.querySelector("#sub-menu").getBoundingClientRect() 函数获取元素的位置。

{
    "x": 1261.5,
    "y": -309,
    "width": 298,
    "height": 452,
    "top": -309,
    "right": 1559.5,
    "bottom": 143,
    "left": 1261.5
}

然后您可以检查子菜单是否会溢出页面并分配一个类,使其向左对齐而不是向右对齐。

const subMenuBound = document.querySelector("#sub-menu").getBoundingClientRect();
const windowWidth = document.getElementsByTagName("body")[0].clientWidth;

const subMenuX = subMenuBound.x;
const subMenuWidth = subMenuBound.width;

if (subMenuBound.width + subMenuBound.x > windowWidth) {
    // assign a class to the sub-menu to
    // align to the left instead of right
} else {
    // remove the class
}

关于javascript - 下拉方向根据可用空间而变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68711455/

相关文章:

javascript - 如何访问 GraphQL 解析器中的请求对象(使用 Apollo-Server-Express)

javascript - 如何在wp8网络浏览器控件中使用javascript加载html?

html - css - 垂直嵌套菜单 - 无法获得正确的嵌套样式,它会形成更大的矩形

javascript - jQuery Accordion 菜单和复选框问题

javascript - 如何获取高亮文本?

html - 在水平显示中添加菜单项

HTML/CSS 菜单样式栏布局不正确

javascript - 如何使用 jquery 从变量设置下拉框的值和文本?

android - 如何在android中使用按钮 TextView 等创建自定义下拉/弹出 View

javascript 语法/将两个项目放在一个 $ 语法中