JavaScript事件

JavaScript事件

  • 特效是由事件触发的
  • 事件源:任何一个html元素(节点)都是一个事件源
  • 一个事件源可以添加多个事件
  • 键盘事件:keypress键盘事件,keyup抬起,keydown按下 文档:load加载 表单:focus获得焦点,blur失去焦点,submit提交事件,change改变事件 其他:scroll滚动事件,select start选择事件

2. 事件中的Event对象

  • 只要事件发生就会产生一个event事件
  • 事件发生后创建对象
  • Event 对象代表事件的状态,比如事件在其中发生的元素、键盘按键的状态、鼠标的位置、鼠标按钮的状态。
  • 事件通常与函数结合使用,函数不会在事件发生前被执行

2.1. event事件对象常见的属性和方法

事件对象属性方法说明
e.target返回触发事件的对象 标准
e.srcElement返回触发事件的对象 非标准ie6-8使用
e.type返回事件的类型,比如:click,mouseover 不带on
e.returnValue该属性阻止默认事件(默认行为) ie6-8,比如不让链接跳转
e.preventDefault()该属性阻止默认事件(默认行为)标准,比如不让链接跳转
e.stopPropagation()阻止冒泡 【标准】
e.cancelBubble阻止冒泡【ie】

2.2. 阻止默认事件的发生

补充一个知识点:点击a标签的时候,想要将默认的跳转去除掉,添加自己的跳转方式 对于a标签来说,默认的行为就是进行页面跳转,如果不想让a标签进行跳转,可以在注册事件中使用return false

<a id="link" href="http://www.baidu.com">这是a</a>
<script>
  var link = document.getElementById("link");
  link.onclick = function() {
      alert("嘻嘻"); 
      return false; //阻止页面跳转
  }
</script>

2.3. 阻止默认事件的发生

对于一些标签来说,他们拥有自己的事件,比如:a标签可以跳转,submit/button可以提交表单,reset可以重置按钮,那么如果想要给这些按钮添加事件,并且不让他执行对应的默认事件的话,就需要使用自制时间发生; 阻止默认事件的方法有两种:使用的是事件对象的方法来阻止event.stopPropagation();

  1. 如果是使用 on+事件名 或者  attachEvent() 添加的事件 使用 return false;
  2. 如果是使用 addEventListener 添加的事件 使用 event.preventDefault();
<a id="link" href="http://www.baidu.com">这是a</a>
<script>
var link = document.getElementById("link");
// 阻止方法一 
link.onclick = function() {
  alert("嘻嘻"); 
    // 取消默认事件
  return false; 
}
// 阻止方法二
link.addEventListener('click',function(event){
    var ev = event || window.event;
    alert('我在京东');
    // 取消默认事件
    ev.preventDefault();
});
</script>

将两种方法进行封装

// 封装 - 取消默认事件
function preventDef(event){
    var ev = event || window.event;
    if(ev.preventDefault){
        ev.preventDefault();
    }else{
        ev.returnValue = false;
    }
}

 2.4. 事件流-事件冒泡机制

 参考文档:https://blog.csdn.net/qq_51066068/article/details/124249346

气泡从水底开始往上升,由深到浅,升到最上面。在上升的过程中,气泡会经过不同深度层次的水。 相对应地:这个气泡就相当于我们这里的事件,而水则相当于我们的整个dom树; 事件从dom 树的底层,层层往上传递,直至传递到dom的根节点。 当子元素与父元素有相同的事件时,当子元素被触发时父元素也会被触发冒泡机制

 

在不同浏览器中,冒泡的程度不同

IE 6.0: div -> body -> html -> document

其他浏览器: div -> body -> html -> document -> window

注意:并不是所有的事件都能冒泡,以下事件不冒泡:blur、focus、load、unload

阻止冒泡的方法

标准浏览器 和 ie浏览器

w3c:event.stopPropagation()

IE:event.cancelBubble = true

兼容写法
if(event && event.stopPropagation){  // w3c标准 
  event.stopPropagation(); 
}else{  // IE系列 IE 678 
  event.cancelBubble = true; 
}
<style>
  #father{
    width: 300px;
    height: 300px;
    background-color: #f00;
    margin: auto;
  }
