DAY11-event事件

什么是事件

一个事件由什么东西组成

  • 触发谁的事件:事件源
  • 触发什么事件:事件类型
  • 触发以后做什么:事件处理函数
var oDiv = document.querySelector('div')

oDiv.onclick = function () {}
// 谁来触发事件 => oDiv => 这个事件的事件源就是 oDiv
// 触发什么事件 => onclick => 这个事件类型就是 click
// 触发之后做什么 => function () {} => 这个事件的处理函数
  • 我们想要在点击 div 以后做什么事情,就把我们要做的事情写在事件处理函数里面
var oDiv = document.querySelector('div')

oDiv.onclick = function () {
  console.log('你点击了 div')
}
  • 当我们点击 div 的时候,就会执行事件处理函数内部的代码
  • 每点击一次,就会执行一次事件处理函数

事件对象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Sainkkwo-1662550128215)(/1560735081472.png)]

去把生番给我做了,记住制造成自杀的假象

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QRzLEzvc-1662550128217)(/1560735100759.png)]

老大说,给你配个对象兼秘书,叫event(伊文)

比较羞涩,用的时候,得叫她出来,平时需要隐藏起来

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NRUlY1Bg-1662550128217)(/1560735132286.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1erqhJnw-1662550128218)(/1560735160585.png)]

事件对象
  • 就是当你触发了一个事件以后,对该事件的一些描述信息

  • 例如:

    • 你触发一个点击事件的时候,你点在哪个位置了,坐标是多少
    • 你触发一个键盘事件的时候,你按的是哪个按钮
  • 每一个事件都会有一个对应的对象来描述这些信息,我们就把这个对象叫做 事件对象

  • 浏览器给了我们一个 黑盒子,叫做 window.event,就是对事件信息的所有描述

    • 比如点击事件
    • 你点在了 0,0 位置,那么你得到的这个事件对象里面对应的就会有这个点位的属性
    • 你点在了 10, 10 位置,那么你得到的这个事件对象里面对应的就会有这个点位的属性
    oDiv.onclick = function () {
      console.log(window.event.X轴坐标点信息)
      console.log(window.event.Y轴坐标点信息)
    }
    
  • 这个玩意很好用,但是一般来说,好用的东西就会有 兼容性问题

  • IE低版本 里面这个东西好用,但是在 高版本IEChrome 里面不好使了

  • 我们就得用另一种方式来获取 事件对象

  • 在每一个事件处理函数的行参位置,默认第一个就是 事件对象

    oDiv.onclick = function (e) {
      // e 就是和 IE 的 window.event 一样的东西
      console.log(e.X轴坐标点信息)
      console.log(e.Y轴坐标点信息)
    }
    
  • 综上所述,我们以后在每一个事件里面,想获取事件对象的时候,都用兼容写法

    oDiv.onclick = function (e) {
      e = e || window.event
      console.log(e.X轴坐标点信息)
      console.log(e.Y轴坐标点信息)
    }
    

事件的分类

鼠标事件
事件含义
onclick鼠标单击
ondblclick鼠标双击(必须连续点击两下)
onmouseover鼠标移入,即鼠标停留在图片等的上方(一次)
onmouseout鼠标移出,即离开图片等所在的区域(一次)
onmousemove鼠标移动,即鼠标在图片的上方不断移动(多次)
onmouseup事件会在鼠标按键被松开时发生。
onmousedown事件会在鼠标按键被按下时发生。
页面事件
名称含义
onload网页内容加载/运行完毕之后调用/执行函数里面的内容
onresize当浏览器的窗口大小被改变时触发的事件
表单事件
名称作用
onblur指定元素失去焦点(光标没了)
onfocus指定元素获取焦点(点击出现光标)
onreset重置表单的时候触发事件,执行对应的js功能
onsubmit提交表单的时候触发事件,执行对应的js功能
onchange下拉菜单改变时候触发

event的使用

<body>
 <p onclick="fn()">只愿君心似我心,定不负相思意</p>
</body>
<script>
   function fn(eve){
      // 兼容的写法
       var e = window.event || eve;
       console.log(e);
   }
</script>

 早期的浏览器中,在IE/Opera中,是window.event,而在Firefox中,是event

任何事件的触发都会产生event对象

event事件对象属性

老大给的美女event可以做什么呢?

