博客列表 >运用CSS定位和JS事件来编写实用二级下拉菜单

运用CSS定位和JS事件来编写实用二级下拉菜单

知行合一
知行合一原创
2020年06月22日 17:08:261007浏览

二级下拉菜单在网站中应用非常广泛,这次我们利用CSS和原生Js来编写一个实用的二级下拉菜单。主要应用到的技术有CSS的定位,列表项和JS事件。

CSS定位

四种定位方式
static:定位的默认值。
relative:相对定位,相对于原来位置。(用的较多)
absolute:相对于有定位的父级元素或更上级元素进行定位。(用的较多)
fixed:相对于视窗本身进行固定定位。

javascript事件

针对JS事件本人做了三个页面来学习这块内容。

事件与事件监听

  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. </head>
  8. <body>
  9. <!--事件属性-->
  10. <button onclick="console.log(this.innerText)">按钮1</button>
  11. <button>按钮2</button>
  12. <button>按钮3</button>
  13. <!--事件属性只有最后一次是有效的 同名事件刚覆盖-->
  14. <script>
  15. // querySelector() 方法仅仅返回匹配指定选择器的第一个元素。如果你需要返回所有的元素,请使用 querySelectorAll() 方法替代
  16. document.querySelectorAll("button")[1].onclick = function () {
  17. console.log("第一次点击");
  18. };
  19. document.querySelectorAll("button")[1].onclick = function () {
  20. console.log("第二次点击");
  21. };
  22. //事件监听器 可以给一个元素多次添加同一个事件,
  23. //并且可以自定义事件的出发阶段
  24. const btn3 = document.querySelectorAll("button")[2];
  25. btn3.addEventListener("click", function () {
  26. console.log("第一次点击");
  27. });
  28. btn3.addEventListener("click", function () {
  29. console.log("第二次点击");
  30. });
  31. </script>
  32. </body>
  33. </html>

事件触发阶段

  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. </head>
  8. <body>
  9. <div>
  10. <li><a href="">事件触发阶段</a></li>
  11. </div>
  12. <script>
  13. const body = document.querySelector("body");
  14. //也可以这样写 document.body;
  15. const div = document.querySelector("div");
  16. const li = document.querySelector("li");
  17. const a = document.querySelector("a");
  18. // a.addEventListener("click", showTagName,false);
  19. //第三个值false是默认值,不写也可默认就是冒泡。如果是True,则是由外至内的捕获
  20. // a.addEventListener("click", showTagName);
  21. // li.addEventListener("click", showTagName);
  22. // div.addEventListener("click", showTagName);
  23. // body.addEventListener("click", showTagName);
  24. a.addEventListener("click", showTagName, true);
  25. li.addEventListener("click", showTagName, true);
  26. div.addEventListener("click", showTagName, true);
  27. body.addEventListener("click", showTagName, true);
  28. function showTagName() {
  29. alert(this.tagName);
  30. }
  31. </script>
  32. </body>
  33. </html>

事件代理与事件委托

  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>Document</title>
  7. </head>
  8. <body>
  9. <ul>
  10. <li>项目1</li>
  11. <li>项目2</li>
  12. <li>项目3</li>
  13. <li>项目4</li>
  14. <li>项目5</li>
  15. <li>项目6</li>
  16. <li>项目7</li>
  17. <li>项目8</li>
  18. <li>项目9</li>
  19. <li>项目10</li>
  20. </ul>
  21. <script>
  22. const lis = document.querySelectorAll("li");
  23. //forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。
  24. // lis.forEach(function (li) {
  25. // li.addEventListener("click", function () {
  26. // console.log(li.innerText);
  27. // });
  28. // });
  29. // for (var i = 0; i <= lis.length; i++) {
  30. // lis[i].addEventListener("click", function () {
  31. // console.log(this.innerText);
  32. // });
  33. // }
  34. //ev 事件对象
  35. //事件代理,用父级代理子元素以及更下一级的元素上的同名事件
  36. // document.querySelector("ul").addEventListener("click", function (ev) {
  37. // console.log(this.tagName);
  38. // });
  39. //Event 对象 简写ev
  40. //Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
  41. document.querySelector("ul").addEventListener("click", function (ev) {
  42. console.log(ev.target);
  43. });
  44. //event.target 返回事件的目标节点(触发该事件的节点)
  45. document.querySelector("ul").addEventListener("click", function (ev) {
  46. console.log(ev.currentTarget);
  47. });
  48. ////event.currentTarget 返回的是事件绑定者
  49. </script>
  50. </body>
  51. </html>