</style>
</head>
<body>
    <div id="father">
        <button id="btn">点击</button>
    </div>
<script>
    window.onload = function(){
        var father = document.getElementById('father');
        var btn = document.getElementById('btn');
        father.onclick = function(){
            if(event&&event.stopPropagation){ // w3c标准,阻止冒泡事件
                event.stopPropagation();
            }else{ // IE系列 ie678
                event.cancelBubble = true;
            }
            alert('father点击');
        }
        btn.onclick = function(){
            if(event&&event.stopPropagation){ // w3c标准,阻止冒泡事件
                event.stopPropagation();
            }else{ // IE系列 ie678
                event.cancelBubble = true;
            }
            alert('btn点击');
        }
        document.onclick = function(){
            alert('文档点击');
        }
    }
</script>

谁需要组织冒泡,就在对应的操作前,添加阻止冒泡事件

面试题-Javascript的事件流模型都有什么? “事件冒泡”:事件开始由最具体的元素接受,然后逐级向上传播 “事件捕捉”:事件由最不具体的节点先接收,然后逐级向下,一直到最具体的 “DOM事件流”:三个阶段:事件捕获,成为目标阶段,事件冒泡

使用addEventListener实现事件冒泡

默认冒泡顺序是从内往外进行冒泡

<style>
    .body{
        width: 100%;
        height: 100%;
        background-color: #f00;
    }
    .warp{
        width: 300px;
        height: 300px;
        background-color: #0f0;
    }
    .inner{
        width: 100px;
        height: 100px;
        background-color: #00f;
    }
</style>
<body>
    <div class="warp">
        <div class="inner"></div>
    </div>
</body>
<script>
    var inner = document.querySelector('.inner');
    var warp = document.querySelector('.warp');
    // 给按钮添加点击事件
    inner.addEventListener('click',fun2);
    function fun2(){
        console.log('inner被点击');
    }

    warp.addEventListener('click',fun1);
    function fun1(){
        console.log('warp被点击');
    }

    document.body.addEventListener('click',fun3);
    function fun3(){
        console.log('body被点击');
    }
</script>

可以通过给addEventListener添加第三个参数值,更改冒泡的顺序

useCapture=true 默认值, false. true 代表以事件捕获形式触发事件, false 代表以事件冒泡形式触发事件

<style>
    .body{
        width: 100%;
        height: 100%;
        background-color: #f00;
    }
    .warp{
        width: 300px;
        height: 300px;
        background-color: #0f0;
    }
    .inner{
        width: 100px;
        height: 100px;
        background-color: #00f;
    }
</style>
<body>
    <div class="warp">
        <div class="inner"></div>
    </div>
</body>
<script>
    var inner = document.querySelector('.inner');
    var warp = document.querySelector('.warp');
    // 给按钮添加点击事件
    inner.addEventListener('click',fun2,useCapture=true);
    function fun2(){
        console.log('inner被点击');
    }

    warp.addEventListener('click',fun1,useCapture=true);
    function fun1(){
        console.log('warp被点击');
    }

    document.body.addEventListener('click',fun3,useCapture=true);
    function fun3(){
        console.log('body被点击');
    }
</script>

2.5. 事件委托【在dom对象后面讲】

需求:只做一个鲜花网手机端购物车效果 点击能够添加一个商品,在商品上点击删除能够删除这个商品


<button>点击添加商品</button>
<div class="show">
  <p>暂时没有商品</p>
  <ul>
      <li data-index="11">老的商品1</li>
      <li data-index="12">老的商品2</li>
      <li data-index="13">老的商品3</li>
  </ul>
</div>
<style>
    *{
        margin: 0;
        padding: 0;
        list-style: none;
    }
    li{
        height: 80px;
        border: 1px solid #f00;
        margin: 10px;
    }
