二级菜单作为最普通小组件,我遇到了坑.

   <style>
.wrapper {
height: 150px;
border: 1px solid;
width: 150px;
} .wrapper>div {
height: 48px;
width: 150px;
border: 1px solid;
text-align: center;
line-height: 48px;
cursor: pointer;
position: relative; } .son {
display: none;
position: absolute;
left: 150px;
top: 0px;
border: 1px solid;
height: 150px;
width: 150px;
} .son>div {
height: 48px;
width: %;
text-align: center;
line-height: 48px;
cursor: pointer;
border: 1px solid;
}
</style>
</head> <body> <div class="wrapper">
<div class="father string">string
<div class="son string-son">
<!-- 为什么要设置成父子关系?????因为设成兄弟元素,mouseover事件并不能作用在son上,也就不能鼠标移到它身上时候还能有父的mouseover事件 -->
<!-- mouseover事件和mouse -->
<div>one</div>
<div>two</div>
<div>three</div>
</div>
</div>
<div class="father boolen">boolen
<div class="son boolen-son">
<div>true</div>
<div>false</div>
</div>
</div>
<div class="number father">number
<div class="son number-son">
<div></div>
<div></div>
</div>
</div>
</div>
var father = document.getElementsByClassName('father');
for (let i = ; i < father.length; i++) {
father[i].onmouseover = function(){
var son = father[i].getElementsByTagName('div')[];
son.style.display = 'block';
}
father[i].onmouseleave = function(){
var son = father[i].getElementsByTagName('div')[];
son.style.display = 'none';
}
以上的代码是可以实现效果的,鼠标移入会出现son,鼠标一出会son不见, 但是下面的就不可以了.
 
下面的鼠标一旦移动那个出father,进到son区域后,son区域会消失,也就是不可以点到son,没法用.
 
father[i].onmouseenter= function(){
var son = father[i].getElementsByTagName('div')[];
son.style.display = 'block';
}
father[i].onmouseout = function(){
var son = father[i].getElementsByTagName('div')[];
son.style.display = 'none';
}
没法用的原因是因为定义在父级上的mouseenter事件和大多数事件不一样,不会传播给儿子,我这样理解是和官方不一样的.不过不影响结果.
而mouseover事件会传播给儿子;在看一个例子就知道了:
两个父子div.父div上绑定click事件
father.onclick = function(){console.log(1111)}
然后点击子div,也会触发事件,输出1111;这官方的解释是:点击的是son,在son上触发了click事件,事件是冒泡的,会传播给父级,父级上绑定了事件函数,从而导致事件函数的执行.
 
(但是我觉得这样理解不好,因为很简单的原因:son也是father 的一部分,son上触发就等于father上触发啊,触发事件自然执行函数.这样比较容易理解.且根本不会有执行顺序上的问题,因为son上没绑定函数)
但此时你如果把click换成mouseenter,点击son它不好使了,不输出111,只有点击非son的father部分它才好使.
官方就把从son到father的事件传播叫做事件冒泡,把这种人为或者非人为的方式来达到不往上传播的手段叫做阻止事件冒泡.也就是说,mouseover事件不会向上传播,自带阻止事件冒泡的功能.
按照官方的说法,则必须把元素在页面的结构理解为:子元素一定在父元素上面,点击子元素所在父元素区域即点击子元素而非父元素,只是子元素事件大部分可以冒泡,然后达到父元素.(只有这么理解才能解释的通)
按我的理解就是,子属于父,点击子就是点击父.好比父是一个国家中国,子是他下面的省黑龙江.鼠标是美帝的炮弹,当一颗炮弹达到黑龙江,难道不是打到了中国?有点秃噜了...
 
 
这种事件冒泡会有好处,也会有坏处,好处要利用,坏处要防止发生.就行用人一样
点击实现出现二级菜单.
father[i].onclick = function (e) {
e.stopPropagation()//注意这一行
var son = document.getElementsByClassName('son');
for (var j = ; j < son.length; j++) {
if (j == i) {
son[j].style.display = 'block';
} else {
son[j].style.display = 'none'
}
}
}
}
document.onclick = function (e) {
var son = document.getElementsByClassName('son');
for (var k = ; k < son.length; k++) {
son[k].style.display = 'none'
}
}
当我们点击father时候,如果没有e.stopPropagation()这一行,现象是会不出现效果.原因是:当点击father时候,document是father的父级,即触发了document事件.
按照官方的解释:事件冒泡是有顺序的,总是子冒泡到父;点击了子,子事件绑定了函数,函数执行,在冒泡到父,父的事件上绑定了函数,则,函数又执行.最终结果,子菜单没出来.
这时候,如果想实现效果,就必须在该事件触发时,不让子事件传播到父,则需要加上那么一行:e.stopPropagation();
 
 
总之,最重要的是记住这种默认的父子结构:子总在父上面,且子总是爱将事件传给父如果不阻止的话!!!!!
 
 
 
 

