1、css中的定位:
css样式中的定位大致有4种:静态定位,相对定位,绝对定位,固定定位。
静态定位(position:static)
一般的标签元素不加任何定位属性都属于静态定位,在页面的最底层属于 标准流。相对定位(position:relative)
相对定位元素不可层叠,依据left、right、top、bottom等属性在正常文档流中偏移自身位置。绝对定位(position:absolute)
如果它的父元素设置了除static之外的定位,比如position:relative或position:absolute及position:fixed,那么它就会相对于它的父元素来定位,位置通过left , top ,right ,bottom属性来规定,如果它的父元素没有设置定位,那么就得看它父元素的父元素是否有设置定位,如果还是没有就继续向更高层的祖先元素类推,总之它的定位就是相对于设置了除static定位之外的定位的第一个祖先元素,如果所有的祖先元素都没有以上三种定位中的其中一种定位,那么它就会相对于文档body来定位(并非相对于浏览器窗口,相对于窗口定位的是fixed)。固定定位(position:fixed)
相对于浏览器窗口定位,并且不会随着滚动条进行滚动。
2、冒泡与捕捉,事件代理
冒泡与捕捉
捕获型事件(event capturing):事件从最不精确的对象(document 对象)开始触发,然后到最精确(也可以在窗口级别捕获事件,不过必须由开发人员特别指定)。当某个元素触发某个事件(如onclick),顶层对象document就会发出一个事件流,随着DOM树的节点向目标元素节点流去,直到到达事件真正发生的目标元素。在这个过程中,事件相应的监听函数是不会被触发的。
冒泡型事件:事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。就是事件从最深的节点开始,然后逐步向上传播事件,举个例子:页面上有这么一个节点树,div>ul>li>a;比如给最里面的a加一个click点击事件,那么这个事件就会一层一层的往外执行,执行顺序a>li>ul>div,有这样一个机制,那么我们给最外面的div加点击事件,那么里面的ul,li,a做点击事件的时候,都会冒泡到最外层的div上,所以都会触发。
事件触发阶段类型 |
特征 |
参数设置 |
冒泡 |
由内向外传递 |
addEventListener(事件类型,事件方法,false),最后一个参数可省略,默认就是冒泡方法 |
捕获 |
由外向内传递 |
addEventListener(事件类型,事件方法,true) |
为什么要用事件代理
在JavaScript中,添加到页面上的事件处理程序数量将直接关系到页面的整体运行性能,因为需要不断的与dom节点进行交互,访问dom的次数越多,引起浏览器重绘与重排的次数也就越多,就会延长整个页面的交互就绪时间,这就是为什么性能优化的主要思想之一就是减少DOM操作的原因;每个函数都是一个对象,是对象就会占用内存,对象越多,内存占用率越大,100个li就要占用100个内存空间。如果要用事件委托,就会将所有的操作放到js程序里面,只对它的父级(如果只有一个父级)这一个对象进行操作,与dom的操作就只需要交互一次,这样就能大大的减少与dom的交互次数,提高性能;
事件委托是利用事件的冒泡原理来实现的。事件监听
在不使用任何框架的情况下,我们在js中通过addEventListener方法给Dom添加事件监听。这个方法有三个参数可以传递addEventListener(event,fn,useCapture)。event是事件类型click,focus,blur等;fn是事件触发时将执行的函数方法(function);第三个参数可以不传,默认是false,这个参数控制是否捕获触发。所以我们只穿两个参数时,这个事件是冒泡传递触发的,当第三个参数存在且为true时,事件是捕获传递触发的。
3、鼠标经过事件实现下拉菜单
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>滑动样式</title>
<style>
*{
margin: 0;
padding: 0;
}
a{
text-decoration: none;
}
body{
display:static;
}
.header{
width: 100%;
background: #000;;
}
.content{
margin: 0 auto;
width: 980px;
}
ul,dl{
list-style: none;
}
ul.nav::after{
content: '';
display: block;
width: 100%;
clear: both;
}
.nav>li{
padding: 0px 20px;
float: left;
cursor: pointer;
position: relative;
}
.nav>li a{
line-height: 80px;
color: #fff;
}
.nav>li:hover{
background-color: #363c41;
}
.nav-active{
background-color: #363c41;
}
.nav-li-chlid{
display: none;
position:absolute;
top: 80px;
left: 0px;
width: 200px;
color: #363c41;
background-color: #fff;
box-shadow:0 2px 4px rgba(0,0,0,.12);
border: rgba(0,0,0,.12) 1px solid;
animation-name: navLiAnmation;
animation-duration: 0.3;
animation-fill-mode: both;
}
.nav-li-chlid>dd{
float: left;
padding: 10px;
text-align: center;
box-sizing: border-box;
display: inline-block;
width: 50%;
}
.nav-li-chlid>dd a{
line-height: 30px;
color: #363c41;
}
@keyframes navLiAnimation {
0%{
transform: translate3d(0,30px,0);
opacity: .3;
}
100%{
transform: translate3d(0,0,0);
opacity: 1;
}
}
</style>
</head>
<body>
<div class="header">
<ul class="nav content">
<li>
<a href="">首页</a>
</li>
<li>
<a href="">入门教程</a>
</li>
<li>
<a href="">社区问答</a>
<dl class="nav-li-chlid">
<dd>
<a>社区问答</a>
</dd>
<dd>
<a>社区问答</a>
</dd>
<dd>
<a>社区问答</a>
</dd>
<dd>
<a>社区问答</a>
</dd>
<dd>
<a>社区问答</a>
</dd>
<dd>
<a>头条</a>
</dd>
</dl>
</li>
<li>
<a href="">技术文章</a>
<dl class="nav-li-chlid">
<dd>
<a>技术文章</a>
</dd>
<dd>
<a>技术文章</a>
</dd>
<dd>
<a>技术文章</a>
</dd>
<dd>
<a>技术文章</a>
</dd>
<dd>
<a>头条</a>
</dd>
<dd>
<a>头条</a>
</dd>
</dl>
</li>
<li>
<a href="">资料下载</a>
<dl class="nav-li-chlid">
<dd>
<a>资料下载</a>
</dd>
<dd>
<a>资料下载</a>
</dd>
<dd>
<a>资料下载</a>
</dd>
<dd>
<a>资料下载</a>
</dd>
<dd>
<a>资料下载</a>
</dd>
<dd>
<a>资料下载</a>
</dd>
</dl>
</li>
<li>
<a href="">php培训</a>
<dl class="nav-li-chlid">
<dd>
<a>php培训</a>
</dd>
<dd>
<a>php培训</a>
</dd>
<dd>
<a>php培训</a>
</dd>
<dd>
<a>php培训</a>
</dd>
<dd>
<a>php培训</a>
</dd>
<dd>
<a>php培训</a>
</dd>
</dl>
</li>
</ul>
</div>
</body>
<script>
const navs = document.querySelectorAll('.nav > li');
navs.forEach(function(nav){
nav.addEventListener('mouseover',showSubMenu);
nav.addEventListener('mouseout',closeSubMenu)
});
// 显示子菜单
function showSubMenu(event){
console.log(event.target)
//target是指触发事件的元素,currentTarget是指绑定该触发事件的元素
//搞清楚node节点与节点元素,nextElementSibling获取到的是相邻的兄弟节点元素,nextSibling获取到的是相邻的兄弟节点
//其中通过firstChild和lastChild获得HTML Node是不可取的。因为,根据浏览器的不同,firstChild有可能返回parentObj的属性对象。
if(event.target.nextElementSibling!==null){
event.target.nextElementSibling.style.display = 'block'
}
}
// 关掉子菜单
function closeSubMenu(event){
if(event.target.nodeName==='A' && event.target.nextElementSibling!==null){
event.target.nextElementSibling.style.display = 'none'
}
}
</script>
</html>