• 第6天-javascript事件


    什么是事件

    事件是用户在访问页面执行时的操作,也就是用户访问页面时的行为。当浏览器探测到一个事件时,比如鼠标点击或者按键。它可以触发与这个事件相关的JavaScript对象(函数),这些对象成为事件处理程序。

    事件函数绑定

    事件函数:当事件发生了,用于处理该事件的具体应对方案,表现出来就是一些代码块。例如:当鼠标点击(事件)---做什么操作?就由处理函数来完成

    总结:

    注意的就是事件发生和事件处理函数是不同的概念

    事件发生以后,可以有事件处理函数来做对应的事情,也可以没有

    如果没有事件处理函数,不会影响事件的发生,该发生的还是会发生,至于做什么事情,由事件处理函数来决定

    <button id="btn1">按钮1</button>
    <button id="btn2">按钮2</button>
    
    <script>
        oBtn1 = document.getElementById('btn1');
        oBtn2 = document.getElementById('btn2');
        
        oBtn1.onclick = function(){
            alert('hello world');
        }
        
        oBtn2 = null
    </script>
    事件函数绑定

    鼠标事件

    onmousedown 当鼠标按下的时候触发
    onmouseup 当鼠标抬起的时候触发
    <div id="box" style=" 100px; height: 100px; background-color: red;"></div>
    
    <script>
        oBox = document.getElementById('box');
        oBox.onmousedown = function(){
            oBox.style.backgroundColor = 'green';
        };
        
        oBox.onmouseup = function(){
            oBox.style.backgroundColor = 'orange';
        };
    </script>
    示例
    onmouseover 当鼠标移入的时候触发
    onmouseout 当鼠标移出的时候触发
    <style>
        a{    
            padding: 20px;
            text-decoration: none;
            color: black;
        }
    </style>
    
    ...
    
    <a href="#">首页</a>
    <a href="#">产品介绍</a>
    <a href="#">关于我们</a>
    
    <script>
        //找到a标签
        aA = document.getElementsByTagName('a');
        //oA是一个数组,遍历出每个a标签
        for(i in aA){
            //鼠标移入事件
            aA[i].onmouseover = function(){
                //如何确定是哪个a标签,可以使用this
                //onsole.log(this)
                this.style.backgroundColor = 'red';
                this.style.color = 'white';
            };
            //鼠标移出事件
            aA[i].onmouseout = function(){
                this.style.backgroundColor = 'white';
                this.style.color = 'black';
            };
        }
    </script>
    示例
    onclick 当鼠标点击的时候触发
    ondblclick 当鼠标双击的时候触发
    onmousemove 当鼠标移动的时候触发
    oncontextmenu  当鼠标右键的时候触发(可以定义右键菜单)
    <button>按钮</button>
    
    <script>
        //通过标签获取元素,获取到的是一个数组
        oBtn = document.getElementsByTagName('button');
        
        //鼠标双击,因为是数组,所以必须要oBtn加索引才能获取到具体的元素
        oBtn[0].ondblclick = function(){
            alert('鼠标双击了');
        }
        
        //鼠标移动事件
        document.onmousemove = function(){
            console.log('鼠标移动了');
        }
        
        //鼠标右键事件
        document.oncontextmenu = function(){
            alert('右键显示菜单');
            //阻断原来的右击动作
            return false;
        }
    </script>
    示例

    键盘事件

    onkeydown 当键盘按下的时候触发
    onkeyup 当键盘抬起的时候触发
    <script>
        //键盘按下
        document.onkeydown = function(){
            console.log('键盘按下');
            //alert('键盘按下')   这个会阻断事件,导致键盘抬起的动作函数不会执行
        }
        
        document.onkeyup = function(){
            console.log('键盘抬起');
        }        
    </script>
    示例

    那么键盘事件有什么使用场景呢。比如:百度搜索框,当我们输入完关键字,按下回车键后,就会执行搜索

    <script>
        //传一个事件参数
        document.onkeydown = function(evt){
            console.log(evt);
        }
    </script>
    示例

    然后我们随便按一个键盘,查看console, 有一项 keyCode(键盘码),每一个按键都有一个唯一的keyCode

    我们可以,这样,来按下回车键,查看到回车键的keyCode为13

    <script>
        document.onkeydown = function(evt){
            //console.log(evt);
            console.log(evt.keyCode);
        }
    </script>
    示例

    因此,我们可以这样模拟回车搜索

    <script>
        //键盘按下
        document.onkeydown = function(evt){
            if(evt.keyCode === 13){
                alert('开始搜索..');
            }
        }
    </script>
    示例

    表单事件

    onsubmit  当表单提交的时候触发

    <form action="https://www.baidu.com/s">
        <input name="wd" id='ipt' />
        <button type="submit">提交</button>
    </form>
    
    <script>
        oForm = document.getElementsByTagName('form');
        oIpt = document.getElementById('ipt');
        oForm[0].onsubmit = function(){
            iptValue = oIpt.value;
            if (iptValue == ''){
                alert('内容不能为空');
                //return flase可以阻止提交
                return false;
            };
            
            return true;    
        };
    </script>
    示例

    onchange 当修改表单字段的时候会触发(内容改变就会触发)

    商品单价: <span id="price">198</span> <br/>
    商品数量:<input id="ipt1" type="text" value="1" />
    商品总价:<input id="ipt2" type="text" value="198">
    
    <script>
        var oIpt1 = document.getElementById('ipt1');
        oIpt1.onchange = function(){
            var price = document.getElementById('price').innerHTML;
            var oIpt2 = document.getElementById("ipt2");
            oIpt2.value = price * this.value;
        };
    </script>
    示例
    <form action="https://www.baidu.com/s" id="fm">
        <input id="ipt" type="text" value="请输入搜索内容" name="wd"/>
    </form>
    
    <script>
        var oIpt = document.getElementById('ipt');
        
        //获取焦点事件
        oIpt.onfocus = function(){
            //把输入框内容清空
            oIpt.value = "";
        };
        
        //失去焦点事件
        oIpt.onblur = function(){
            //让输入框内容恢复原样,当用户没有输入内容的时候
            if(oIpt.value == ""){
                oIpt.value = "请输入搜索内容";
            };    
        }
        
        //按回车键表单会自动提交到action设置的地址,浏览器的默认行为
        //当用户没有输入内容的时候,提示不能提交,只有当用户输入内容后才可以提交
        var oForm = document.getElementById("fm");
        oForm.onsubmit = function(){
            if(oIpt.value == ""){
                alert('内容不能为空');
                return false;
            };
        };
    </script>
    获取焦点和失去焦点事件

    窗口事件

    onload 当对象加载完成以后触发

    要解决这个问题,我们就需要当整个对象加载完再执行,这样就不会报错了

     onresize   当窗口改变的时候的触发

    <script>
         window.onresize = function(){
            //窗口改变的时候去计算宽高,来做布局
            //获取浏览器可视区的高端
            console.log(document.documentElement.clientHeight);
            console.log(document.documentElement.clientWidth);
         }
    </script>
    示例

    事件对象 event以及兼容性

    事件对象就是当事件发生的时候,用来记录事件的相关信息的对象

    <script>
        alert(event);
        window.onload = function(){
            alert(event); //object event
            console.log(event);
        }
        
        //注意 :必须要在事件发生的时候才有值,否则就是undefined
        //兼容性问题
        //    1、在IE和chrome下event对象是内置的,直接使用event就可以了, 在火狐下不支持
        //  2、在火狐和chrome下事件对象是事件处理函数的第一个参数,在ie低版本下不支持
        window.onload = function(evt){
            alert(evt); //object event
            console.log(evt);
        } 
        //如果要解决兼容性,可以这样
        window.onload = function(evt){
            var ev = evt || event;
            alert(ev);
        }
    </script>
    事件对象及兼容性

    event对象上的属性 clientX, clientY

    clientX和clientY是鼠标指针在浏览器页面可视区的坐标

    <div id="box" style="height: 200px; background-color: orange;"></div>
    
    <script>
        oBox = document.getElementById('box');
        oBox.onclick = function(event){
            console.log('x',event.clientX, 'y',event.clientY);
        }
    </script>

     百度登录拖拽效果前置知识-offsetLeft和offsetTop

    <style type="text/css">
        #box{
            height: 200px;
             200px;
            background-color: red;
            position: absolute;
            left: 0px;
            top: 30px;
        }
    </style>
     
     ...
     
    <script>
        //基本思想:要让div移动,可以通过改变left和top值
        //通过js来动态改变
        //条件:需要知道如何获取left值和top值
        oBox = document.getElementById('box');
        oBox.onclick = function(){
            console.log(oBox.offsetLeft, oBox.offsetTop);
        }
    </script>

     拖拽效果

    <style type="text/css">
        #box{
            height: 200px;
             200px;
            background-color: orange;
            position: absolute;
            left: 0;
            top: 0;
        }
    </style>
    
    ...
    <div id="box"></div>
    <script>
        var oBox = document.getElementById('box');
        oBox.onmousedown = function(event){
            var difX = event.clientX - oBox.offsetLeft;
            var difY = event.clientY - oBox.offsetTop;
            //鼠标移动
            oBox.onmousemove = function(event){
                oBox.style.left = event.clientX - difX + "px";
                oBox.style.top = event.clientY - difY + "px";
                    
            };
            //鼠标抬起后,box不再移动
            oBox.onmouseup = function(){
                oBox.onmousemove = null;
            }
        }
    </script>
    
    
    //这段代码实现了拖拽效果
    //但是当快速移动鼠标的时候还有问题,这个后面再解决
    拖拽效果代码实现

     事件冒泡机制

    当一个元素接收到一个事件以后,会将事件传播给它的父级元素,它的父级元素会一层一层往上传播,直到最顶层的window,这种事件传播机制叫做事件冒泡

    <style type="text/css">
            #box1{
                height: 400px;
                 400px;
                background-color: green;
                margin: 0 auto;
            }
            
            #box2{
                height: 300px;
                 300px;
                background-color: orange;
                margin: 0 auto;
            }
            
            #box3{
                 200px;
                height: 200px;
                background-color: red;
                margin: 0 auto;
            }
    </style>
    
    ...
    
    <script>
        var oBox1 = document.getElementById('box1');
        var oBox2 = document.getElementById('box2');
        var oBox3 = document.getElementById('box3');
        
        function fn(event){
            alert(this.id);
        }
        
        oBox1.onclick = fn;
        oBox2.onclick = fn;
        oBox3.onclick = fn;
        
    </script>
    示例

    当点击div3的时候,先触发div3的点击事件,弹出div3的id值为box3

    然后把点击事件传给父级元素div2,触发div2的点击事件,div2绑定了事件处理函数fn,因此会弹出div2的id属性值box2

    接着div2再把点击事件传播给div1,div1同样也绑定了事件处理函数,弹出id值为box1

    div1再往上传播点击事件,由于div1的父级没有绑定事件处理函数,所以没有弹出值,但是div1的父级还是接收了点击事件,只是没有做出响应

    这个就是冒泡机制的全过程,冒泡机制在javascript中是默认存在的

     事件冒泡带来的影响

    <style type="text/css">
        #box{
             300px;
            height: 300px;
            background-color: orange;
            display: none;
        }
    </style>
    ...
    
    <button id="btn">显示</button>
    <div id="box"></div>
    
    <script>
        var oBtn = document.getElementById('btn');
        var oBox = document.getElementById('box');
        
        //点击按钮显示div, 但是因为冒泡机制,会触发它的父级onclick时间,而document的onclick时间处理函数有把div隐藏
        //因此时间冒泡机制会导致div不能显示出来
        oBtn.onclick = function(){
            oBox.style.display = 'block';
        }
        
        document.onclick = function(){
            oBox.style.display = 'none';
        }
    </script>
    事件冒泡机制带来的影响
    ...
    <script>
        var oBtn = document.getElementById('btn');
        var oBox = document.getElementById('box');
        
        oBtn.onclick = function(event){
            oBox.style.display = 'block';
            event.stopPropagation(); //阻止冒泡
        }
        
        document.onclick = function(){
            oBox.style.display = 'none';
        }
    </script>
    阻止事件冒泡

    事件冒泡带来的好处

    虽然事件冒泡带来了一些不好的影响,但是可以通过取消事件冒泡来解决,之所以默认事件冒泡机制开启,是因为事件冒泡会节省很多代码。例如:有一个需求,点击一个按钮,显示div,点击除按钮外的其他元素,需要隐藏div ,这个时候有两种解决方案。第一种,找到页面中除了按钮外的其他元素,都给这些元素加点击事件,然后隐藏div。这一种如果页面中有几百个元素,那么实现起来就相当复杂,因此不能采用。第二种解决方案,给这些元素的共同父级加点击事件,当这些元素触发点击事件以后,把事件传播给父级元素的点击事件,这样就节省很多代码,也就是上面案例中的应用实现。

     事件源

    <ul>
        <li>python</li>
        <li>Java</li>
        <li>Golang</li>
    </ul>
    
    <script>
        //我们已经学习过事件冒泡机制
        //现在在li的父级元素配置点击事件,那么子元素li点击就会传播到ul的点击事件
        
        var oUl = document.getElementsByTagName('ul')[0];
        //那么当点击li的时候,我们怎么知道点击了哪个li呢?这就需要用到事件源了event.target
        oUl.onclick = function(event){
            console.log(event.target);
        }
    </script>
    事件源

    下面我们来完成一个小案例,在表单中输入内容,点击添加按钮,会把 表单的内容作为li元素追加到ul中,当点击li的时候,字体变成红色

    <input type="text" id="ipt" /> <button id="btn">添加</button>
    
    <ul>
        <li>Python</li>
        <li>Java</li>
        <li>Golang</li>
    </ul>
    
    <script>
        //找到input元素
        var oInput= document.getElementById('ipt');
        //找到按钮
        var oBtn = document.getElementById('btn');
        
        //找到ul
        oUl = document.getElementsByTagName('ul')[0];
        
        //找到li,注意这里获取到的是个数组
        var oLis = document.getElementsByTagName('li');
        
        //按钮点击事件
        oBtn.onclick = function(){
            //获取input的值
            var oInputvalue = oInput.value;
            //如果值为空则弹窗提示不能为空
            if(oInputvalue == ""){
                alert('值不能为空!');
                return  false;
            }
            
            //创建一个li元素
            var oLi = document.createElement('li');
            //li里面的内容为 input的值
            oLi.innerHTML = oInputvalue;
            //把这个li加入到ul中
            oUl.appendChild(oLi);
        }
        
        //设置li的点击事件,字体变为红色
        for(var i=0;i<oLis.length;i++){
            oLis[i].onclick = function(){
                this.style.color = "red";
            }
        }        
    </script>
    方案1

    这是为什么呢?

    这是因为先执行了循环,只有3个值,因为前面的3个可以正常变色。那么这种情况下,我们就可以不用循环,利用冒泡机制来解决

    把点击事件放在li的父级元素ul上(因为冒泡机制,点击li会传播到ul),然后根据事件源能够做到点击了哪个li,然后把它的字体变色

    //设置ul的点击事件
    oUl.onclick = function(event){
        event.target.style.color = "red";
    }

    前面我们还遗留了一个拖拽效果,速度变快出现 bug的问题,那是因为移动过快导致鼠标已经移出了div,从而导致oBox.onmousemove事件没有发生了。这个问题也可以通过冒泡机制解决,我们只要把鼠标按下,移动,抬起的事件绑定到它的父级元素document就可以了

  • 相关阅读:
    VHDL中常用函数类型转换程序包
    Error (10309): VHDL Interface Declaration error in keyboard.vhd(63): interface object "scan_code" of mode out cannot be read. Change object mode to bu
    堆排序
    死锁及如何处理死锁-转载
    红黑书——算法导论
    Randomize select algorithm 随机选择算法
    转载:MATLAB画图常用调整代码
    广告营销学术语
    使用weka进行Cross-validation实验
    设计一个简单的,低耗的能够区分红酒和白酒的感知器(sensor)
  • 原文地址:https://www.cnblogs.com/sellsa/p/9807467.html
Copyright © 2020-2023  润新知