属性说明
event.typetype属性指示事件类型。
event.whichwhich 属性指示按了哪个键或按钮。
event.clientX事件触发时鼠标距离窗口左边的距离(可视区域)。
event.clientY事件触发时鼠标距离窗口上边的距离(可视区域)。
event.screenX事件触发时鼠标距离屏幕左边的距离。
event.screenY事件触发时鼠标距离屏幕上边的距离。
event.button返回值为0,左键;返回值为1,中键;返回值为2,右键
event.offsetX当鼠标事件发生时,鼠标相对于事件发生元素左边的位置
event.offsetY当鼠标事件发生时,鼠标相对于事件发生元素顶部的位置
event.pageX当鼠标事件发生时.相对于文档窗口左边的位置
event.pageY当鼠标事件发生时.相对于文档窗口顶部的位置

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yM5JDSjm-1662550128219)(/1560738380822.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cTo9q34o-1662550128220)(/1560744129922.png)]

此时可视窗口与文档窗口重叠,pageX等于clientX, pageY等于clientY, 如果我们缩小浏览器窗口直到浏览器出现滚动条。此时可视窗口左上角位置不变,但文档窗口左上角位置发生的变化.

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s2oHMerb-1662550128221)(/1560744169992.png)]

由此我们可以看出当浏览器没有滚动条时(可视窗口与文档窗口重合),pageX与clientX相等,pageX与clientY相等,如果出现下拉滚动条并向下拉动滚动条,文档窗口向上滚动,如果出现左右滑动的滚动条并向右拉动滚动条,文档窗口向左滚动,在文档窗口滚动的情况下,pageX>=clientX, pageY>=clientY, x = clientX, y = clientY.
案列实现
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
      #box{
          width:100px;
          height: 100px;
          background: pink;
          margin:40px;
      }
    </style>
</head>
<body style="height: 1000px">
    <div id="box">

    </div>
    <script>
     var divObj = document.getElementById('box');
         divObj.onclick = function(eve){
             var e  = window.event || eve;
             //console.log(e)4
             // 获取事件类型
            // console.log(e.type)
            
             // 获取按的那个键
           //  console.log(e.which)

           // 鼠标距离可视区的距离
            console.log('可视x',e.clientX);
            console.log('可视y',e.clientY);

            // 距离屏幕x,y的距离
            // console.log('x',e.screenX);
            // console.log('y',e.screenY);

            // 鼠标相对于元素的,x,y距离
            //  console.log('x',e.offsetX);
            // console.log('y',e.offsetY);

             // 相对于文档的x,y距离
             // 没有滚动条,可视区域和文档区域的位置重合
              console.log('文档x',e.pageX);
              console.log('文档y',e.pageY);
         }
    </script>
</body>
</html>

例2:小天使的移动

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
      img{
          position: absolute;
          top:0px;
          left:0px;
      }
    </style>
</head>
<body>
    <img src="../images/tianshi.gif" alt="">
    <script>
      // 1 给整个文档绑定鼠标移动事件
      document.onmousemove = function(eve){
          var e = eve || window.event;
             // 2 获取可视区域的位置
          var tmpX = e.clientX;
          var tmpY = e.clientY;
           // 3 将位置设置到img
          var imgObj = document.querySelector('img');
          imgObj.style.top = tmpY+'px';
          imgObj.style.left = tmpX+'px';

      }
   

   

    
    </script>
</body>
</html>

应用与练习