</style>
<script>
  var op = document.querySelector('.show p');
  var oLi = document.querySelectorAll('ul li');
  var oUi = document.querySelectorAll('ul');
  if(oUl.length==0){
      op.style.display = 'block';
  }else{
      op.style.display = 'none';
  }
  
  // 给商品添加删除功能
  for(var i=0;i<oLi.length;i++){
      oLi[i].onclick = function(){
        // console.log(this); 获取元素本身
        // console.log(this.dataset); 获取元素下面自定义的data属性
        console.log(this.dataset.index); // 获取index参数值
      }
  }
  
  // 点击按钮添加商品
  var n = 20;
  oBtn.onclick = function(){
      n++;
      // 第一种添加方案
      // oUl.innerHTML += `<li data-index=${n}>新的商品</li>`;
  
      // 第二种添加方案
      var li = document.createElement('li');
      li.setAttribute('data-index',n);
      li.innerHTML = '新商品';
      oUl.appendChild(li);
  }
  
  // 给商品添加删除功能
  // 不实用事件委托:新添加的列表没有绑定事件
  for(var i=0;i<oLi.length;i++){
    oLi[i].onclick = function(){
      // console.log(this); 获取元素本身
      // console.log(this.dataset); 获取元素下面自定义的data属性
      console.log(this.dataset.index); // 获取index参数值
    }
  }
  
  // 使用事件委托
  oUl.onclick = function(e){
      // e.currentTarget 当前绑定事件的元素
      console.log(e.currentTarget); 
      // e.target:触发事件的目标元素,不一定是当前元素,也有可能是当前元素的后代元素
      // 因为后代元素触发的事件也会冒泡从而触发当前元素的事件
      console.log(e.target); 
    
      // 判断是否是li标签
      if(e.target.tagName == 'LI'){
          console.log(e.target.parentNode.dataset.index); 
      }
  }
</script>

事件委托的优点:

1.减少事件注册,节省内存

2.在table上代理所有td的click事件

3.在ul上代理所有li的click事件

4.简化了dom节点更新时,相应事件的更新。

5.不用在新添加的li上绑定click事件

6.当删除某个li时,不用移解绑元素上的click事件【引出堆栈,内存泄漏,垃圾回收机制】

事件委托的缺点:

1.事件委托基于冒泡,对于不冒泡的事件不支持

2.层级过多,冒泡过程中,可能会被某层阻止掉

3.理论上委托会导致浏览器频繁调用处理函数,虽然很可能不需要处理。所以建议就近委托,比如在table上代理td,而不是在document上代理td。

4.把所有事件都用代理就可能会出现事件误判。比如,在document中代理了所有button的click事件,另外的人在引用改js时,可能不知道,造成单击button触发了两个click事件。

2.6. 事件封装

// 绑定事件 - 判断是否是ie浏览器
// obj-某个对象  EType - 某个事件  fun - fun函数
function addEvent(obj, EType, fun) {
  if (obj.addEventListener) {
    obj.addEventListener(EType, fun);
  } else if (obj.attachEvent) {
    obj.attachEvent("on" + EType, fun);
  } else {
    obj["on" + EType] = fun;
  }
}

// 移除元素事件
function removeEvent(obj, EType, fun) {
  if (obj.removeEventListener) {
    obj.removeEventListener(EType, fun);
  } else if (obj.detachEvent) {
    obj.detachEvent("on" + EType, fun);
  } else {
    obj["on" + EType] = null;
  }
}

// 取消默认行为
function preventDefaultFun(event) {
  if (event.preventDefault) {
    event.preventDefault();
  } else {
    event.returnValue = false;
  }
}

// 阻止事件传播
function stopPropagationFun(event) {
  if (event.stopPropagation) {
    event.stopPropagation();
  } else {
    event.cancelBubble = true;
  }
}

2.7 e.target和this的区别

区别: e.target返回的是触发事件的对象(元素) this 返回的是绑定事件的对象(元素) e.currentTarget 当前绑定事件的元素

<div class="box">box盒子</div>
<ul class="list">
    <li>列表1</li>
    <li>列表2</li>
    <li>列表3</li>
    <li>列表4</li>
</ul>
<script>
    var oBox = document.getElementsByClassName('box')[0];
    var oList = document.getElementsByClassName('list')[0];
    oBox.onclick = function(e){
      console.log(this); // div
      console.log(e.target); // div
    }
    oList.onclick = function(e){
      // e.target指向的是被点击的对象,谁触发了这个事件,就是谁,li能够拥有点击事件,是因为事件冒泡
      console.log(this);  // ul
      console.log(e.target); // li
    }
