网页导航菜单的子菜单平铺(带背景栏)实现

-

之前给公司做的一个小型知识库管理网站时遇到一个问题,在这里记录下解决的过程。

公司的美工要求首页导航菜单 要跟他们公司的网站风格保持一致,如图所示

(子菜单是平铺的)

我一看,心想很简单嘛

先贴一下通用菜单html结构

<li>
     <a href="" class="abc">热设计</a>
          <ul>
               <li><a href="">设计规范</a></li>
               <li><a href="">案例分享</a></li>
               <li><a href="">经验文章</a></li>

</ul>
     
</li>

只要设置子菜单的<li>css为float:left,并给<ul>设置背景就可以了嘛

但是 实现的时候发现并不简单,因为<ul>的位置是基于一级菜单<li>的位置的,所以<ul>的背景栏只会从一级菜单的<li>的位置开始显示,不会显示通栏(背景栏会铺满页面)

于是我想给子菜单的<ul>外面包一层<div>,并设置<div> position:absolute;   left:0;  top:0;并取消一级菜单<li>的position:relative属性

最终得到这样的结果

虽然背景栏铺满了,但是子菜单却不跟一级菜单对齐了。

通常是设置以及菜单的<li>为position:relative;而子菜单的<ul>(或本例中外层的div)为position:absolute,(偏移多少可以自行设置left跟top)这样就可以使子菜单随父菜单对齐了,

但是为了设置通栏的背景,去掉了一级菜单<li>的position:relative属性,导致子菜单无法跟踪父菜单;

于是设想 仍设置一级菜单<li>为position:relative,而设置div为position:fixed(position为fixed时只会根据整个屏幕进行布局,并始终悬浮,父容器的position是否为relative并不影响)

同时设置子菜单的<ul>为position:absolute,意图是想让子菜单<ul>跨过其父容器<div>,而去跟踪祖容器(即一级菜单的<li>)位置(因为了解到容器的position设置为absolute时,会去查找它父容器是否设置了position为relative,若设置了则根据其位置进行定位,若未设置就继续往上层祖容器查找,若都未设置,则根据页面进行定位)

结果如图:

子菜单全部移动到最左侧了(因为设置了left:0),说明子菜单没有追踪一级菜单的<li>,而是跟随了其父容器<div>的位置,就是说父容器只要设置了position属性,不管是否为relative,子容器都会根据其位置进行定位。

这样从逻辑上确定了只靠css是无法实现需要的效果的

{

1 要想设置背景为通栏,只能设置div为positon:absolute;left:0;且不能设置一级菜单<li>的position属性;

2 要想让子菜单追踪父菜单的位置,必须设置父菜单的position:relative,同时设置子菜单position:absolute;

1与2互相矛盾

}

所以 我们只能另寻他法,即jquery

jquery有一个名为 offset() 的方法,可以获取某个元素的位置(若该元素是基于父元素的位置定位的,在该方法获得相对于父元素的位置,不然则是相对于整个屏幕的位置)

如元素p, var pos=p.offset(), pos具有两个属性:p.top , p.left,根据字面意思就可以了解其含义;同时offset(top:x;top:y)可以动态设置元素的位置