1.光标的实时显示,画布功能的实现

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-D9NpUljF-1662550128221)(/1560742320889.png)]

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
			#xy{position: fixed;left: 0;bottom: 0;}
			.box{border-radius: 50%;position: absolute;}
			input{position: absolute;z-index: 999999999999;}
			input:nth-child(2){left: 50px;}
			input:nth-child(3){left: 100px;}
		</style>
	</head>
	<body>
		<input type="button" name="" id="btn1" value="+" />
		<input type="button" name="" id="btn2" value="-" />
		<input type="button" name="" id="red" value="red" />
		<span id="xy"></span>
	</body>
	<script type="text/javascript">
	 // 1 获取节点
     var btnsObj = document.querySelectorAll('input');
     var btn1Obj = btnsObj[0];
     var btn2Obj = btnsObj[1];
     var btn3Obj = btnsObj[2];
     var spanObj = document.getElementById('xy');

     // div背景颜色
     var c = 'black';
     // div宽高的设置
     var w =h= 8;


    /*******必须是按下的时候,滑过才显示******/
  
     // 2 给document绑定鼠标移动事件
     document.onmousedown = function(event){
         // 嵌套一个移动事件
         document.onmousemove = function(){

        
         // 获取事件对象
         var e = window.event || event;
         // 获取鼠标实相对于文档的时的位置
          var mouseX = e.pageX;
          var mouseY = e.pageY;
          // 将实时的位置放到页面左下角
          spanObj.innerHTML = mouseX+','+mouseY;

          /******动态创建div,鼠标经过后显示******/
          var divObj = document.createElement('div');
              // 设置div的定位
              divObj.style.position = 'absolute';
              divObj.style.top = mouseY+'px';
              divObj.style.left = mouseX+'px';
              // 设置背景颜色
              divObj.style.background = c;
              // 设置div的宽高
              divObj.style.width = w+'px';
              divObj.style.height = h+'px';
              // 设置div为圆的
              divObj.style.borderRadius = '50%';
              // 追加到页面中
              document.body.appendChild(divObj);
            }
     }

     // 鼠标抬起来的时候,清除移动事件
     document.onmouseup = function(){
         document.onmousemove =null;
     }

    /*******点击控制div的大小******/
    btn1Obj.onclick = function(){
        w+=2;
        h+=2;
    }
    btn2Obj.onclick = function(){
        w-=2;
        h-=2;
    }
    //点击之后改变div颜色
    btn3Obj.onclick = function(){
        c= 'red';
    }
	</script>
</html>

2.跟随点击产生随机的颜色小方块
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>

</head>

<body>

  <script>
    document.onclick = function (e) {
      var eve = e || window.event;
      var tmpX = eve.pageX;
      var tmpY = eve.pageY;
      var divObj = document.createElement('div');
      divObj.style.position = 'absolute';
      divObj.style.background = getColor();
      divObj.style.top = tmpY + 'px';
      divObj.style.left = tmpX + 'px';
      var tmpNum = getRan(50, 100);
      divObj.style.width = tmpNum + 'px';
      divObj.style.height = tmpNum + 'px';
      this.body.appendChild(divObj);
    }

    function getRan(min, max) {
      return Math.round(Math.random() * (max - min) + min);
    }

    function getColor() {
      var c = '#';
      for (var i = 0; i < 6; i++) {
        c += getRan(0, 16).toString(16)
      }
      return c;
    }
  </script>
</body>

</html>
键盘事件

一般只给能在页面上选中的元素(表单元素) 和 document 来绑定键盘事件.div之类的元素没办法去触发这类事件.

名称
名称作用
onkeydown按下键盘触发事件·
onkeyup按下键盘后松开触发事件
onkeypress按下并抬起

注意:适用于大部分的标签元素

键盘码获取
按键ASCII码
event.keyCode返回当前按键的ASCII码
空格32
回车13
左上右下37,38,39,40
a65
altKey(k大写)判断alt是否被按下,按下返回true
ctrlKey(k大写)判断ctrl是否被按下,按下返回true
shiftKey(k大写)判断shift是否被按下,按下返回true

脚下留心:

   兼容问题:   var eve = event || window.event
              var keyC = eve.keyCode || eve.which
              
  IE只有keyCode属性,FireFox中有which和charCode属性,Opera中有keyCode和which属性,Chrome中有keyCode、which和charCode属性

使用场景

在用户登录时,如果按下了大写锁定键(20),则加以提示大写锁定;在有翻页的时候,如果用户按下左右箭头,触发上下翻页等。

实际操作

		// 给整个文档即HTML元素绑定事件
		document.onkeydown = function(eve){
			var e = eve || window.event
			var keycode = e.keyCode || e.which
			
			switch(keycode){
				case 13:
					console.log("回车");break;
				case 65:
					console.log("a");break;
				case 66:
					console.log("b");break;
				case 67:
					console.log("c");break;
				case 68:
					console.log("d");break;
				case 69:			
                console.log("e");break;
			}
		}

案例:使用上下左右箭头控制四方形移动

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
            #box{
                position: absolute;
                width:150px;
                height: 150px;
                background: red;
           
            }
          
          </style>
</head>

