清风陪你学习-JavaScript-浏览器的API(三)

3事件对象

3.1 概述

事件的触发,大部分情况下是用户的一种行为,也就是说,我们并不能确定用户什么时间触发;

而且,由于事件的传播机制,我们甚至不能确定事件具体触发在哪个节点;这是一件很不爽的事情;

如何解决呢?

事件发生以后,系统会调用我们写好的事件处理程序

系统会在调用处理程序时,将事件发生时有关事件的一切信息,封装成一个对象,

作为参数传给监听函数(事件处理程序),我们把这个对象称为事件对象有关事件发生的一切信息,都包含在这个事件对象中;

根据事件类型的不同,事件对象中包含的信息也有所不同;如点击事件中,包含鼠标点击的横纵坐标位置,键盘事件中,包含键盘的键值等;


<body>
 
   <divid="div">
 
       <p>pppp</p>
 
   </div>
 
   <inputtype="text"value=""id="i">
</body>
<script>
vard=document.getElementById('div');
//鼠标事件
d.addEventListener('click',function(e){
 
   console.log(e);
});

vari=document.getElementById('i');
//键盘事件
i.addEventListener('keydown',k);
functionk(e){
 
   console.log(e);
}
</script>

3.2 事件对象中的常用属性及方法

3.2.1属性

event.bubbles:属性返回一个布尔值,表示当前事件是否会冒泡;event.eventPhase:返回一个整数值,表示事件流在传播阶段的位置

0:事件目前没有发生。1:事件目前处于捕获阶段。2:事件到达目标节点。3:事件处于冒泡阶段。

event.type:返回一个字符串,表示事件类型,大小写敏感;event.timeStamp:返回一个毫秒时间戳,表示事件发生的时间;

clientXclientY :获取鼠标事件触发的坐标


<body>
 
   <divid="d">
 
       <pid="p">sdf</p>
 
   </div>
</body>
<script>
 
   varp=document.getElementById('p');
 
   p.onclick=function(e){
 
       //当前事件是否会冒泡
 
       console.log(e.bubbles);
 
       //事件目前所处的节点
 
       console.log(e.eventPhase);
 
       //事件类型
 
       console.log(e.type);
 
       //事件发生的时间戳
 
       console.log(e.timeStamp);
 
  }
</script>

3.2.2 事件代理/委托

event.target:对事件起源目标的引用,属性返回触发事件的那个节点。event.currentTarget:属性返回事件当前所在的节点,即正在执行的监听函数所绑定的那个节点。作为比较,target属性返回事件发生的节点。


vard=document.getElementById('d');
d.onclick=function(e){
 
   //返回事件节点
 
   console.log(e.currentTarget);
 
   //返回触发节点
 
   console.log(e.target);
}

由于事件会在冒泡阶段向上传播到父节点,因此可以把子节点的监听函数定义在父节点上,由父节点的监听函数统一处理多个子元素的事件。这种方法叫做事件的代理也叫事件委托也有人称为事件代理


<head>
 
   <title></title>
 
   <metacharset="UTF-8">
 
   <style>
 
       div{padding: 40px}
 
       #div3{width: 300px;height: 300px;border: 1pxsolidred;}
 
       #div2{width: 200px;height: 200px;border: 1pxsolidred;}
 
       #div1{width: 100px;height: 100px;border: 1pxsolidred}
 
   </style>
</head>
<body>
 
   <divid="div3">3
 
       <divid="div2">2
 
          <divid="div1">1</div>
 
       </div>
 
   </div>
</body>
<script>
 
   vard=document.getElementById('div3');
 
   d.onclick=function(e){
 
       e.target.style.background='red';
 
  }
</script>

3.3.3 阻止浏览器默认行为&阻止事件传播

event.preventDefault():方法取消浏览器对当前事件的默认行为,比如点击链接后,浏览器跳转到指定页面,或者按一下空格键,页面向下滚动一段距离。

event.stopPropagation():方法阻止事件在DOM中继续传播,防止再触发定义在别的节点上的监听函数

<body>
 
   <divid="div2">2
 
       <divid="div1">1
 
          <aid="a"href="http://qq.com">清风陪你学习</a>
 
       </div>
 
   </div>
</body>
<script>
 
   vard2=document.getElementById('div2');
 
   vard1=document.getElementById('div1');
 
   vara=document.getElementById('a');
 
   d2.onclick=function(e){
 
      alert('d2');
 
  }
    d1.onclick=function(e){
 
      alert('d1');
 
  }
    a.onclick=function(e){
 
       //阻止事件传播
 
       //e.stopPropagation();
 
      alert('a');
 
      //阻止浏览器默认行为
 
      e.preventDefault();
 
  }
