Javascript中的事件

249 阅读5分钟

Javascript常用事件

JS 事件(event)是当用户与网页进行交互时发生的事情,例如单机某个链接或按钮、在文本框中输入文本、按下键盘上的某个按键、移动鼠标等等。当事件发生时,您可以使用 JavaScript 中的事件处理程序(也可称为事件监听器)来检测并执行某些特定的程序。

一般情况下事件的名称都是以单词on开头的,例如点击事件 onclick、页面加载事件 onload 等。下图中列举了一些 JavaScript 中常用的事件:

js事件.png

js中的事件分为0级事件和2级事件

0级事件表现形式如下:直接向元素添加事件,可以理解为带on的就是0级事件,0级事件存在覆盖问题,下边重新向元素绑定形同的事件,之前绑定的事件会被覆盖。

     <div id="box"></div>
     let box = document.queryseleter('#box');
      box.onclick = () => {
        console.log(1111);
    };
     box.onclick = () => {
        console.log(2222);
     };

2级事件表现形式如下:通过addEventlistener方法添加的事件是唯一的,可以向元素添加多个相同的事件,不会被覆盖,addEventlistener接收三个参数,第一个参数为要绑定的事件(不用加on),第二个参数为一个回调函数,里面写事件触发要做的事情,第三个参数为true表示在捕获阶段触发,为false表示在冒泡阶段触发。

     <div id="box"></div>
     let box = document.queryseleter('#box');
     box.addEventlistener('click',()=>{
     console.log(666);
     });

只有DOM2级事件包含三个阶段,事件捕获阶段,处于目标阶段,事件冒泡阶段,removeEventlistener:移除事件,需要将回调函数具名化

事件对象

事件对象为 event 对象,是一个内置全局对象,而 event 对象在 Firefox 不存在这个对象,对 Firefox 需要使用一个局部变量来接收有关事件的相关信息,在是事件对象中有很多属性,供我们使用.

image.png

使用event事件对象
 <button id="btn"></button>
 let btn = ducument.getElementById('#btn');
 btn.addEventlistener('click',(ev)=>{
 console.log(ev.target);//此处的ev就是事件对象
  //ev.target指的就是点击的那个元素(实操的那个元素)也称为事件源
  //client 是鼠标点击的位置 到浏览器视口的偏移量
  //page 是鼠标点击的位置   到body的偏移量
 })

事件的传播机制

当点击子元素的时候不单单会触发子元素的事件,还会触发父元素的事件。但是点击父元素就没有这种情况,事件冒泡是从里到外传播的,看的是节点之间的关系。在事件对象Event中的stoPpropagation可以阻止这一行为,

 <div id="outer">
        <div id="center">
            <div id="inner">
            </div>
        </div>
    </div>
    
    //事件的冒泡传播 从里到外 看的是节点的关系
    outer.onclick = function() {
        console.log('点击了outer');
    }
    center.onclick = function() {
        console.log('点击了centerr');
    }
    inner.onclick = function(e) {
        e.stopPropagation(); //阻止冒泡
        //当事件传播到outer之后 阻止继续向上冒泡
        console.log('点击了inner');
    }

阻止a标签的默认行为

<a href="baidu.com" id=“a”>
let a = document.getElementById('#a');
//先执行事件的回调函数 后走默认行为
a.onclick = (ev)=>{
ev.preventDefault();//点击a标签不再跳转
}
ev.preventDefault();与<a href="javascript:;"> 功能相同

事件对象练习

拖拽练习

    <div id="box" style="width: 200px;height: 200px;background-color: pink;cursor: move;"></div>
    