<body>
    <div id="box">


    </div>
    <script>
    var boxObj = document.getElementById('box');
    // 设置box的初始位置
    var t = 100;
  //  boxObj.style.top = t+'px';
    var l = 100;
    //boxObj.style.left = l+'px';
    pos(t,l)
      //给文档绑定键盘事件
       document.onkeydown = function(event){
           var e = event || window.event;
           // 获取键盘码
           var code = e.keyCode || e.which;
           //console.log(code)
           if(code==38){  // 上
               // 上是top值,减小
              t-=10;
           }
           if(code==40){// 下
              t+=10;

           }

           if(code==37){  // 左
               l-=10;
           }

           if(code==39){  // 右
                l+=10;
           }

             pos(t,l);
       }

  // 将值设置到div上
  function pos(t,l){
    boxObj.style.top = t+'px';
    boxObj.style.left = l+'px';
  }

    </script>
</body>
</html>
组合按键
  • 组合案件最主要的就是 alt / shift / ctrl 三个按键
  • 在我点击某一个按键的时候判断一下这三个键有没有按下,有就是组合了,没有就是没有组合
  • 事件对象里面也为我们提供了三个属性
    • altKey :alt 键按下得到 true,否则得到 false
    • shiftKey :shift 键按下得到 true,否则得到 false
    • ctrlKey :ctrl 键按下得到 true,否则得到 false
  • 我们就可以通过这三个属性来判断是否按下了
document.onkeyup = function (e) {
  e = e || window.event
  keyCode = e.keyCode || e.which
  
  if (e.altKey && keyCode === 65) {
    console.log('你同时按下了 alt 和 a')
  }
}
触摸事件
  • ontouchstart : 触摸开始事件

  • ontouchend : 触摸结束事件

  • ontouchmove : 触摸移动事件

    此处的触摸事件要把浏览器调成手机模拟器模式,才能生效

<!DOCTYPE html>

<html>

<head>
  <title>touchend Event in HTML</title>
  <style>
    body {
      text-align: center;
    }

    p {
      font-size: 30px;
    }
  </style>
</head>

<body>


  <p ontouchend="end()" ontouchstart="start()" ontouchmove="move()">
    码中自有黄金屋,码中自有颜如玉!
  </p>
  <br>

  <p id="test"></p>

  <script> 
    function start() {
      document.getElementById(
        "test").innerHTML =
        "触摸开始";
    }
    function end() {

      document.getElementById(
        "test").innerHTML =
        "触摸结束";
    }


    function move() {
      document.getElementById(
        "test").innerHTML =
        "触摸当中";
    }

  </script>

</body>

</html>

事件冒泡

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fPl6KwE5-1662550128222)(/1560756341686.png)]

事件流:事件执行顺序我们叫他事件流。

  事件流中事件冒泡的由来:IE公司认为,如果你面前有个靶子,你的飞镖射中了其中一环,并不仅仅是只对这一环产生了操作,而是对整个靶子都产生了操作。

   所以,当最里面的元素触发了事件的时候,会依次向上触发所有元素的相同事件(从触发事件的元素开始一直向上触发),但是事件冒泡对我们几乎没有任何好处,所以我们需要阻止事件冒泡,禁止之后事件只会停留在当前层。
阻止事件冒泡

通过事件对象,可以阻止事件冒泡.

通用方法

event.stopPropagation();
说明:stopPropagation是事件对象Event的一个方法,作用是阻止目标元素事件冒泡到父级元素。

IE浏览器的方法

event.cancelBubble = true;

例1:事件冒泡行为的演示

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<style>
#aa{
    width: 500px;
    height: 500px;
    background: pink;
}
#bb{
    width: 300px;
    height: 300px;
    background: red;
}
#cc{
    width: 150px;
    height: 150px;
    background:green;
}
</style>
<body>
<div id="aa">
    aa
   <div id="bb">
       bb
       <div id="cc">cc</div>
   </div>

</div>
    
    <script>
      //事件冒泡: 当触发了子级元素时,父级元素上的同类型事件,也会被触发
      // 这就是冒泡
      
      var aaObj = document.getElementById('aa');
      var bbObj = document.getElementById('bb');
      var ccObj = document.getElementById('cc');

      // 给aa,bb,cc都绑定点击事件
      aaObj.onclick = function(){
          alert('我是aa')
      }
      bbObj.onclick = function(){
          alert('我是懵B')
      }

      ccObj.onclick = function(){
          alert('我是cc')
      }
    </script>
</body>
</html>