</script>

3.3 案例

验证密码的长度改变背景颜色


<inputtype="text"value=""id="txt"/>
<scriptsrc="common.js"></script>
<script>
 
 //根据id获取文本框---失去焦点的事件
 
 document.getElementById("txt").onblur=function () {
 
   //判断文本框中输入的内容长度是否在610个之间,如果是这样的,则背景颜色为红色
 
   if(this.value.length>=6&&this.value.length<=10){
 
     this.style.backgroundColor="red";
 
  }else{
 
     this.style.backgroundColor="green";
 
  }
  };
</script>

div的高亮显示


<style>
 
   div {
 
       width: 200px;
 
       height: 200px;
 
       background-color: green;
 
       float: left;
 
       margin-right: 20px;
 
       cursor: pointer;
 
       border: 2pxsolidgreen;
 
  }
</style>

<body>
 
   <div></div>
 
   <div></div>
 
   <div></div>
 
   <div></div>
 
   <div></div>

 
   <script>
 
       //根据标签名字获取所有的div
 
       vardivObjs=document.getElementsByTagName("div");
 
       //循环遍历
 
       for (vari=0; i<divObjs.length; i++) {
 
          //为每个div添加鼠标进入事件
 
          divObjs[i].onmouseover=mouseoverHandle;
 
          //为每个div添加鼠标离开事件
 
          divObjs[i].onmouseout=mouseoutHandle;
 
       }
        functionmouseoverHandle() {
 
          this.style.border="2px solid red";
 
       }
        functionmouseoutHandle() {
 
          //希望这个样式属性的值还原成默认的时候,值就是""空的字符串
 
          this.style.border="";
 
       }
    </script>

鹦鹉学舌


<body>
 
   <inputtype="text"id="t1"><br>
 
   <inputtype="text"id="t2">
</body>
<script>
 
   document.getElementById('t1').oninput=function(){
 
       document.getElementById('t2').value=this.value;
 
  }
</script>

飞机大战


<style>
 
   div {
 
       height: 500px;
 
       width: 400px;
 
  }

    img {
 
       height: 50px;
 
       width: 50px;
 
       position: absolute;
 
  }
</style>

<body>
 
   <div>
 
       <imgsrc="/img/feiji.png"alt=""id="img"style="left:0px;top: 0px">
 
   </div>
</body>
<script>
 
   document.onkeydown=function (ev) {
 
       varcode=ev.keyCode;
 
       varimg=document.getElementById('img');
 
       varx=parseInt(img.style.left), y=parseInt(img.style.top);
 
       if (code==37) {
 
          x=parseInt(img.style.left) -4+'px';
 
       }
        if (code==38) {
 
          y=parseInt(img.style.top) -4+'px';
 
          console.log(y);
 
       }
        if (code==39) {
 
          x=parseInt(img.style.left) +4+'px';
 
       }
        if (code==40) {
 
          y=parseInt(img.style.top) +4+'px';
 
       }

        img.style.left=x;
 
       img.style.top=y;
 
  }
</script>

·       鼠标点哪图片飞到哪里

思路:给整个dom绑定鼠标点击事件,获取点击位置后修改图片位置


<style>
 
   img {
 
       position: absolute;
 
       width: 50px;
 
       height: 50px;
 
  }
</style>

<body>
 
   <imgsrc="/img/c3.jpg"alt="">
</body>
<script>
 
   varim=document.getElementsByTagName('img')[0];
 
   document.onclick=function (e) {
 
       im.style.left=e.clientX+'px';
 
       im.style.top=e.clientY+'px';
 
  }
</script>

·       跟着鼠标飞的天使

思路:点击图片后,给整个dom绑定鼠标移动事件,让图片跟随


<style>
 
   img {
 
       position: absolute;
 
       width: 50px;
 
       height: 50px;
 
  }
</style>

<body>
 
   <imgsrc="/img/c3.jpg"alt="">
</body>
<script>
 
   varim=document.getElementsByTagName('img')[0];
 
   im.onclick=function () {
 
       document.onmousemove=function (e) {
 
          im.style.left=e.clientX+'px';
 
          im.style.top=e.clientY+'px';
 
       }
   }
</script>

·       实时获取鼠标在div内的坐标


<body>
 
   <divid="div3">3
 
      <pid="p"></p>
 
   </div>

</body>
<script>
 
   varp=document.getElementById('p');
 
   document.getElementById('div3').onmousemove=function(e){
 
       p.innerHTML=e.clientX+','+e.clientY;
 
       p.style.top=e.clientY+"px";
 
       p.style.left=e.clientX+"px";
 
  }