</script>

3. JS触发事件的方式有哪些

方法一:在js获取元素/标签

元素.事件名称 = 匿名函数 / function(){}

var oBox = document.querySelector('.box');
oBox.onclick = function(){
    console.log(oBox);
}

方法二: 元素.事件名称 = 函数名称

var oBox = document.querySelector('.box');
oBox.onclick = changeColor;
function changeColor(){
    oBox.style.backgroundColor = 'red';
}

方法三:    在html中触发  

 onclick = "代码段 / 函数调用"    如果是函数的调用,可以传递一个参数,this(表示的是当前的标签)

<div class="box" onclick="changeColor(this,'green')"></div>
<script>
function changeColor(getThis,color1){
    console.log(getThis);
    getThis.style.backgroundColor = color1;
}
</script>

 4.鼠标事件

事件说明
onclick鼠标点击某个对象
ondblclick鼠标双击某个对象
onmouseover鼠标被移到某元素之上
onmouseout鼠标从某元素移开
onmousemove鼠标被移动
onmousedown某个鼠标按键被按下
onmouseup某个鼠标按键被松开
oncontextmenu右键事件
onmousewheel当滚轮被滚动的时候
<!-- 给一个元素添加多个点击事件 -->
<style>
    .box{
        width: 300px;
        height: 300px;
        border: 1px solid #f00;
    }
</style>
<div class="box"></div>
<script>
    var oBox = document.querySelector('.box');
    // 单击
    oBox.onclick = function(){
        console.log(this);
        this.style.backgroundColor='red';
    }
    // 鼠标悬浮
    oBox.onmouseover = function(){
        this.style.backgroundColor='blue';
    }
    // 鼠标离开
    oBox.onmouseout = function(){
        this.style.backgroundColor='green';
    }
    // 双击
    oBox.ondblclick = function(){
        this.style.backgroundColor='pink';
    }
    var x = 0;
    // 鼠标移动
    oBox.onmousemove = function(){
        console.log(x++);
        // this.style.backgroundColor='orange';
    }
</script>

onmouseenter 和 onmouseover的区别

1、onmouseover、onmouseout:鼠标经过时自身触发事件,经过其子元素时也触发该事件; 支持冒泡

2、onmouseenter、onmouseleave:鼠标经过时自身触发事件,经过其子元素时不触发该事件。不支持冒泡

 

5. 键盘事件

导语:页面中有时候想要提交表单数据,直接按下enter就可以提交了;或者在玩游戏的时候可以通过WASD这四个按键来控制上下左右的方向,这就是通过键盘事件来操作的

​****事件​****说明
onkeypress[使用的比较少]键盘的某个键被按下
onkeydown键盘的某个键被按下或按住
onkeyup键盘的某个键被松开

 一个onkeydown+onkeyup = 鼠标单击事件,想要区分键盘上的每个按键,是通过键盘的keyCode值来判断的,所以想要知道按下的是哪个按键,可以使用event.keyCode

onkeydown 只要是按下的状态,就会一直触发当前事件

onkeyup 只有弹起的那一瞬间,才会触发

案例:通过上下左右四个键,控制div移动

<div class="box" style=" margin-left: 0px;margin-top: 0px;"></div>
<script>
    var oBox = document.querySelector('.box');
    document.onkeyup = function(){
        if(event.keyCode==39){
            oBox.style.marginLeft = parseFloat(oBox.style.marginLeft)+5 + 'px';
            console.log(parseFloat(oBox.style.marginLeft)+5);
        }else if(event.keyCode==37){
            oBox.style.marginLeft = parseFloat(oBox.style.marginLeft)-5 + 'px';
        }else if(event.keyCode==83){
            oBox.style.marginTop = parseFloat(oBox.style.marginTop)+5 + 'px';
        }
    }
</script>

注意:js中的.style添加的是行内样式,获取的也是行内样式 默认清空下标签没有margin-left值的话,获取之后转为float类型的时候,会变成NaN,所以:记得给标签添加默认的行内css样式

当然最好的方法还是通过left,top这些值来改变元素的位置,这样代码会更简单