下拉菜单代码如下

  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>Document</title>
  7. <style>
  8. * {
  9. padding: 0;
  10. margin: 0;
  11. list-style: none;
  12. }
  13. a {
  14. text-decoration: none;
  15. color: tomato;
  16. }
  17. #nav {
  18. background-color: black;
  19. height: 50px;
  20. line-height: 50px;
  21. }
  22. #nav > li {
  23. display: block;
  24. width: 150px;
  25. float: left;
  26. margin-right: 30px;
  27. position: relative;//父元素相对定位
  28. text-align: center;
  29. }
  30. #nav > li > a:hover {
  31. color: yellow;
  32. }
  33. #nav > li > ul {
  34. position: absolute; //绝对定位,相对于有相对定位的父LI定位
  35. top: 50px;
  36. width: 150px;
  37. display: none;
  38. }
  39. #nav > li > ul li {
  40. height: 40px;
  41. border-bottom: 1px solid white;
  42. line-height: 40px;
  43. text-align: center;
  44. background-color: rgba(0, 0, 0, 0.8);
  45. }
  46. #nav > li > ul li:hover {
  47. background-color: rgba(0, 0, 0, 0.6);
  48. }
  49. </style>
  50. </head>
  51. <body>
  52. <ul id="nav">
  53. <li><a href="">网站首页</a></li>
  54. <li>
  55. <a href="">国内景点</a>
  56. <ul>
  57. <li><a href="">故宫</a></li>
  58. <li><a href="">长城</a></li>
  59. <li><a href="">后海</a></li>
  60. <li><a href="">颐和园</a></li>
  61. </ul>
  62. </li>
  63. <li>
  64. <a href="">国外景点</a>
  65. <ul>
  66. <li><a href="">金字塔</a></li>
  67. <li><a href="">圣母院</a></li>
  68. <li><a href="">埃菲尔铁塔</a></li>
  69. <li><a href="">自由女神</a></li>
  70. </ul>
  71. </li>
  72. <li>
  73. <a href="">中国名人</a>
  74. <ul>
  75. <li><a href="">秦始皇</a></li>
  76. <li><a href="">孔子</a></li>
  77. <li><a href="">李白</a></li>
  78. <li><a href="">杜甫</a></li>
  79. </ul>
  80. </li>
  81. <li>
  82. <a href="">世界名人</a>
  83. <ul>
  84. <li><a href="">亚历山大</a></li>
  85. <li><a href="">拿破仑</a></li>
  86. <li><a href="">俾斯麦</a></li>
  87. <li><a href="">斯大林</a></li>
  88. </ul>
  89. </li>
  90. </ul>
  91. <script>
  92. const navs = document.querySelectorAll("#nav>li");
  93. navs.forEach(function (nav) {
  94. nav.addEventListener("mouseover", showSubMenu);
  95. nav.addEventListener("mouseout", closeSubMenu);
  96. });
  97. function showSubMenu(ev) {
  98. // console.log(ev.target);
  99. // 当前这个导航有没有子菜单?
  100. if (
  101. //ev.target.nodeName === "A" &&
  102. //这里加上面判断的话,必须鼠标在A标签上才可显示。鼠标在LI上显示不了
  103. ev.target.nextElementSibling !== null
  104. ) {
  105. ev.target.nextElementSibling.style.display = "block";
  106. }
  107. }
  108. function closeSubMenu(ev) {
  109. if (
  110. ev.target.nodeName === "A" && //这里必须加判断,要不移动到其它LI标签上就会消失。因为冒泡
  111. ev.target.nextElementSibling !== null
  112. ) {
  113. ev.target.nextElementSibling.style.display = "none";
  114. }
  115. }
  116. </script>
  117. </body>
  118. </html>

展示效果如下

二级下拉菜单

制做二级菜单总结如下

  • 在学习过程中,有很多不明白的地方,多看视频教程。
  • 不懂的知识点,参数、名字等多百度搜索一下。
  • 多写几遍代码,多写注释。
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议