</script>

·       一次性事件案例(下载按钮点一次则失效)


<body>
 
   <inputtype="button"id="btn"value="下载">
</body>
<script>
 
   varbtn=document.getElementById('btn');
 
   functionf(){
 
       alert(123);
 
       btn.removeEventListener('click',f);
 
  }
    
    btn.addEventListener('click',f);
</script>

4节点操作

页面元素节点的操作,都离不开DOM对象

4.1 节点操作1

document.createElement()用来生成网页元素节点,参数为元素的标签名;

document.createTextNode()用来生成文本节点,参数为所要生成的文本节点的内容;

node.appendChild()接受一个节点对象作为参数,将其作为最后一个子节点,插入当前节点;

node.hasChildNodes()返回一个布尔值,表示当前节点是否有子节点

node.removeChild()接受一个子节点作为参数,用于从当前节点移除该子节点

node.cloneNode()用于克隆一个选中的节点。它接受一个布尔值作为参数,表示是否同时克隆子节点,默认是false,即不克隆子节点。注意:不会克隆绑定到该元素上的事件;

node.innerHTML返回该元素包含的 HTML 代码。该属性可读写,常用来设置某个节点的内容;(不属于W3C DOM规范)

node.innerText

返回该元素包含的内容。该属性可读写


<body>
 
   <divid="d">
 
       <span>111</span>
 
   </div>
</body>
<script>
 
   //创建元素节点
 
   varp=document.createElement('p');
 
   //创建文本节点
 
   vart=document.createTextNode('气味');
 
   //添加节点
 
   p.appendChild(t);
 
   vard=document.querySelector('#d')
 
   d.appendChild(p);

 
   //判断是否有子节点
 
   if(d.hasChildNodes('span')){
 
       vars=document.querySelector('span');
 
       //删除子节点
 
       d.removeChild(s);
 
  }

    // 克隆一个节点
 
   varc=d.cloneNode(true);
 
   d.appendChild(c);

    //操作选中元素的HTML代码,有值则是设置,无值则是获取
 
   alert(d.innerHTML);
 
   
    console.log(document.getElementById('d').innerText);
 
   console.log(document.getElementById('d').innerHTML);
</script>

案例:

点击按钮创建img节点,添加到body


<body>
 
   <inputtype="button"value="我要图"id="btn">
</body>
<script>
 
   varbtn=document.getElementById('btn');
 
   btn.onclick=function(){
 
       // var img =document.createElement('img');
 
       // img.src ='/img/c2.jpg';
 
       //document.getElementsByTagName('body')[0].appendChild(img);
 
       
        // 直接
 
       document.getElementsByTagName('body')[0].innerHTML+="<imgsrc='/img/c3.jpg'>";
 
  }
</script>

动态创建文本框


<body>
 
   <inputtype="button"value="++"id="btn">
 
   <divid="bo"></div>
</body>
<script>
 
   varbtn=document.getElementById('btn');
 
   btn.onclick=function () {
 
       //document.getElementById('bo').innerHTML += '<inputtype="text">';
 
       
        varinp=document.createElement('input');
 
       document.getElementById('bo').appendChild(inp);
 
  }
</script>

4.2 节点属性

4.2.1 原生属性

HTML元素节点的标准属性(即在标准中定义的属性),会自动成为元素节点对象的属性


<body>
 
   <divid="d"a="b"></div>
</body>
<script>

 
   vard=document.querySelector('#d');
 
   //获取原有属性值
 
   console.log(d.id);
 
   //修改原有属性值
 
   d.id='ff';
 
   console.log(d.a); // undefined
</script>

4.2.2 属性操作的标准方法

node.getAttribute()返回当前元素节点的指定属性。如果指定属性不存在,则返回null

node.setAttribute()为当前元素节点新增属性。如果同名属性已存在


<body>
 
   <divid="d"></div>
</body>
<script>
 
   vard=document.querySelector('#d');
 
   //设置属性,有则修改,无则添加,可设置非标准属性
 
   d.setAttribute('id','ffdd');
 
   d.setAttribute('aa','kk');
 
   //获取属性值,可获取非标准属性
 
   console.log(d.getAttribute('aa'));
</script>

node.hasAttribute()返回一个布尔值,表示当前元素节点是否包含指定属性

node.removeAttribute()从当前元素节点移除属性


//如果有id属性
if(d.hasAttribute('id')){
 
   //删除id属性
 
   d.removeAttribute('id');
}

4.3 节点操作2