6. 光标事件

事件说明
onfocus元素获得焦点
onblur元素失去焦点
// 获取焦点,让value消失;失去焦点,显示提示信息
<input type="radio" name="" id="inp" value="请输入用户名">
<script>
  var oInp = document.getElementById('inp');
  oInp.onfocus = function(){
    oInp.value = '';
  }
  oInp.onblur = function(){
    oInp.value = '请输入用户名';
  }
</script>

 案例:模拟小米官网搜索框效果

需求:input获取焦点显示下拉菜单信息,失去焦点,隐藏信息

<style>
    ul{
        display: none;
    }
</style>
<input type="radio" name="" id="inp" placeholder="小米">
<ul>
    <li>全部商品</li>
    <li>小米</li>
    <li>红米</li>
    <li>电脑</li>
    <li>平板</li>
    <li>笔记本</li>
</ul>
<script>
    // 小米官网 input效果
    // 给inp添加获取焦点的事件
    // 显示ul
    // 给inp添加失去焦点的事件
    // 隐藏ul
    var oInp = document.getElementById('inp');
    var oUl = document.querySelector('ul');
    oInp.onfocus = function(){
        oUl.style.display = "block";
    }
    oInp.onblur = function(){
        oUl.style.display = 'none';
    }
</script>

7. 窗口事件

事件说明
onresize览器窗口被调整大小时发生

8. 表单事件

导语:onsubmit,onreset相对来说用的比较少 onchange:onselect 属性可用于以下元素内:以及 在百度文库中,当我们选中文本的内容的时候,会显示 搜索/复制/发送到手机/翻译 等内容,这时候就可以使用onselect

事件说明
onsubmit提交按钮被点击
onreset重置按钮被点击
onselect文本内容被选定
onchange用户改变表单元素的内容
oninput在用户输入时触发
<form id='form1' action="a.php" onsubmit="alert('hello '+uname.value)" onreset="alert('world')">
    用户名:<input type="text" name="uname" id=""><br/>
    密码:<input type="password" name="pwd" id=""><br/>
    <textarea name="" id="" cols="30" rows="10">
        我的名字叫张三
    </textarea>
    <input type="submit" name="" id="">
    <input type="reset" name="" id="">
</form>

文本被选中

// 给多行文版框添加 选择的功能
var text = document.querySelector('textarea');
text.onselect = function(){
    console.log('123456789');
}

onchange 内容发生改变

// 只用多行文本发生会触发
text.onchange = function(){
    console.log('页面内容发生改变');
}

// 表单中的任意一个内容发生改变,都会触发onchange
var form1 = document.getElementById('form1');
form1.onchange = function(){
    console.log('change');
}

注意:onselect 属性可用于以下元素内:< input type="file" >、< input type="password">、< input type="text">、< keygen> 以及 < textarea>.

注意2:oninput事件类似于 onchange 事件。不同之处在于 oninput 事件在元素值发生变化是立即触发, onchange 在元素失去焦点时触发。另外一点不同是 onchange 事件也可以作用于 <keygen> 和 <select> 元素。

9. 单选框和复选框被选中

复选框是否被选中需要判断复选框中的checked的值 true:选中 false:没选中

基础案例

<input type="checkbox" id='inp'/>
<script>
    var oInp = document.querySelector('#inp');
    oInp.onclick = function(){
        console.log(this.checked);
    }
</script>

案例:购物车案例-将选中的商品价格进行计算

<table border='1' width="500">
    <tr>
        <td>选择</td>
        <td>商品名称</td>
        <td>商品价格</td>
    </tr>
    <tr>
        <td>
            <input type="checkbox" class="sel"/>
        </td>
        <td>上衣</td>
        <td class="price">100</td>
    </tr>
    <tr>
        <td><input type="checkbox" class="sel"/></td>
        <td>裤子</td>
        <td class="price">200</td>
    </tr>
    <tr>
        <td><input type="checkbox" class="sel"/></td>
        <td>包包</td>
        <td class="price">300</td>
    </tr>
    <tr>
        <td>全选:<input type="checkbox"/></td>
        <td colspan="2" id='totlePrice'>总价:0</td>
    </tr>