例2:在例1的基础上阻止事件冒泡

 <script>
        // 获取节点
      var aa = document.getElementById('aa');
      var bb = document.getElementById('bb');
      var cc = document.getElementById('cc');
      // 绑定事件
      aa.onclick=del;
      bb.onclick = del;
      cc.onclick = del;
      function del(event){
          var e = event || window.event;
          if(e.stopPropagation){   // 通用方式阻止冒泡行为
              e.stopPropagation();
          }else{
               e.cancelBubble=true;  // IE浏览器阻止默认行为
          }
     
            alert(this.innerText);
      }
     
    </script>

练习

1 鼠标跟随的实现

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
    * {
      margin: 0;
      padding: 0;
    }

    ul, li {
      list-style-type: none;
    }

    ul {
      padding: 100px;
    }

    li {
      width: 400px;
      height: 40px;
      border: 1px solid #333;
      padding: 20px;
      margin: 10px;

      position: relative;

      background-color: #fff;
    }

    li > p {
      position: absolute;
      left: 600px;
      top: 300px;
      width: 300px;
      height: 200px;

      display: none;

      /* 表示让 p 标签不接受任何事件 */
      pointer-events: none;

      z-index: 999;
    }
  </style>
</head>
<body>

  <ul>
    <li>
      标题一
      <p style="background-color: pink;">内容标题一的说明内容标题一的说明内容标题一的说明内容标题一的说明内容标题一的说明内容标题一的说明内容标题一的说明内容标题一的说明内容标题一的说明内容标题一的说明内容标题一的说明内容标题一的说明内容标题一的说明内容标题一的说明内容标题一的说明内容标题一的说明内容标题一的说明内容标题一的说明内容</p>
    </li>
    <li>
      标题二
      <p style="background-color: skyblue;">标题二的说明内容标题二的说明内容</p>
    </li>
    <li>
      标题三
      <p style="background-color: orange;">标题三的说明内容标题三的说明内容</p>
    </li>
  </ul>



  <script>
    /*
      案例 - 鼠标跟随

      需求:
        1. 移入 li 的时候
          => 自己的后代元素 p 显示
        2. 移出 li 的时候
          => 自己的后代元素 p 消失
        3. 在 li 内光标移动的时候
          => 自己的后代元素 p 跟随光标移动

      代码实现:
        1. 需求1
          1-1. 获取到所有的 li
          1-2. 给谁绑定什么事件 ?
            => 给 li 绑定鼠标移入事件 mouseover
          1-3. 让自己的后代 p 元素显示
            => p.style.display = 'block'
        2. 需求2:
          2-1. 获取到所有的 li(步骤1完成)
          2-2. 给谁绑定什么事件 ?
            => 给 li 绑定鼠标移出事件 mouseout
          2-3. 让自己的后代 p 元素隐藏
            => p.style.display = 'none'
        3. 需求3:
          3-1. 获取到所有的 li(步骤1完成)
          3-2. 给谁绑定什么事件 ?
            => 给 li 绑定鼠标移动事件 mousemove
          3-3. 让自己的后代 p 元素跟随鼠标移动
            => 拿到鼠标的坐标信息
              -> 哪一组坐标合适
              -> offset 一组
              -> 因为 p 是根据 li 进行定位的
            => 把坐标信息赋值给 p 的 left 和 top 样式

      小 BUG
        + 从左向右的时候, 会抖动
        + 原因:
          => 光标和 p
        + 解决:
          => 方案1:
            -> 让 p 距离光标远一点
          => 方案2:
            -> 让 p 标签不接受事件
            -> 任何事件到达我的身上的时候, 直接穿透我
            -> 去到我的父元素身上
            -> 给 p 加一个 css 样式
              + pointer-events: none;
    */

    // 0. 获取元素
    var lis = document.querySelectorAll('ul > li')

    // 1. 需求1:
    // 给每一个 li 绑定事件
    // 拿到每一个 li(遍历)
    // 逐个绑定事件
    lis.forEach(function (item) {
      // 1-2. 给每一个 li 绑定鼠标移入事件
      item.onmouseover = overHandler

      // 2-2. 给每一个 li 绑定鼠标移出事件
      item.onmouseout = outHandler

      // 3-2. 给每一个 li 绑定鼠标移动事件
      item.onmousemove = moveHandler
    })

    // 移入的事件处理函数
    function overHandler() {
      // 1-3. 让自己的后代元素 p 显示出来
      // 自己是 ? this
      this.firstElementChild.style.display = 'block'
    }

    // 移出的事件处理函数
    function outHandler() {
      // 2-3. 让自己的后代元素 p 消失
      this.firstElementChild.style.display = 'none'
    }

    // 移动的事件处理函数
    function moveHandler(e) {
      // 3-3. 拿到合适的坐标信息
      var x = e.offsetX
      var y = e.offsetY

      // 赋值给自己的后代元素 p 的 left 和 top
      this.firstElementChild.style.left = x + 'px'
      this.firstElementChild.style.top = y + 'px'
    }
  </script>