//js部分
    let x = 0,
        y = 0; //用来存储盒子移动之前的偏移量的
    let box = document.getElementById('box');
    //鼠标按键按下
    box.onmousedown = function(e) {
    //pageX || pageY表示 鼠标距离body的偏移量
    //startX || startY  表示盒子距离body的距离
        this.startX = e.pageX;
        this.startY = e.pageY;
        //鼠标移动
        document.onmousemove = function(e) {
            let moveX = e.pageX - box.startX, // 鼠标的横向偏移
                moveY = e.pageY - box.startY; // 鼠标的纵向偏移
            box.style.transform = `translate(${moveX+x}px,${moveY+y}px)`
                //盒子在移动的时候的偏移量 是她的基础偏移量+鼠标偏移量
        }
        //鼠标按键抬起
        document.onmouseup = (e) => {
        //按键抬起记录当前位置
            x += e.pageX - this.startX;
            y += e.pageY - this.startY;
            //移除事件
            document.onmousemove = null;
            document.onmouseup = null;
        }
    }

京东放大镜

//css部分
<style>
        #box {
            width: 300px;
            height: 300px;
            border: solid 1px #ccc;
            float: left;
            position: relative;
        }
        #box img {
           width: 100%;
            height: 100%;
        }
        #box2 {
            width: 600px;
           height: 600px;
            border: solid 1px pink;
            float: left;
            display: none;
            overflow: hidden;
        } 
        #box2 img {
            width: 200%;
            height: 200%;
        }
        .mask {
            width: 100px;
            height: 100px;
            background: rgba(0, 0, 0, 0.3);
            cursor: move;
            position: absolute;
            top: 0;
            left: 0;
            z-index: 30;
            display: none;
        }
    </style>
//HTML部分
  <div id="box">
        <!-- 小图盒子 -->
        <img src="https://img12.360buyimg.com/n1/s450x450_jfs/t1/121591/31/27770/108029/6264bf67E2566526f/0f6456a0160c2dae.jpg
">
        <div class="mask"></div>

    </div>
    <div id="box2">
        <!-- 大图盒子 -->
        <img src="https://img12.360buyimg.com/n1/s450x450_jfs/t1/121591/31/27770/108029/6264bf67E2566526f/0f6456a0160c2dae.jpg
">
    </div>
    
   //js部分
   <script>
    (function() {
        class magniFier {
            constructor(id, id1) {
                this.box1 = document.querySelector(id);
                this.box2 = document.querySelector(id1);
                this.img = this.box2.querySelector('img');
                this.mask = this.box1.querySelector('.mask')
                this.img.style.width = '300%';
                this.img.style.height = '300%';
                this.bindEvent();
            }

            bindEvent() {
                this.box1.onmousemove = (e) => {
                    let obj = this.box1.getBoundingClientRect();
                    let x = e.clientX - obj.left - 50,
                        y = e.clientY - obj.top - 50;
                    if (x <= 0) x = 0;
                    if (y <= 0) y = 0;
                    if (x >= 200) x = 200;
                    if (y >= 200) y = 200;
                    this.mask.style.transform = `translate(${x}px,${y}px)`;
                    this.img.style.transform = `translate(${-x*6}px,${-y*6}px)`
                }
                this.box1.onmouseenter = () => {

                    this.box2.style.display = 'block';
                    this.mask.style.display = 'block';
                }
                this.box1.onmouseleave = () => {
                    this.box2.style.display = 'none';
                    this.mask.style.display = 'none';

                }
            }
        }
        window.magniFier = magniFier;
    })();
    new magniFier('#box', '#box2')
</script>

简易穿梭框

        #box1 {
            position: absolute;
            width: 200px;
            height: 400px;
            background-color: antiquewhite;
            top: 0;
            left: 0
        }
        
        #box1 span {
            display: inline-block;
            padding: 10px;
            cursor: move;
            border-radius: 5px;
            border: 1px solid #ccc;
        }
        
        #box2 {
            position: absolute;
            left: 300px;
            width: 200px;
            height: 400px;
            top: 0;
            background-color: aqua;
        }
        
        #box2 span {
            display: inline-block;
            padding: 10px;
            border-radius: 5px;
            border: 1px solid #ccc;
        }
        
        #btn {
            width: 100px;
            height: 50px;
            border-radius: 15px;
            background-color: cornflowerblue;
            position: absolute;
            top: 450px;
            left: 200px;
        }