</table>
<script>
    // 1. 单选 - 给复选框添加一个事件
    // 2. 判断复选框的状态
    // 3. checked=true计算 / 否则不用计算
    // 4. 0-checked-price  1-checked-price  2-checked-price
    var oSel = document.querySelectorAll('.sel');
    var oPrice = document.querySelectorAll('.price');
    var totlePrice = document.querySelector('#totlePrice');
    var sum = 0;
    for(var i=0;i<oSel.length;i++){
        oSel[i].index = i;
        oSel[i].onclick = function(){
            if(this.checked){
                // 计算总价
                sum += parseFloat(oPrice[this.index].innerHTML);
            }else{
                sum -= parseFloat(oPrice[this.index].innerHTML);
            }
            totlePrice.innerHTML = "总价:"+sum;
        }
    }
</script>

 10. 加载事件

导语:正常情况下,js代码是可以写在head标签中,也可以写在/body结束的后面;但是当我们把js代码写在head中,并且js代码中有获取页面html标签的操作的时候,这时候的js代码就会报错

表示没有 “无法读取null属性(读取'innerHTML')”,也就是没有获取到对象,这时候可以在所有js的代码外面天际onload的;表示,html页面内容加载完毕之后,在执行js代码

​****事件​****说明
onload页面或图像加载完成
onbeforeunload页面卸载前执行
<script>
    // 页面加载完之后再执行js
    window.onload = function(){
        var oBox = document.getElementById('box');
        console.log(oBox.innerHTML);
    }
</script>
<div id='box'>hello world</div>

 // 如果页面中有滚动事件,滚动之后,想要重新刷新页面的时候,滚动条在最上面,可以使用这个方式
 window.onbeforeunload = function () {
      window.scrollTo(0, 0);
 }

 11. 滚动事件

​****事件​****说明
onscroll窗口发生滚动
scrollTo滚动到指定位置【增加】

方法一: window.scrollTo(x-coord,y-coord)

x-coord 是文档中的横轴坐标。

y-coord 是文档中的纵轴坐标。

比如: window.scrollTo(x-coord,y-coord)

x-coord 是文档中的横轴坐标。

y-coord 是文档中的纵轴坐标。

比如:window.scrollTo(0,1000); // 垂直滚动到1000的位置

方法二: window.scrollTo(options) // option为对象格式 window.scrollTo(options) // option为对象格式

  • top 等同于 y-coord
  • left 等同于 x-coord
  • behavior 类型String,表示滚动行为,支持参数 smooth(平滑滚动),instant(瞬间滚动),默认值auto,实测效果等同于instant

基础案例1:只要页面发生滚动,就触发滚动事件

<style>
body{
    height: 10000px;
}
</style>
<script>
    var i=1;
    window.onscroll = function(){
        console.log(i++);
    }
</script>
  1. 文档可视区域高度(屏幕的高度)   document.documentElement.clientHeight
  2. 文档高度(整个html页面的高度)   document.documentElement.scrollHeight
  3. 文档滚动高度(标准浏览器生效)   document.documentElement.scrollTop
  4. 文档滚动高度(IE浏览器有效)       document.body.scrollTop
  5. 获得当前坐标的X,Y坐标            x=event.clientX;   Y=event.clientY
  6. 获取当前元素的宽度和高度,定位的left和top/元素上面内容的高度

height=ele.offsetHeight;

width=ele.offsetWidth    

left = ele.offsetLeft

top = ele.offsetTop

 常用的尺寸获取方式:

获取页面滚动上去的高度:document.documentElement.scrollTop/document.body.scrollTop

获取当前元素的宽度和高度:ele.offsetHeight/ele.offsetWidth

获取窗口的宽度和高度:window.innerHeight

获取文档的宽度和高度:document.documentElement.scrollHeight

 12. js中两种添加事件的方式

  • 方式一 :on+事件名
  • 方法二:添加事件监听

1.方式一 :on+事件名

// 添加事件关联
oneDiv.onclick = function() {
  console.log("+++++");
}
oneDiv.onclick = function() {
  console.log("-----");
}
// 取消事件关联
oneDiv.onclick = null;
oneDiv.onclick = false;