node.nextElementSibling返回紧跟在当前节点后面的第一个同级Element节点,如果当前节点后面没有同级节点,则返回null

node.previousElementSibling返回紧跟在当前节点前面的第一个同级Element节点,如果当前节点前面没有同级节点,则返回null

node.parentElement返回当前节点的父级Element节点;

node.childNodes返回一个NodeList集合,成员包括当前节点的所有子节点(注意空格回车也算)

node.firstChild

返回树中节点的第一个子节点,如果节点是无子节点,则返回null

node.lastChild

返回该节点的最后一个子节点,如果该节点没有子节点则返回null


<body>
 
   <divid="d1">
 
       <pid="p1">11111</p>
 
       <pid="p2">222</p>
 
       <pid="p3">33333</p>
 
       <pid="p4">4444</p>
 
   </div>
 
   <divid="d2">
 
       <pid="p5">55555</p>
 
       <pid="p6">66666</p>
 
   </div>
</body>
<script>
 
   varp2=document.querySelector('#p2');
 
   //下一个兄弟节点
 
   p2.nextElementSibling.style.background='red';
 
   //上一个兄弟节点
 
   p2.previousElementSibling.style.background='red';
 
   //父级节点
 
   p2.parentElement.style.background='red';

 
   vard1=document.querySelector('#d1');
    //所有子节点列表
 
   d1.childNodes[3].style.background='red';
</script>

4.4 CSS样式操作

每个DOM对象都有style属性,我们可以直接操作,用来读写行内CSS样式。之前,我们已经简单的使用过JS控制元素的CSS样式;在具体使用的时候还有一些需要重点注意的细节:

1.      名字需要改写,将横杠从CSS属性名中去除,然后将横杠后的第一个字母大写:

比如background-color写成backgroundColor

2.      属性值都是字符串,设置时必须包括单位:

比如,divStyle.width的值不能写为100,而要写为100px


<body>
 
   <divid="d1"style="width:400px;height:200px;border: 1px solid red"></div>
</body>
<script>
 
   vard1=document.querySelector('#d1');
 
   d1.onclick=function(){
 
       //赋值则是设置
 
       d1.style.backgroundColor='red';
 
       //不赋值则是获取
 
       alert(d1.style.width);
 
  }
</script>

以上代码中,我们获取的CSS样式,均是行内样式;

如果将样式表写在 style 标签内,我们将无法获取和修改;

getComputedStyle()接受一个节点对象,返回该节点对象最终样式信息的对象,所谓最终样式信息,指的是各种CSS规则叠加后的结果。

注意: getComputedStyle()window对象下的方法,不是DOM对象


<style>
 
   #d1{
 
       width: 200px;height: 200px;
 
       border: 1pxsolidred;
 
  }
</style>

<body>
 
   <divid="d1"></div>
</body>

<script>
 
   vard1=document.querySelector('#d1');
 
   d1.onclick=function(){
 
       //获取不到
 
       console.log(d1.style.width);
 
       //获取计算后的样式
 
       console.log(getComputedStyle(d1).width);
 
  }
</script>

点击变大小案例:


<head>
<metacharset="UTF-8">
<title>Document</title>
<style>
 
   #d1{
 
       width: 200px;height: 200px;
 
       border: 1pxsolidred;
 
  }
</style>
</head>
<body>
 
   <divid="d1"></div>
</body>
<script>
 
   vard1=document.querySelector('#d1');
 
   d1.onclick=function(){
 
       varw=parseInt(getComputedStyle(d1).width);
 
       varh=parseInt(getComputedStyle(d1).height);
 
       d1.style.width=w+10+'px';
        d1.style.height=h+10+'px';
 
  }
</script>

其他方法和属性:

document.documentURI返回文档的 URL

node.replaceChild(newChild,oldChild) 用指定的节点替换当前节点的一个子节点,并返回被替换掉的节点。

node.insertBefore(): parentElement.insertBefore(newElement,referenceElement)

4.5 案例

节点方式隔行变色


<body>
 
   <inputtype="button"value="隔行变色"id="btn"/>
 
   <ulid="uu">
 
       <li>雪花啤酒</li>
 
       <li>金士百啤酒</li>
 
       <li>青岛啤酒</li>
 
       <li>燕京啤酒</li>
 
       <li>百威啤酒</li>
 
       <li>哈尔滨啤酒</li>
 
       <li>乐宝啤酒</li>
 
       <li>崂山啤酒</li>
 
   </ul>
