event

本文详细介绍了JavaScript中的事件处理,包括事件对象、事件冒泡、事件委托、事件绑定及事件传播等概念,并提供了相关代码示例。通过事件对象获取鼠标坐标,事件冒泡控制事件传递,事件委托实现高效事件处理,以及键盘事件和滚动事件的处理方法。同时,文章探讨了不同浏览器的事件处理兼容性问题。
摘要由CSDN通过智能技术生成

事件对象

  1. onmousemove:鼠标移动事件
    • 事件对象:
      • 当事件响应函数被触发时,浏览器会生成一个和事件本身相关联的对象,传递给回调函数,这个对象包含了事件的一切信息,比如鼠标的坐标,按键值的值等等。这个对象被称为事件对象
      • 事件对象由系统自动产生
    • clientX、clientY 获取鼠标指针的水平坐标和垂直坐标
      var x, y;
      window.onload = function () {
        var div = document.getElementById("box");
        div.onmousemove = function (e) {
          //e为事件本身(事件对象)
          x = e.clientX;
          y = e.clientY;
          console.log(x, y);
        };
      };

事件冒泡

  1. 事件冒泡就是事件的向上传导机制,当后代的事件被触发后,其祖先元素的相同事件也会被触发
  2. 可以通过:事件对象.canceBubble = true (cance:通过 bubble:气泡)
  3. 开发中事件冒泡大多情况都有用
 window.onload = function () {
        var sp = document.getElementById("sp");
        sp.onclick = function (e) {
          // console.log(this);
          this.style.color = "red";
          console.log("span被点击");
          // 阻止浏览器默认的冒泡行为
          // 阻止的不是console.log而是点击这个行为向父元素传递
          // 添加之后,父元素不会因为子元素的点击而响应
          e.cancelBubble = true;
        };

        var box = document.getElementById("box");
        box.onclick = function () {
          console.log("div被点击");
        };
      };

事件委托

  • 将事件统一绑定为祖先元素,当后代元素上的事件被触发时,会一直冒泡到祖先元素上,从而通过祖先元素的回调函数来处理事件
  • 事件委托是利用了事件的冒泡机制,委托可以减少事件的绑定次数,提高程序的性能
 window.onload = function () {

            //获取所有a标签
            var all = document.getElementsByTagName('a');
            //循环给a标签绑定单击事件
            // for (var i = 0; i < all.length; i++) {
            //     all[i].onclick = function () {
            //         console.log('被点击');
            //     };
            // }

            var ul = $('add');
            //添加li标签
            $('btn').onclick = function () {
                //  ul.innerHTML += '<li><a href="javascript:;">连接四</a></li>';
                /*
                    每创建一个新的a标签,多需要重新绑定点击事件
                */
                var li = document.createElement('li');
                li.innerHTML = '<a href="javascript:;" class="link">连接四</a>';
                // console.log(li.children[0]);
                // li.children[0].onclick = function(){
                //     console.log('被点击');
                // };
                ul.append(li);
            };

            /*
                  问题: 绑定一次事件,使用到多个元素上?
                  结论:事件绑定到父元素,父元素统一处理事件
              */
            //统一给父元素绑定一次事件
            ul.onclick = function (e) {
                // console.log('被点击,触发');

                //判断是否为a标签
                //console.log(e.target); //获取事件源
                if(e.target.className == 'link'){
                    console.log('a被点击');  
                };

            };
        };