2.方法二:添加事件监听【推荐使用】

语法1:element.addEventListener(event, function, useCapture)

Event: 必须。字符串,指定事件名。

注意: 不要使用 "on" 前缀。 例如,使用 "click" ,而不是使用 "onclick"。

Function: 必须。指定要事件触发时执行的函数。

useCapture: 可选。布尔值,(默认值, false. true 代表以事件捕获形式触发事件, false 代表以事件冒泡形式触发事件)

// 添加事件关联
function fun1() {
  console.log("++++++");
}
function fun2() {
  console.log("-----");
}
oneDiv.addEventListener("click", fun1);
oneDiv.addEventListener("click", fun2);
oneDiv.addEventListener("click", function() {
  console.log('你好');
});

// 取消事件关联
oneDiv.removeEventListener("click", fun1);

3.addEventListener的兼容性

// 其他浏览器
oneDiv.addEventListener("click", fun1);
oneDiv.removeEventListener("click", fun1);

// IE 低版本浏览器
Ie浏览器中的on关键词不能少
oneDiv.attachEvent("onclick", fun1);
oneDiv.detachEvent("onclick", fun1);

 

  1. 对比onclick和addEventListener

1.addEventListener可以对同一个元素绑定多个事件【相同事件】,执行顺序从上到下依次执行。而onclick同一个元素只能绑定一个【相同】事件,如有多个,后面的事件会覆盖前面的事件。

2.addEventListener的第三个参数为布尔类型,默认为false,也就是执行的冒泡机制,如为true,则执行捕获机制

3.addEventListener它对任何 DOM 元素都是有效的,而不仅仅只对 HTML 元素有效。点击查看dom分类

4.注册addEventListener事件时不需要写on,而onclick方式则必须加on

5.在移除事件上,onclick使用的是指针指向null,例如document.onclick = null,而addEventListener则使用的是独有的移除方法removeListener(要使用此方法,addEventListener必须执行的是外部函数或存在函数名,不然则不能使用) 6.addEventListener为DOM2级事件绑定,onclick为DOM0级事件绑定

7.IE678只能使用attachEvent,无addEventListener

总结:对于简单事件(同一个元素上只有一个事件)使用行内的onclick更合适。对于复杂事件使用 addeventlistenr 最后可以删除事件。 推荐使用addeventlistenr ,他是现在浏览器的标准,浏览器的兼容性会更好一些

13. DOM CSS动态样式 

用js对页面中的元素执行获取css样式 或者 添加对应的css样式的操作,js中获取css样式的方法比较多(obj.style,getComputedStyle,currentStyle),但是设置样式,只能使用obj.style的方式

  1. obj.style 【获取行内样式】 注意:可以获取样式,也可以设置样式

动态样式

  • 动态样式指通过脚本动态控制元素的样式,实现页面显示格式的动态变化。比如:动态滚动的文本、动态移动的图片、可折叠的树形菜单等。

使用style对象访问样式

  • 每个HTML标记均具有style属性,相应的,JavaScript脚本中的HTML元素对象都具有style属性,该属性是一个style对象。
  • Style对象的属性与CSS样式中的属性一一对应。

元素对象.className="类名"

  • 因为属性名class在JS中为关键字,所在此处写做className
var box = document.getElementById("box");
box.style.color="#ff0000";
box.style.width="400px";
box.style.height="300px";
box.style.backgroundColor="#ff0000";
box.style.border="1px solid #f00";
  • getComputedStyle 【非IE浏览器下,获取内部样式,或者外部样式】 注意:只能获取不能设置

基本语法: window.getComputedStyle(元素).样式属性

  • currentStyle 【IE浏览器下获取内部样式,或者外部样式】

基本语法: 元素.currentStyle.样式属性

  • js获取css样式,兼容性写法 一般情况下我们在使用的时候,我们不知道用户使用的是什么浏览器,所以需要对获取元素的方式做浏览器的判断
// 兼容写法
/**
 * 
 * @param obj 获取哪个元素的样式【属性】
 * @param attr  样式的名称【属性】
 * @returns 返回样式的值【属性值】
*/
function getCss(obj,attr){
    if(obj.currentStyle){
        return obj.currentStyle[attr];
    }else{
        return window.getComputedStyle(obj)[attr];
    }   
}

