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

   <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. C# Barrier 实现

    当您需要一组任务并行地运行一连串的阶段,但是每一个阶段都要等待所有其他任务都完成前一阶段之后才能开始,你一通过Barrier实例来同步这一类协同工作.Barrier初始化后,将等待特定数量的信号到来, ...

  2. vue把localhost改成ip地址无法访问—解决方法

    打开package.json文件,找到下面的代码 "scripts": { "dev": "webpack-dev-server --inline - ...

  3. python接口自动化测试(四)-Cookie&Sessinon

    掌握了前面几节的的内容,就可以做一些简单的http协议接口的请求发送了,但是这些还不够.HTTP协议是一个无状态的应用层协议,也就是说前后两次请求是没有任何关系的,那如果我们测试的接口之前有相互依赖关 ...

  4. mysql百分比显示

    select doll_name, type, value concat( left(get /(get+ fall)*100, 5), '%') as 抓取概率 from doll_conf

  5. PHP异步扩展Swoole笔记(1)

    安装Swoole扩展 通过pecl安装, 系统中最好已经有http2依赖, 如果是Ubuntu, 可以直接通过apt安装nghttp2, 如果是Centos或者需要自己编译, 在Github下载ngh ...

  6. python3 + flask + sqlalchemy +orm(2):数据库中添加表

    往数据库中添加一张保存文章的表,表明为article,字段有id,title,content 同样一个配置文件:config.py DEBUG = True #dialect+driver://roo ...

  7. 前端学习-jQuery

    老师博客:https://www.cnblogs.com/yuanchenqi/articles/6070667.html day43,day44 jquery 中文文档:http://jquery. ...

  8. 关于在最新的 Visual Studio 2017 版本中使用 Web Deploy 遇到的 SSL 连接错误

    错误信息: 无法完成向远程代理 URL 发送请求.请求被中止: 未能创建 SSL/TLS 安全通道. 原因分析: 最新版本的 Visual Studio 中,已经抛弃了 https 协议中旧版 SSL ...

  9. php生成毫秒时间戳的例子

    php时间函数time()生成当前时间的秒数,但是在一些情况下我们需要获取当前服务器时间和GMT(格林威治时间)1970年1月0时0分0秒的毫秒数,与Java中的currentTimeMilis()函 ...

  10. (10) 如何MySQL读压力大的问题

    如何进行读写分离 由开发人员根据所执行的SQL类型连接不同的服务器 由数据库中间层实现读写分离 读写分离时,需要注意,对于实时性要求比较高的数据,不适合在从库上查询(因为主从复制存在一定延迟(毫秒级) ...