做二级菜单时候遇到的关于事件冒泡以及mouseover和mouseenter的不同的更多相关文章

  1. 事件处理& 事件委托& 区别mouseover与mouseenter

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. 第十五篇 JS 移入移出事件 模拟一个二级菜单

    JS 移入移出事件 模拟一个二级菜单   老师演示一个特别简单二级菜单,同学们除了学习JS,还要注意它的元素和CSS样式. 这节课介绍的是JS鼠标移入.移出事件:onmouseover是移入事件,on ...

  3. 巨蟒django之权限7:动态生成一级&&二级菜单

    内容回顾: . 权限的控制 . 表结构设计 存权限的信息 用户表 - name 用户名 - pwd 密码 - roles 多对多 角色表 - name - permissions 多对多 权限表 - ...

  4. python 全栈开发,Day109(客户管理之动态"二级"菜单)

    昨日内容回顾 1. 权限有几张表? 2. 简述权限流程? 3. 为什么要把权限放入session? 4. 静态文件和模块文件 5. 相关技术点 - orm查询 - 去空 - 去重 - 中间件 - in ...

  5. django自定义rbac权限组件(二级菜单)

    一.目录结构 二.表结构设计 model.py from django.db import models # Create your models here. class Menu(models.Mo ...

  6. JavaScript阻止事件冒泡(兼容IE、Chrome、FF)

    这里仅仅是一个简单代码demo,因为时间问题并未做深入研究,因为今天做项目时要用到阻止事件冒泡的内容,找了好多才找到一个可以使用的,特记录之. <!DOCTYPE HTML> <ht ...

  7. 彻底弄懂JS的事件冒泡和事件捕获(不推荐阅读)

    由于搬去敌台了,好久没来博客园,今天无意中翻到有“误认子弟”的评论,这里特意做个说明. 本文中关于事件冒泡和事件捕获的描述和例子都是OK的,错就错在后面用jquery去展示了利用事件冒泡的例子有误,其 ...

  8. 用jQuery做一个三级菜单,鼠标移动到二级菜单的选项上,然后再迅速离开后,当鼠标再移动到该一级菜单或其他二级菜单选项,三级菜单也会显示。

    用jQuery做一个三级菜单,鼠标移动到二级菜单的选项上,然后再迅速离开后,当鼠标再移动到该一级菜单或其他二级菜单选项,三级菜单也会显示. 原因:在为一个元素绑定hover事件之后,用户把光标移入元素 ...

  9. Android学习笔记之横向二级菜单实现

    PS:元旦来一发. 学习内容: 1.Android二级横向菜单的实现过程.效果如上图...   这种横向的二级菜单在很多的app都有所应用.效果看起来还是非常的美观的.也算是项目需要,自己也就学了一下 ...

随机推荐

  1. Hadoop的启动和停止说明

    Hadoop的启动和停止说明   sbin/start-all.sh 启动所有的Hadoop守护进程.包括NameNode. Secondary NameNode.DataNode.ResourceM ...

  2. hive sql 常见异常

    1.union Logging initialized using configuration in file:/home/xiaoju/hadoop/apache-hive-1.2.1-bin/co ...

  3. sqlite "insert or replace" 和 "insert or ignore" 用法

    insert or replace:如果不存在就插入,存在就更新insert or ignore:如果不存在就插入,存在就忽略只对UNIQUE约束的字段起作用.举例:建表:CREATE TABLE T ...

  4. C# System.IO.StreamReader

    实现一个 TextReader,使其以一种特定的编码从字节流中读取字符. using System; using System.IO; class Test { public static void ...

  5. [C#] 解决Silverlight反射安全关键(SecuritySafeCritical)时报“System.MethodAccessException: 安全透明方法 XXX 无法使用反射访问”的问题

    作者: zyl910 一.缘由 在Silverlight中使用反射动态访问时,经常遇到"System.MethodAccessException: 安全透明方法 XXX 无法使用反射访问-- ...

  6. centos7 安装curl-7.51.0

    curl简介curl是一个广泛使用的用来上传和下载的命令行工具,当然严格来讲,它还可以有别的用途.对于测试来讲,它是Web相关测试非常实用的工具,包括debugging,使用起来非常方便.而且另一方面 ...

  7. Linux好用的工具命令 - rz/sz

    Linux系统中将本地的文件上传到服务器或者从服务器上下载文件到本地可以通过安装lrzsz工具来简单便利的完成. >>RZ :将本地的文件上传到服务器 >>SZ:从服务器上下载 ...

  8. 【iCore4 双核心板_ARM】例程二十六:LWIP_MODBUS_TCP实验——电源监控

    实验现象: 核心代码: int main(void) { system_clock.initialize(); led.initialize(); adc.initialize(); delay.in ...

  9. 在BootStrap的modal中使用Select2

      bootstrap 3 $.fn.modal.Constructor.prototype.enforceFocus = function() {}; bootstrap4 $.fn.modal.C ...

  10. [Linux]Linux下signal function传参方式

    https://stackoverflow.com/questions/6970224/providing-passing-argument-to-signal-handler This is a r ...