14. event对象使用技巧

  1. e.target 获取元素本身 我们可以使用e.target获取元素本身
  2. e.target.dataset 获取data-绑定的属性
  3. e.currentTarget 当前绑定事件的元素

15.移动端事件

PC端事件: 鼠标类:click,mouseover,mouseout,mouseleave,mouseenter,mouseup,mousedown 键盘类:keydown,keyup 其他类:blur,focus,change,load 但是对于移动端来说,是不存在鼠标事件和键盘事件的,因为移动端是没有鼠标和键盘的;

移动端事件: 单击事件,双击事件,滑动事件(上滑,下滑,左滑,右滑) 长按事件

摇一摇,重力感应等

案例:鼠标悬浮效果

<style>
    .box{
        width: 100px;
        height: 100px;
        background-color: red;
    }
    .box:hover{
        background-color: blue;
    }
</style>
<div class="box"></div>
<script>
    let box = document.querySelector('.box');
    let i=0;
    box.onclick = function(){
        console.log(++i);
    }
</script>

这个效果在PC端是没有问题的,但是在移动端,鼠标悬浮的时候,颜色是不会发生改变的; 移动端是没有鼠标的,也没有鼠标悬浮事件; 移动端的PC事件也有问题,click在移动端大概有300ms的延迟

移动端事件

触摸事件touch只有移动端才有touch事件

touch事件模型

touchsatrt:当手指触摸屏幕时触发,不管当前有多少只手指

touchmove:当手指在屏幕上滑动时连续触发,通常我们再滑屏页面,会调用event.preventDefault()

touchend:当手指离开屏幕时触发

touchcancel:系统通知跟踪触摸时候会触发。例如在触摸过程中突然有人打电话过来取消了当前的操作,此时会触发事件,这个事件用的比较少;

触摸事件的响应顺序:ontouchsatrt > ontouchmove > ontouchend > onclick 300ms延时

移动端为什么不用click

click事件在手机端会出现大概300ms的延迟,实际的执行延迟要比这个大,因为浏览器的内核运行也需要消耗事件。延迟执行的原因是苹果最早在手机上做了一个事件,当双击页面的时候,页面放大,也就是说,在点击页面的300ms之内,如果没有在此触发点击,则认为是单击事件,如果在此触发则认为是双击事件。 但目前,一般在手机web中,不允许缩放,也就没有双击事件,但是click延迟执行会影响用户体验; 谷歌判断点击的条件是 长按呀lang press的事件阀值为700ms,超过700ms就不再触发click事件

去除移动端click300ms延迟

meta标签
<meta name="viewport" content="width=device-width">

即把viewport设置成设备的实际像素,那么就不会有这300ms的延迟,并且这个举动收到了IE/Firefox/Safari(IOS9.3)的支持,也就是说现在的移动端开发可以不用顾虑click会比较迟钝的问题; 如果设置为initial-scale=1.0,在chrome上是可以生效,但是Safari不会:

<meta name="viewport" content="initial-scale=1.0">
css去除
html{touch-action: manipulation;}
fastClick库

截止2015年底,大多数移动浏览器(特别是Chrome和Safari)不再具有300ms的触摸延迟,毕竟再多引入一个js文件对项目也没有什么好处,不推荐使用。

touch事件对象

每个touch事件对象包含的属性如下:

  • clientX:触摸目标在视口中的x坐标。
  • clientY:触摸目标在视口中的y坐标。
  • pageX:触摸目标在页面中的x坐标。
  • pageY:触摸目标在页面中的y坐标。
  • screenX:触摸目标在屏幕中的x坐标。
  • screenY:触摸目标在屏幕中的y坐标。
  • identifier:标识触摸的唯一ID。
  • target:触摸的DOM节点目标。
  • targetTouches: 当前对象上所有触摸点的列表数组
  • changeTouches:涉及当前(引发)事件的触摸点的列表数组,常用于手指离开的事件,手指都离开屏幕之后,touches和targetTouches中将不再有只,targetTouches还会有一个只,此值为最后一个离开屏幕的手指的触摸点。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值