事件冒泡,在冲突的时候要阻止
当在 子元素 与父元素同事添加onclick事件时, 注意考虑事件冒泡的情况
例如:子元素的onclick事件执行了隐藏某个元素的事件,但父元素的onclick执行了显示这个元素的事件、当触发事件冒泡时,浏览器会先触发子元素的onclick 再 触发 父元素的onclick 就会把这个元素先隐藏又显示了、就会看不到js执行效果
添加事件:
li 上添加 onmouseover事件,控制鼠标滑过时li的背景颜色
li 上添加 onclick 事件,隐藏 ul列表,更换qq面板上状态栏的文本以及状态栏的图标
第四章节听不懂,需要重新学习和多练习
重点:注意需要阻止冒泡和不需要阻止冒泡的情况
kk
//封装函数,通过className获取需要的元素数组
function getByClass(clsName,parent){
var oParent=parent?document.getElementById(parent):document,
eles=[],
elements=oParent.getElementsByTagName('*');
for(var i=0,l=elements.length;i<l;i++){
if(elements[i].className==clsName){
eles.push(elements[i]);
}
}
return eles;
}
window.onload=drag;
function drag(){
//拖拽
var oTilte=getByClass('login_logo_webqq','loginPanel')[0];
oTilte.onmousedown=fnDown;
//关闭
var oClose=document.getElementById('ui_boxyClose');
oClose.onclick=function(){
document.getElementById('loginPanel').style.display='none';
}
//切换状态
//根据功能目标,分析html结构,设置步骤方法,先取出必须元素
var loginState=document.getElementById('loginState'),
stateList=document.getElementById('loginStatePanel'),
lis=stateList.getElementsByTagName('li'),
statetTxt=document.getElementById('login2qq_state_txt'),
loginStateShow=document.getElementById('loginStateShow');
// 先设置点击显示状态列表,并对点击事件设置阻止冒泡,防止冒泡到document层的点击关闭列表功能
loginState.onclick=function(e){
e=e || window.event;
if(e.stopPropagation){
e.stopPropagation();
}else {
e.cancleBubble=true;
}
stateList.style.display='block';
}
//光标滑过、离开和点击状态列表效果
//使用for遍历循环,为每个li添加事件
for (var i = 0,l=lis.length; i < l; i++) {
//滑过
lis[i].onmouseover=function(){
this.style.background='#567';
}
//离开
lis[i].onmouseout=function(){
this.style.background='#fff';
}
//点击,先隐藏列表、阻止冒泡(否则会冒泡到loginState.onclick事件)
lis[i].onclick=function(e){
//点击到哪个li就获取哪个li的id
var id=this.id;
e=e || window.event;
if(e.stopPropagation){
e.stopPropagation();
}else {
e.cancleBubble=true;
}
stateList.style.display='none';
//并替换指定className,使用之前的函数封装
statetTxt.innerHTML=getByClass('stateSelect_text',id)[0].innerHTML;
//注意保留的className后的空格
loginStateShow.className='login-state-show '+id;
}
}
//实现点击窗口任意地方都可关闭状态列表,为防止冒泡冲突loginState.onclick事件需要阻止冒泡
document.onclick=function(){
stateList.style.display='none';
}
}
function fnDown(event){ //此event为onmousedown触发,携带光标clientXY参数
event=event || window.event;
var oDrag=document.getElementById('loginPanel'),
//计算出onmousedown时光标与面板之间的水平垂直距离
disX=event.clientX-oDrag.offsetLeft,
disY=event.clientY-oDrag.offsetTop;
//移动
document.onmousemove=function(event){ //此event为onmousemove触发
event=event || window.event;
fnMove(event,disX,disY);//为下一步进行封装
}
//释放
document.onmouseup=function(){
document.onmousemove=null;//光标释放直接将onmousemove赋值null,清空
document.onmouseup=null;//在清空自身,不浪费资源,防止与其他的onmouseup冲突
}
}
function fnMove(e,posX,posY){
var oDrag=document.getElementById('loginPanel'),
l=e.clientX-posX,//光标距离 减去 光标与面板之间的距离 等于面板实际定位距离
t=e.clientY-posY,//可以保证光标与面板的相对位置不变的情况下拖拽面板
winW=document.documentElement.clientWidth || document.body.clientWidth,//窗口的宽度,后者为IE兼容
winH=document.documentElement.clientHeight || document.body.clientHeight,//窗口的高度
maxW=winW-oDrag.offsetWidth-10,//避免面板拖出窗口,限定拖拽最大距离(减10是因为面板关闭按钮盒子使用了绝对定位,拖拽时会被边框遮挡)
maxH=winH-oDrag.offsetHeight;//用窗口宽高减去面板宽高即可得到
//进行距离判断,固定上下限
if(l<0){
l=0;
}else if(l>maxW){
l=maxW;
}
//因为关闭按钮在面板顶部,所以最小值改为其绝对定位位移的相反值
if(t<10){
t=10;
}else if(t>maxH){
t=maxH;
}
oDrag.style.left=l+'px';
oDrag.style.top=t+'px';
}
1.首先分析实现原理;然后分析要取出的对象,进行取出;再给对象绑定事件;
2.分析各种事件,并对其件进行函数封装;
3.块的里面的文字(状态、下)不见了:用负缩进把他们搞到窗口之外了,当代码注释使用。
4.在适当的地方阻止事件冒泡:
ul父元为div,点击li时希望ul隐藏,点击div时希望其显示,在点击li后会冒泡到div ,因而需要阻止冒泡;
注意区分onmousedown和onclick,只能阻止相对应类型事件。
重点:利用事件冒泡实现切换状态菜单;当一个块内包含众多事件时,必须要注意到事件冒泡的影响。
5.在其他任何地方点击,要使列表隐藏:document.onclick是代表在页面的任何地方点击事件。
document下的子元素还有一个onclick事件,所以要注意事件冒泡的影响;