JS事件(补充)
事件冒泡
在触发事件时候 会一层一层向上冒泡 (他同时会触发父类的事件)
阻止事件冒泡 意思就是阻止事件的向上传递
在点击div里面的按钮时 会触发div的点击事件 事件冒上去了
<head>
<style>
div{
width: 300px;
height: 300px;
background-color: red;
}
</style>
</head>
<body>
<div id="bigBox">
<div id="box">
<button id="btn">按钮</button>
</div>
</div>
</body>
阻止事件向上冒泡 stopPropagation这个方法可以阻止事件冒泡 且他遵从w3c规则 (兼容各大浏览器 ie9之前不兼容)
e.stopPropagation();
ie浏览器的阻止事件冒泡 利用了一个属性 cancelBubble 设置为true 他也兼容各大浏览器(不遵从w3c规范 未来这个属性可能没有用)
e.cancelBubble = true //取消冒泡 不建议写这种
建议的写法
var box = document.getElementById('box')
var btn = document.getElementById('btn')
var bigBox = document.getElementById('bigBox')
box.onclick = function(){
console.log('大盒子被点击了');
}
btn.onclick = function(e){
//得到事件源对象
e = e || window.event
if(e.stopPropagation){ //如果浏览器可以使用
e.stopPropagation() //就使用这个
}else{
e.cancelBubble = true //如果不能使用就使用这个
}
console.log('按钮被点击了');
}
bigBox.onclick = function(){
console.log('外面的大盒子被点击了');
}
默认行为
a标签默认会跳转页面
<body>
<a href="http://www.baidu.com">a标签</a>
<script>
document.getElementsByTagName('a')[0].onclick = function (e) {
console.log('点击了');
//return false 阻止默认行为 遵从w3c但是ie9浏览器之前不支持(常用的)
// return false
// ie浏览器 兼容 其他浏览器也可以使用
// e.preventDefault() //阻止默认事件
//针对低版本浏览器
e.returnValue = false
}
</script>
</body>
练习
一个盒子里面有俩个小盒子 右键点击第一个小盒子换颜色 右键点击第二个小盒子 变内容 点击大盒子改字体颜色
<head>
<style>
#bigbox{
height: 100px;
background-color: yellow;
}
</style>
</head>
<body>
<div id="bigbox">
<div>第一个盒子</div>
<div>第二个盒子</div>
</div>
<!-- 一个盒子里面有俩个小盒子 右键点击第一个小盒子换颜色 右键点击第二个小盒子 变内容 点击大盒子改字体颜色 -->
<script>
var bigbox = document.getElementById('bigbox')//获取大盒子
var smalls = bigbox.children //获取里面的子元素
bigbox.onmousedown = function(){
this.style.color = 'red'
}
smalls[0].onmousedown = function(e){
//表示e.stopPropagation可以使用的话 就调用stopPropagation方法
e.stopPropagation?e.stopPropagation():e.cancelBubble = true
if(e.button == 2){
this.style.backgroundColor = 'red'
}
}
smalls[1].onmousedown = function(e){
//表示e.stopPropagation可以使用的话 就调用stopPropagation方法
e.stopPropagation?e.stopPropagation():e.cancelBubble = true
if(e.button == 2){
this.innerText = '我是改了的内容'
}
}
//事件 右键出现菜单 oncontextmenu的事件
document.oncontextmenu = function(e){
//return false 后面的内容不会执行 return false一般放在最后一句
//如果第一个可以用就用第一个 不可以使用第二个
e.preventDefault?e.preventDefault():e.returnValue = false
}
</script>
</body>
offset家族
关于element元素的offset家族 偏移
e.offsetX 获取鼠标偏移的x坐标 离对应的元素
<head>
<style>
.box{
width: 500px;
height: 500px;
background-color: black;
position: absolute;
left: 100px;
}
.innerBox{
width: 300px;
height: 300px;
background-color: pink;
position: absolute;
left: 100px;
}
.smallBox{
width: 100px;
height: 100px;
background-color: yellow;
position: absolute;
left: 50px;
top: 100px;
}
</style>
</head>
<body>
<div class="box">
<div class="innerBox">
<div class="smallBox"></div>
</div>
</div>
</body>
偏移的父元素
在没有给innerBox加定位之前获取的是body
在给innerBox加了定位之后获取的是innerBox
是获取偏移的父元素 上级元素谁加了定位我就找谁 都没有加找body offsetParent有奶便是娘(谁加了定位我就找谁)
offsetParent不会找自己 找离自己近的且加了定位的
var smallBox = document.querySelector('.smallBox')
console.log(smallBox.offsetParent);
//获取自己的偏移量 基于offsetParent 离左边的距离和离上面的距离
console.log(smallBox.offsetLeft); //获取元素的左偏移量
console.log(smallBox.offsetTop); //获取元素的上偏移量
//获取自己的 width 和 height
console.log(smallBox.offsetWidth);
console.log(smallBox.offsetHeight);
基础拖拽
实现拖拽
鼠标按下去 然后移动 就会跟着动 鼠标松开不动了
鼠标按下 onmousedown 鼠标移动 onmousemove 鼠标松开 onmouseup
offset家族的内容 只能读取不能设置
<head>
<style>
#box{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
</style>
</head>
<body>
<div class="bigBox">
<div id="box"></div>
</div>
<script>
var box = document.getElementById('box')
box.onmousedown = function(){
box.onmousemove = function(e){
e = e || window.event
//获取鼠标的位置
var mouseX = e.pageX
var mouseY = e.pageY
//中心点要减去的宽高
var w = box.offsetWidth/2
var h = box.offsetHeight/2
//定位设置left值以及top值
var left = mouseX - w //鼠标坐标-原本的宽度的一半 //在内部的坐标
var top = mouseY - h
this.style.left = left+'px'
this.style.top = top+'px'
}
}
//鼠标弹起事件
box.onmouseup = function(){
box.onmousemove = function(){
}
}
</script>
</body>
在一定区域拖拽
<head>
<style>
#box{
width: 100px;
height: 100px;
background-color: red;
position: absolute;
}
.bigBox{
width: 500px;
height: 500px;
position: absolute;
left: 300px;
background-color: yellow;
}
</style>
</head>
<body>
<div class="bigBox">
<div id="box"></div>
</div>
<script>
var box = document.getElementById('box')
var bigBox = document.getElementsByClassName('bigBox')[0]
box.onmousedown = function(){
box.onmousemove = function(e){
e = e || window.event
// 获取大盒子的偏移
var bigx = bigBox.offsetLeft
var bigy = bigBox.offsetTop
//获取鼠标的位置
var mouseX = e.pageX
var mouseY = e.pageY
//中心点要减去的宽高
var w = box.offsetWidth/2
var h = box.offsetHeight/2
//定位设置left值以及top值
var left = mouseX - w - bigx //鼠标坐标-原本的宽度的一半-大盒子的偏移量 //在内部的坐标
var top = mouseY - h - bigy
this.style.left = left+'px'
this.style.top = top+'px'
//里面的盒子的偏移
var x = box.offsetLeft
var y = box.offsetTop
//区间设置
if(x<0){
this.style.left = '0px'
}
if(y<0){
this.style.top = '0px'
}
//x y最大区间设置
if(x>bigBox.offsetWidth-w*2){
this.style.left = bigBox.offsetWidth-w*2 +'px'
}
if(y>bigBox.offsetHeight-h*2){
this.style.top = bigBox.offsetHeight-h*2 + 'px'
}
}
}
//鼠标弹起事件
box.onmouseup = function(){
box.onmousemove = function(){
}
}
</script>
</body>
事件监听
事件监听是对应的一个事件监听器给到对应的元素
我们可以通过添加事件监听器给到某个元素 来给他绑定事件
<body>
<div>
123
</div>
<button onclick="remove()">移除div事件监听</button>
<script>
var div = document.getElementsByTagName('div')[0]
//常用方式
// div.onclick = function(){
// console.log('hello');
// }
//添加事件监听 参数1为事件名 参数2为对应执行的方法
var fn = function(){
console.log('hello world');
}
div.addEventListener('click',fn)
//function是对象 引用数据类型 function声明一个函数 上面的是一个函数对象 下面的又是一个函数对象
//这个俩个对象并不相等 这个是独立的俩个对象 直接在里面写function是没有办法移除的
function remove(){
//移除事件监听 参数1为事件名 参数2 执行的方法
div.removeEventListener('click',fn)
}
//关于浏览器兼容问题 针对ie8以下的浏览器
// box.attachEvent("onclick", fn); //添加事件
// box.detachEvent("onclick", fn); //移除事件
//完整兼容写法
//添加的写法
// if(box.addEventListener){
// //事件是否捕捉 默认为false 为事件冒泡
// box.addEventListener('click',fn,false)
// }else{
// box.attachEvent("onclick", fn);
// }
function addEvent(element,type,fn){
if(element.addEventListener){
//事件是否捕捉 默认为false 为事件冒泡
element.addEventListener(type,fn,false)
}else{
element.attachEvent("on"+type, fn);
}
}
//移除的写法
// if(box.removeEventListener){
// //事件是否捕捉 默认为false 为事件冒泡
// box.removeEventListener('click',fn)
// }else{
// box.detachEvent("onclick", fn);
// }
function removeEvent(element,type,fn){
if(element.addEventListener){
//事件是否捕捉 默认为false 为事件冒泡
element.addEventListener(type,fn,false)
}else{
element.attachEvent("on"+type, fn);
}
}
</script>
</body>
事件委托
事件委托机制就是将自己要加的事件加给父元素(当子元素很多的时候)
<body>
<ul id="box">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
<script>
// 点击li打印里面的值 给li添加点击事件
//利用事件委托机制我给ul添加
var box = document.getElementById('box')
box.onclick = function(e){
//通过e.target找到你点击的目标元素 来进行操作
console.log(e.target.innerText);//目标元素
init()
e.target.style.backgroundColor = 'red'
}
function init(){
var lis = box.children
for(var i=0;i<box.childElementCount;i++){
// console.log(i);
lis[i].style.backgroundColor = ''
}
}
</script>
</body>
获取事件的兼容
使用style属性 只能获取style属性内部的内容(只能获取内嵌的样式) 是不能获取对应的内联样式的
js的style属性只能操作内嵌的
getComputedStyle方法是可以获取对应的设置所有样式
<head>
<style>
#box{
color: red;
}
</style>
</head>
<body>
<div id="box">
123
</div>
</body>
获取样式 getComputedStyle获取样式 支持ie9及其他浏览器 参数1为element 参数为string 可省略
var box = document.getElementById("box")
var boxStyle = window.getComputedStyle(box)
//样式对象 里面的属性 获取字体样式
console.log(boxStyle.color);
// ie8以前的浏览器 currentStyle 获取样式
var style = box.currentStyle
console.log(style);
常用方式 解决兼容
if (window.getComputedStyle) {
style = window.getComputedStyle(box, null); //支持IE9+及非IE浏览器
} else {
style = box.currentStyle; // IE8及以前
}
//使用三元运算符
var style = window.getComputedStyle?window.getComputedStyle(box):box.currentStyle
var boxStyle = window.getComputedStyle(box)
//样式对象 里面的属性 获取字体样式
console.log(boxStyle.color);
// ie8以前的浏览器 currentStyle 获取样式
var style = box.currentStyle
console.log(style);
##### 常用方式 解决兼容
```js
if (window.getComputedStyle) {
style = window.getComputedStyle(box, null); //支持IE9+及非IE浏览器
} else {
style = box.currentStyle; // IE8及以前
}
//使用三元运算符
var style = window.getComputedStyle?window.getComputedStyle(box):box.currentStyle