</body>
</html>

强化练习

1 1.CSS模拟下拉菜单

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uQF2wqIf-1662550128223)(/1560757845233.png)]

<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8">
		<title></title>
		<style type="text/css">
			*{margin: 0;padding: 0;list-style: none;}
			#cont{width: 300px;margin: 40px auto;}
			input{width: 296px;height: 40px;}
			ul{background: #eee;display: none;}
			ul li{line-height: 30px;text-indent: 20px;border-bottom: solid 1px black;}
			ul li.active{background: #ccc;}
		</style>
	</head>
	<body>
		<div id="cont">
			<input type="text" name="" id="txt" value="" />
			<ul>
				<li>选项1</li>
				<li>选项2</li>
				<li>选项3</li>
				<li>选项4</li>
				<li>选项5</li>
				<li>选项6</li>
			</ul>
		</div>
	</body>
	<script type="text/javascript">
	  // 1 获取节点
     var  inputObj = document.getElementById('txt');
     var  ulObj  =  document.getElementsByTagName('ul')[0];
     var   lisObj = ulObj.children;
     // 保存li对应的索引值
     var index =-1;
      // 2 给input框,绑定获取焦点事件,获取焦点时显示ul
       inputObj.onfocus = function(){
           // 显示ul
           ulObj.style.display = 'block';
       }
      // 3失去焦点时,隐藏ul
       inputObj.onblur = function(){
           // 隐藏ul
        ulObj.style.display = 'none';
       }
      // 4 循环li,绑定鼠标移入事件,设置class='active'
       for(var i=0;i<lisObj.length;i++){
           
           // 将当前li对应的索引值,保存到li对象
           lisObj[i].index = i;
           lisObj[i].onmouseover = function(){
               //鼠标移入时发生的
               // 将li对象上保存的index属性,取出放到全局变量中
              index = this.index;
              // 调用设置选中样式的函数
              select();
           }
       }
        //目标:按上下键让li轮流选中
        // 1 给inputObj绑定键盘事件
         inputObj.onkeydown = function(event){
             var e  = event || window.event;
            // 2获取键盘码, 判断按的是上键还是下键
             var code = e.which || e.keyCode;
            if(code=='38'){  //按的是上键
               // 3 按上键让li的索引值减小
               if(index==-1 || index==0) index = lisObj.length-1;
               else index--;
                //调用选中的函数
               select();
            }
              //4  按下键让li的索引值增大 
            if(code==40){
                if(index==lisObj.length-1) index = 0;
                else index++;

                select();
            }
         }


      
      // 设置选中li的样式,及inout内容显示
      function select(){
          // 先取消所以所有li的class
          for(var i =0;i<lisObj.length;i++){
              lisObj[i].className = '';
          }
          lisObj[index].className  = 'active';
                // 5 让li的内容,显示在input中
          // 获取li标签中的内容
          var text = lisObj[index].innerHTML;
       
          // 放到input框
          inputObj.value = text;
      }
	</script>
</html>

     inputObj.onkeydown = function(event){
         var e  = event || window.event;
        // 2获取键盘码, 判断按的是上键还是下键
         var code = e.which || e.keyCode;
        if(code=='38'){  //按的是上键
           // 3 按上键让li的索引值减小
           if(index==-1 || index==0) index = lisObj.length-1;
           else index--;
            //调用选中的函数
           select();
        }
          //4  按下键让li的索引值增大 
        if(code==40){
            if(index==lisObj.length-1) index = 0;
            else index++;

            select();
        }
     }


  
  // 设置选中li的样式,及inout内容显示
  function select(){
      // 先取消所以所有li的class
      for(var i =0;i<lisObj.length;i++){
          lisObj[i].className = '';
      }
      lisObj[index].className  = 'active';
            // 5 让li的内容,显示在input中
      // 获取li标签中的内容
      var text = lisObj[index].innerHTML;
   
      // 放到input框
      inputObj.value = text;
  }
</script>

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值