事件绑定

  1. 元素对象.事件名称 = 回调函数
    • 只能一个元素的相同事件只能绑定一次
    • 不能绑定多个(会被覆盖)
  2. 元素对象.addEventListener()
    • 参数:
      • 事件字符串:去掉on
      • 回调函数:事件触发时需要响应的函数
      • 是否在捕获阶段出发事件,boolean样式,一般设置为false
    • 一个元素的相同事件可以多次绑定
    • 执行的顺序为绑定的顺序
  3. 元素.attachEvent()
    • 参数:
      • 事件字符串,需要on
      • 回调函数
    • 一个元素的相同事件,可以被多次绑定,执行顺序为倒序
    • 仅支持IE浏览器
      /*
        绑定事件自定义函数

        参数:
          - obj:需要绑定的事件对象
          - eventStr:事件名称 不带on
          - callBack:回调函数
      */

      window.onload = function () {
        // 事件绑定
        input.addEventListener(
          "click",
          function () {
            console.log("1");
          },
          false
        );
        input.addEventListener(
          "click",
          function () {
            console.log("2");
          },
          false
        );
          
        // 兼容IE8
        input.attachEvent("onclick", function () {
          console.log("1");
        });
        input.attachEvent("onclick", function () {
          console.log("2");
        });
      // 实际应用(考虑兼容问题)

      /*
        参数:
          1、需要绑定的事件对象
          2、事件名称(不带on)
          3、回调函数
      */
      window.onload = function () {
        var input = document.getElementById("btn");

        bind(input, "click", function () {
          console.log(this.nodeName); //input
          console.log("----------");
        });

        function bind(obj, eventStr, callBack) {
          // 非IE
          if (obj.addEventListener) {
            obj.addEventListener(eventStr, callBack, false);
          } else if (attachEvent) {
            // 兼容IE8
            obj.attachEvent("on" + eventStr, function () {
              //call意思是调用callBack,让callBack函数属于obj
              callBack.call(obj);
            });
          } else {
            obj["on" + eventStr] = callBack;
          }
        }
      };

事件传播

// 调用了.js文件      
function bind(obj, eventStr, callBack) {
        if (obj.addEventListener) {
          obj.addEventListener(eventStr, callBack, false);
        } else if (obj.attachEvent) {
          // IE8兼容
          obj.attachEvent("on" + eventStr, callBack);
        } else {
          // 究极兼容
          obj["on" + eventStr] = callBack;
        }
      }
        bind(box1, "click", function () {
          console.log("1");
        });
        bind(box2, "click", function () {
          console.log("2");
        });
        bind(box3, "click", function () {
          console.log("3");
        });

键盘事件

  • onkeydown 键盘按下事件
  • 事件对象.keyCode 获取按钮的编码
  • onkeyup 键盘松开事件
        document.onkeydown = function (e) {
          // console.log(e);
          // 获取按下按键的uncode编码
          console.log(e.keyCode);
          // 判断是否按下回车
          if (e.keyCode == 13) {
            console.log("回车");
          }
          // 判断组合键被按下
          /**
           * 使用规则
           *  altkey、ctrlkey、shiftkey:判断alt、ctrl、shift是否被按下
           */
          if (e.keyCode == 67 && e.ctrlKey) {
            console.log("ctrl + c");
          }
          // // 监听键盘松开
          document.onkeyup = function () {
            console.log("键盘松开");
          };
          // // 键盘按下再松开
          document.onkeypress = function () {
            console.log("按下再松开");
          };
        };
        var input = document.querySelector("input");
        input.onkeydown = function (e) {
          console.log(e);
          if (
            (e.keyCode >= 48 && e.keyCode <= 57) ||
            (e.keyCode >= 96 && e.keyCode <= 105)
          ) {
            return false;
          }
        };
      };

滚动事件

      // deltaY:负值 => 向下滚动   正值 => 向上滚动
      window.onload = function () {
        $("box").onwheel = function (e) {
          // 取消默认事件
          e.preventDefault();
          if (e.deltaY > 0) {
            $("box").style.height = $("box").clientHeight + 10 + "px";
          } else if (e.deltaY < 0) {
            $("box").style.height = $("box").clientHeight - 10 + "px";
          }
          // 取消默认滚动行为
          // return false;
        };
      };

键盘移动

      // 移动的第一步有卡顿现象

      // 使用键盘,控制div移动
      window.onload = function () {
        var div = document.querySelector("div");
        // console.log(div);
        document.onkeydown = function (e) {
          // 解决IE8兼容问题
          e = e || window.event;
          // console.log(e.keyCode);
          //定义一个速度
          var speed = 10;
          switch (e.keyCode) {
            case 37: // 左
              div.style.left = div.offsetLeft - speed + "px";
              break;
            case 39: // 右
              div.style.left = div.offsetLeft + speed + "px";
              break;
            case 38: // 上
              div.style.top = div.offsetTop - speed + "px";
              break;
            case 40: // 下
              div.style.top = div.offsetTop + speed + "px";
              break;

            default:
              break;
          }
        };
      };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值