</body>
<script>
 
   //点击按钮,所有的li隔行变色---奇红偶黄
 
   document.getElementById("btn").onclick=function () {
 
       varcount=0;
 
       //要获取ul中所有的子节点
 
       varnodes=document.getElementById("uu").childNodes;
 
       for (vari=0; i<nodes.length; i++) {
 
          varnode=nodes[i];
 
          //判断这个节点是不是li
 
          if (node.nodeType=="1"&&node.nodeName=="LI") {
 
              node.style.backgroundColor=count%2==0?"red" : "yellow";
 
              count++;//记录li标签的个数
 
           }
        }
   };
</script>

全选和全不选


<style>
 
   table {
 
       border-collapse: collapse;
 
       border-spacing: 0;
 
       border: 1pxsolid#c0c0c0;
 
       width: 500px;
 
  }

    th,
 
   td {
 
       border: 1pxsolid#d0d0d0;
 
       color: #404060;
 
       padding: 10px;
 
  }
</style>

<body>
 
   <table>
 
       <thead>
 
          <tr>
 
              <th>
 
                  <inputtype="checkbox"id="th"/>
 
              </th>
 
              <th>菜名</th>
 
              <th>饭店</th>
 
          </tr>
 
       </thead>
 
       <tbodyid="tb">
 
          <tr>
 
              <td>
 
                  <inputtype="checkbox"/>
 
              </td>
 
              <td>红烧肉</td>
 
              <td></td>
 
          </tr>
 
          <tr>
 
              <td>
 
                  <inputtype="checkbox"/>
 
              </td>
 
              <td>西红柿鸡蛋</td>
 
              <td></td>
 
          </tr>
 
          <tr>
 
              <td>
 
                  <inputtype="checkbox"/>
 
              </td>
 
              <td>油炸</td>
 
              <td></td>
 
          </tr>
 
          <tr>
 
              <td>
 
                  <inputtype="checkbox"/>
 
              </td>
 
              <td>清蒸</td>
 
              <td></td>
 
          </tr>
 
       </tbody>
 
   </table>
</body>
<script>
 
   document.getElementById('th').onclick=function () {
 
       vartb=document.getElementsByTagName('input');
 
       if (this.checked==true) {
 
          // console.log(tb);
 
          for (vari=0; i<tb.length; i++) {
 
              tb[i].checked=true;
 
           }
        } else {
 
          for (vari=0; i<tb.length; i++) {
 
              tb[i].checked=false;
 
           }
        }
   }
</script>

作业,实现反选

表格鼠标悬浮高亮(接上一个案例)


vart=document.getElementsByTagName('tbody')[0];
t.onmouseover=function(e){
 
   e.target.parentElement.style.background='#F5F5F5';
}
t.onmouseout=function(e){
 
   e.target.parentElement.style.background='#fff';
}

动态可编辑表格

<style>
 
   table {
 
       border-collapse: collapse;
 
       border-spacing: 0;
 
       border: 1pxsolid#c0c0c0;
 
       width: 500px;
 
  }

    th,
 
   td {
 
       border: 1pxsolid#d0d0d0;
 
       color: #404060;
 
       padding: 10px;
 
  }
</style>

<body>
 
   <inputtype="button"value="添加一行"id="addrow">
 
   <table>
 
       <thead>
 
          <tr>
 
              <td>菜名</td>
 
              <td>饭店</td>
 
              <td>厨师</td>
 
          </tr>
 
       </thead>
 
       <tbodyid="tb"></tbody>
 
   </table>
</body>
<script>
 
   vartbs=document.getElementsByTagName('table')[0];
 
   tbs.onclick=function (e) {
 
       varclicks=e.target;
 
       if (clicks.nodeName=='TD') {
 
          // var inp = document.createElement('input');
 
          // inp.value = clicks.innerText;
 
          // console.log(clicks.parentElement);
 
          clicks.innerHTML='<input value='+clicks.innerText+'>';
 
          tbs.getElementsByTagName('input')[0].onblur=function () {
 
              clicks.innerHTML=this.value;
 
           }
        }
   }

    varaddrow=document.getElementById('addrow');
 
   addrow.onclick=function(){
 
       vartr=document.createElement('tr');
 
       for(vari=0; i<3;i++){
 
          tr.appendChild(document.createElement('td'));
 
       }
        document.getElementById('tb').appendChild(tr);
 
  }

</script>

 

 "我是Spirit_Breeze,中文&lt;晟世清风>,在这纷纷乱世之中,祈望能有一股清流之风." 本人从事销售,不甘心于口舌之利,突然对代码和框架充满兴趣,遂之研究研究,欢迎研究讨论,转载请备注地址和作者,谢谢


猜你喜欢

转载自blog.csdn.net/spirit_breeze/article/details/80905695
今日推荐