我们在菜单的hover事件中对子菜单进行定位,代码如下所示

  var _this1 = null;
            $(‘.nav>li‘).hover(function () {
                _this1 = $(this);
                _this1.find(‘.second-nav‘).show();
                var p = _this1.offset();
                _this1.find(‘.second-nav‘).find(‘ul‘).offset({top:p.top+50,left:p.left-50})
                _this1.find(‘.abc‘).css(‘color‘, ‘ #ff6a00‘)
                var _this2 = null;
                _this1.find(‘.second-nav‘).find(‘li‘).hover(function () {
                    _this2 = $(this);
                    _this2.find(‘.third-nav‘).show();
                    _this2.find(‘.third-nav‘).hover(function () {
                        $(this).show();
                    }, function () {
                        $(this).hide();
                    });
                }, function () {
                    _this2.find(‘.third-nav‘).hide();
                });
            }, function () {
                _this1.find(‘.second-nav‘).hide();
                _this1.find(‘.abc‘).css(‘color‘, ‘ #fff‘)

            });

其中加粗斜体为新加的两行代码(其他的代码都是导航菜单原有的),其中_this变量为鼠标滑过的一级菜单标题的<li>,

_this.offset()取得当前激活标题相对于屏幕的位置,并存入变量p,然后

_this1.find(‘.second-nav‘).find(‘ul‘).offset({top:p.top+50,left:p.left-50})

然后根据_this找到子代元素<ul>应用offset(top:x,left:y)方法进行定位,最后得到需要的结果

现在来看,这实在不算什么问题,解决方案也很简单,如果对jquery了解够多的话

当然,这都是后话了,当时还是纠结了好久,心路历程很曲折哈哈。

还是要把基础学扎实。

原文地址:https://www.cnblogs.com/zjh1437/p/8352720.html

时间: 2024-10-28 20:24:41

网页导航菜单的子菜单平铺(带背景栏)实现的相关文章

ASP.NET MVC动态生成网站菜单及子菜单

在开发ASP.NET MVC网站时,Insus.NET想实现动态产生网站的主菜单及子菜单. 你需要在网站管理后台管理此2张表(Menu,SubMenu)的信息,添加,删除,编辑,更新等. Sequence字段是序号.主菜单按此序号排序.IsMenu字段,添加上来的,不一定是菜单字段. 下面Insus.NET有此表添加的内容如下: 以上上主菜单,下面再来看来看看子菜单,结构与数据: 在子菜单的表结构中,也有一个Sequence字段,这个字段也是序号,不过它是按Controller字段来排序的.可以

安卓开发复习笔记——Menu菜单组件(选项菜单,上下文菜单,子菜单)

菜单是用户界面中最常见的元素之一,使用非常频繁,在Android中,菜单被分为如下三种,选项菜单(OptionsMenu).上下文菜单(ContextMenu)和子菜单(SubMenu). 菜单的实现方式有2种:一种是通过布局文件xml生成菜单,另一种是通过代码生成. 三种菜单内容有点多,不过大体相似,一次性讲完吧,本人偏好代码动态生成,下面就以代码为例. 1.选项菜单(OptionsMenu) 先来看下选项菜单的效果图:   在一个Activity界面中点击手机Menu键,在屏幕下方弹出的菜单

js动态加载div显示主菜单和子菜单+jquery获取动态id

最近在做项目重构的主界面工作中,需要动态显示主菜单以及子菜单(各个界面的链接),查看原来老系统采用的是asp控件,但是重构的时候采用mvc框架,而且这些菜单并不是死的,而是通过其他界面来配置的,主菜单和子菜单都是数据库查询显示.因此,就想到了动态的拼接div来实现效果. 要实现的效果图 实现步骤: 第一步,查询主菜单名称 第二步,查询具体界面名称 第三步,更具菜单ID实现主菜单和子菜单的匹配 实现思路: 每个主菜单一个div,主菜单下的子菜单为一个整体的div,每个具体子菜单为li. 代码实现:

Android 菜单之子菜单SubMenu

子菜单就是在点击了菜单中的选项后弹出的要对菜单中选项操作的菜单           他的操作与之前的两种类型的菜单操作差不多 动态添加 @Override public boolean onCreateOptionsMenu(Menu menu) { SubMenu file = menu.addSubMenu("文件"); SubMenu edit = menu.addSubMenu("编辑"); file.setHeaderTitle("文件"

jQuery/CSS3大屏下拉菜单 自定义子菜单内容

这是一款样式很酷的jQuery/CSS3下拉菜单,首先这款CSS3菜单是宽屏的,主要是下拉菜单非常大气,更重要的是,下拉菜单的内容可以自己定义,也就是说,下拉菜单中可以定义菜单.图片等HTML元素,是一款非常实用的jQuery/CSS3下拉菜单插件. 在线预览   源码下载

Android开发菜单以及子菜单

package com.example.androidtest; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.MenuItem; import android.view.SubMenu; import android.widget.Toast; public class MainActivity extends Activity{ @Ove

jQuery宽屏下拉菜单导航 子菜单可自定义

jQuery是一款流行已久的Javascript框架,确实很好用.今天我们要介绍一款用jQuery实现的下拉菜单导航插件,下拉菜单的外观是仿腾讯云官网菜单的.鼠标滑过主菜单时,即可展开二级下拉子菜单.值得注意的是,这款jQuery下拉菜单的子菜单内容可以自定义,因此也非常灵活. 访问地址:http://www.xuecss3.com/jquery-10-757-1.html 另外分享一个FQ软件:下载地址  http://www.xuecss3.com/qianduan-9-374-1.html

Android攻城狮使用SubMenu创建子菜单

给OptionsMenu选项菜单添加子菜单: 1 public class MainActivity extends Activity { 2 3 @Override 4 protected void onCreate(Bundle savedInstanceState) { 5 super.onCreate(savedInstanceState); 6 setContentView(R.layout.fragment_main); 7 8 } 9 10 @Override 11 public

Android学习(二十三)SubMenu 子菜单

一.SubMenu子菜单 和功能菜单相似,但是可以添加子菜单. 二.实现步骤: 1.通过onCreateOptionsMenu方法创建子菜单,可以通过代码动态创建,也可以通过xml进行创建. 2.通过onOptionsItemSelected方法实现点击子菜单的事件. 三.参考代码: 1.通过代码动态创建子菜单:   main.java package com.example.zhengcheng.submenudemo; import android.support.v7.app.Action