博客列表 >如何编写一个专业实用的导航下拉菜单?

如何编写一个专业实用的导航下拉菜单?

JKY辉哥
JKY辉哥原创
2020年06月14日 00:19:56603浏览
  • 知识点:链接+无序列表+元素定位+事件监听+事件委托
  • vscode 快捷键
    vscode 快捷键

1. 链接 A 标签 的使用

  1. <!-- 1.打开一个网站 -->
  2. <a href="https://www.php.cn" target="_self">php.cn</a>
  3. <a href="https://www.php.cn" target="_blank">php.cn</a>
  4. <!--2. 下载一个文件 -->
  5. <a href="http://127.0.0.1:5500/0612/demo1.zip" target="_blank">下载</a>
  6. <!--3. 发邮件 -->
  7. <a href="mailto:1047858916@qq.com"" target="_blank">发邮件</a>
  8. <!--4.打电话 -->
  9. <a href="tel:158****4023"" target="_blank">打电话</a>
  10. <!--5. 锚点 -->
  11. <a href="#top"">跳转到锚点</a>
  12. <a id="top" style="margin-top: 1000px;">hello world!</a>

2. 列表

  • 有序列表
  • 无序列表
  • 自定义列表
  • 演示代码:
  1. <!-- 无序列表 ul+li -->
  2. <ul>
  3. <li><a href="">首页</a></li>
  4. <li><a href="">正在秒杀</a></li>
  5. <li><a href="">plus</a></li>
  6. </ul>
  7. <!-- 有序列表 -->
  8. <!-- ol+li -->
  9. <h3>商品分类</h3>
  10. <ol start="1" type="i">
  11. <li><a href="">电脑 / 办公</a></li>
  12. <li><a href="">服装 / 男装 / 女装</a></li>
  13. <li><a href="">图书 / 文娱 / 教育</a></li>
  14. </ol>
  15. <!-- 自定义列表 -->
  16. <!-- dl+dt+dd -->
  17. <dl>
  18. <dt>电话:</dt>
  19. <dd><a href="tel:189456***34" target="_blank">189456***34</a></dd>
  20. <dd><a href="tel:0551-67744***" target="_blank">0551-67744***</a></dd>
  21. <dt>地址:</dt>
  22. <dd>北京</dd>
  23. </dl>
  24. ```

3.元素定位

  • 相对定位:元素相对于自己在文档流中的原始位置进行偏移
  • 绝对定位:一定要有一个定位父级做为定位参照物,否则就相对于 body 进行定位
  • 演示代码:
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>元素定位</title>
  7. <style>
  8. /* 元素的定位: 元素默认在页面中是按文档流的顺序进行排列的 */
  9. /* 文档流: 元素的排列按照书写顺序,源码中的顺序 */
  10. body {
  11. /* 文档流定位 */
  12. position: static;
  13. border: 1px solid red;
  14. /* v: viewport, h:height */
  15. /* viewport: 视口, 可视窗口, 当前你的看到的窗口大小; */
  16. height: 100vh;
  17. }
  18. .box1 {
  19. width: 200px;
  20. height: 200px;
  21. border: 1px solid blue;
  22. /* 相对定位: 元素相对于自己在文档流中的原始位置进行偏移 */
  23. /* position: relative;
  24. position: absolute; */
  25. top: 50px;
  26. left: 50px;
  27. }
  28. .box2 {
  29. width: 100px;
  30. height: 100px;
  31. border: 2px solid gold;
  32. /* 绝对定位:一定要有一个定位父级做为定位参照物,否则就相对于body进行定位 */
  33. position: absolute;
  34. top: 50px;
  35. left: 50px;
  36. }
  37. </style>
  38. </head>
  39. <body>
  40. <div class="box1">
  41. <div class="box2"></div>
  42. </div>
  43. </body>
  44. </html>

4. 事件

  • 4.1 事件与事件监听

  1. <!-- 1.事件属性 -->
  2. <button onclick="console.log(this.innerText);">按钮1</button>
  3. <button>按钮2</button>
  4. <button>按钮3</button>
  5. <script>
  6. // 2.对象属性方式添加事件,只有最后一次点击有效,同名事件彼此覆盖
  7. document.querySelectorAll("button")[1].onclick = function () {
  8. console.log("第一次点击");
  9. };
  10. document.querySelectorAll("button")[1].onclick = function () {
  11. console.log("第二次点击");
  12. };
  13. // 3.事件监听器 (工作中更多推荐使用)
  14. const btn3 = document.querySelectorAll("button")[2];
  15. // btn3.addEventListener(事件类型,事件方法)
  16. btn3.addEventListener("click", function () {
  17. console.log("第一次点击");
  18. });
  19. btn3.addEventListener("click", function () {
  20. console.log("第二次点击");
  21. });
  22. // 可以给一个元素多次添加同一个事件,并且可以自定义事件的触发阶段
  23. </script>
  24. ```

  • 4.2 事件监听阶段

  1. <div>
  2. <li>
  3. <a href="#">点击我试试</a>
  4. </li>
  5. </div>
  6. <script>
  7. const a = document.querySelector("a");
  8. const li = document.querySelector("li");
  9. const div = document.querySelector("div");
  10. // const body = document.querySelector("body");
  11. const body = document.body;
  12. // 事件冒泡:由内向外
  13. a.addEventListener("click", showTagName, false);
  14. li.addEventListener("click", showTagName, false);
  15. div.addEventListener("click", showTagName);
  16. body.addEventListener("click", showTagName);
  17. // 事件捕获:由外向内
  18. a.addEventListener("click", showTagName, true);
  19. li.addEventListener("click", showTagName, true);
  20. div.addEventListener("click", showTagName, true);
  21. body.addEventListener("click", showTagName, true);
  22. function showTagName() {
  23. alert(this.tagName);
  24. }
  25. </script>
  26. ```
  • 4.3 事件代理/事件委托

  1. <!-- ul>li{item$}*10 table 创建10个li -->
  2. <ul>
  3. <li>item1</li>
  4. <li>item2</li>
  5. <li>item3</li>
  6. <li>item4</li>
  7. <li>item5</li>
  8. <li>item6</li>
  9. <li>item7</li>
  10. <li>item8</li>
  11. <li>item9</li>
  12. <li>item10</li>
  13. </ul>
  14. <script>
  15. // 循环每一个元素,并打印到控制台
  16. // const lis = document.querySelectorAll("li");
  17. // lis.forEach(function (li) {
  18. // li.addEventListener("click", function () {
  19. // console.log(li.innerText);
  20. // });
  21. // });
  22. // ev:事件对象
  23. // 事件代理:用父级代理所有子元素以及更下一级的元素上的同名事件
  24. document.querySelector("ul").addEventListener("click", function (ev) {
  25. // console.log(this.tagName);
  26. // ev.target:返回的是当前正在触发事件的元素
  27. console.log(ev.target);
  28. //ev.currentTarget:返回的是事件绑定者
  29. console.log(ev.currentTarget);
  30. });
  31. </script>
  32. ```