<div id="box1">
    </div>
    <div id="box2">
    </div>
    <button id="btn">确定</button>
    //js部分
     let ary = [{
        type: 'sex',
        lable: '性别',
        value: "男"
    }, {
        type: 'sex',
        lable: '性别',
        value: "女"
    }, {
        type: 'age',
        lable: '年龄',
        value: "10-30"
    }, {
        type: 'age',
        lable: '年龄',
        value: "30-60"
    }, {
        type: 'height',
        lable: '身高',
        value: ">180"
    }, {
        type: 'height',
        lable: '身高',
        value: "<180"
    }, {
        type: 'weight',
        lable: '体重',
        value: ">180"
    }, {
        type: 'weight',
        lable: '体重',
        value: "<180"
    }]

    let box2 = document.getElementById('box2'), //右侧容器
        box = document.getElementById('box1'), //左侧容器
        btn = document.getElementById('btn'), //按钮
        moveTer = null; //被拖拽的元素
    box.ondragstart = (e) => {
        //拖拽事件 拖拽开始
        moveTer = e.target
    }
    let obj = {};
    box2.ondrop = function() {
        //鼠标按键抬起
        this.style.backgroundColor = 'aqua';
        let ele = moveTer.cloneNode(true); //克隆当前节点(当前拖动的元素)
        let n = ele.dataset.index; //获取元素自定义属性
        ele.setAttribute('draggable', false); //设置拖动属性
        //用新的把旧的顶替掉 防止标签重复
        if (obj[ary[n].type]) {
            let str = ary[n].lable; //二维数组属性名
            let list = box2.querySelectorAll('span'); //已经在box2中的标签
            [...list].forEach(item => {
                if (item.innerText.includes(str)) {
                    //如果重复 删除旧的  添加新的
                    box2.removeChild(item);
                    box2.appendChild(ele);
                }
            })
        } else {
            //没有重复项 就直接添加
            box2.appendChild(ele)
        }
        obj[ary[n].type] = ary[n].value;
        console.log(obj);
    }
    box.ondragend = () => {
        moveTer = null; //松手之后
    }
    box2.ondragenter = function() {
        //鼠标进入  右侧容器变色
        this.style.backgroundColor = 'pink'
    }
    box2.ondragleave = function() {
        //鼠标离开  右侧容器变为初始颜色
        this.style.backgroundColor = 'aqua'
    }
    box2.ondragover = function(e) {
        //鼠标滑过 
        e.preventDefault();

    }
    let str = ``
    ary.forEach((item, index) => {
        str += `<span draggable="true" data-index="${index}">${item.lable}${item.value}</span>`;
        box.innerHTML = str
    })

事件委托

利用事件冒泡的机制我们可以只给父元素一个元素绑定事件,大大减少内存的消耗,事件委托的原理就是事件冒泡+事件源;

  <ul id='ul'>
        <li>1
            <div>
                <h2>wer</h2>
                <div>
                    <div>666</div>
                </div> <button>按钮<i>666</i></button></li>
        <li>2
            <div>
                <h2>wer</h2>
                <div>
                    <div>666</div>
                </div> <button>按钮<i>666</i></button></li>
    </ul>
    
    let ul = document.queryselector('ul');
     ul.onclick = function(e) {
        let tar = e.target;
        tar.qqq = 100
        tar.setAttribute('qqq', 333)
        while (true) {
            console.log(tar);
            if (tar.tagName.toLowerCase() == 'li') {
                console.log(tar.innerHTML)
                return;
            } else if (tar.tagName.toLowerCase() == 'ul') {
                return
            } else {
                tar = tar.parentNode
            }
        }
    }

事件是js中非常重要的一个知识点,在我们日常的日常开发中使用非常频繁,事件是在编程时系统内发生的动作或者发生的事情,系统响应事件后,如果需要,可以用某种方式对事件做出回应。例如:如果用户在网页上单击一个按钮,您可能想通过显示一个信息框来响应这个动作。