5.下拉菜单案例

  • 页面代码
  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8" />
  5. <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  6. <title>下拉菜单</title>
  7. <style>
  8. /* 元素样式初始化: 学到盒模型再详细介绍 */
  9. * {
  10. margin: 0;
  11. padding: 0;
  12. box-sizing: border-box;
  13. }
  14. a {
  15. /* color: rgba(255, 255, 255, 0.7); */
  16. color: #bbb;
  17. text-decoration: none;
  18. }
  19. #nav {
  20. background-color: black;
  21. height: 50px;
  22. line-height: 50px;
  23. }
  24. li {
  25. list-style: none;
  26. margin: 0px 10px;
  27. float: left;
  28. }
  29. #nav > li > a:hover {
  30. color: white;
  31. }
  32. /* 将父级设置为子菜单的定位容器,即转为定位元素即可 */
  33. #nav > li {
  34. position: relative;
  35. }
  36. #nav > li > ul {
  37. position: absolute;
  38. top: 50px;
  39. width: 180px;
  40. border: 1px solid #aaa;
  41. border-top: none;
  42. }
  43. #nav > li > ul > li a {
  44. display: inline-block;
  45. height: 50px;
  46. color: #444;
  47. }
  48. ul.sub li:hover {
  49. background-color: #eee;
  50. }
  51. /* 初始化时不要显示子菜单 */
  52. #nav > li > ul {
  53. display: none;
  54. }
  55. </style>
  56. </head>
  57. <body>
  58. <ul id="nav">
  59. <li><a href="">首页</a></li>
  60. <li><a href="">视频教程</a></li>
  61. <li>
  62. <a href="">资源下载</a>
  63. <ul>
  64. <li><a href="">PHP工具</a></li>
  65. <li><a href="">在线手册</a></li>
  66. <li><a href="">学习课件</a></li>
  67. <li><a href="">网站源码</a></li>
  68. </ul>
  69. </li>
  70. <li><a href="">社区问答</a></li>
  71. <li>
  72. <a href="">技术文章</a>
  73. <ul>
  74. <li><a href="">头条</a></li>
  75. <li><a href="">博客</a></li>
  76. <li><a href="">PHP教程</a></li>
  77. <li><a href="">PHP框架</a></li>
  78. </ul>
  79. </li>
  80. </ul>
  81. </body>
  82. <script>
  83. // 获取所有主导航
  84. const navs = document.querySelectorAll("#nav > li");
  85. navs.forEach(function (nav) {
  86. // 鼠标移入时:显示子菜单
  87. nav.addEventListener("mouseover", showSubMenu);
  88. nav.addEventListener;
  89. // 鼠标移出时:关掉子菜单
  90. nav.addEventListener("mouseout", closeSubMenu);
  91. });
  92. // 显示子菜单
  93. function showSubMenu(ev) {
  94. // console.log(ev.target);
  95. //当前这个导航有没有子菜单?
  96. if (ev.target.nextElementSibling !== null) {
  97. ev.target.nextElementSibling.style.display = "block";
  98. }
  99. }
  100. // 关掉子菜单
  101. function closeSubMenu(ev) {
  102. if (ev.target.nodeName === "A" && ev.target.nextElementSibling !== null) {
  103. ev.target.nextElementSibling.style.display = "none";
  104. }
  105. }
  106. </script>
  107. <!-- 链接 + 无序列表 + 事件监听 +事件委托 -->
  108. </html>
  • 运行结果
    下拉导航菜单

6. 总结

  • 链接 A 标签常用 5 种方式:访问网站、发邮箱、打电话、下载、锚点
  • 列表,工作中更多的用无序列更多和自定义列表
  • 相对定位:元素相对于自己在文档流中的原始位置进行偏移;
  • 绝对定位:绝对定位一定要有一个定位父级做为定位参照物,否则就相对于 body 进行定位
  • 元素的定位: 元素默认在页面中是按文档流的顺序进行排列的
  • 文档流: 元素的排列按照书写顺序,源码中的顺序
  • 事件中 ev:事件对象 ev.target:返回的是当前正在触发事件的元素 ev.currentTarget:返回的是事件绑定者
  • 事件冒泡:由内向外 事件捕获:由外向内
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议
JKY辉哥2020-06-15 11:31:181楼
好的,朱老师,我一定会多动手练习的