你的浏览器不支持canvas

做你害怕做的事情,然后你会发现,不过如此。

《智能社:JavaScript教程——从入门到精通》第20~21集笔记 鼠标键盘事件

时间: 作者: 黄运鑫

本文章属原创文章,未经作者许可,禁止转载,复制,下载,以及用作商业用途。原作者保留所有解释权。


笔记目录

  1. 《智能社:JavaScript教程——从入门到精通》第1~5集笔记 事件
  2. 《智能社:JavaScript教程——从入门到精通》第6~10集笔记
  3. 《智能社:JavaScript教程——从入门到精通》第11~14集笔记 DOM操作和表格
  4. 《智能社:JavaScript教程——从入门到精通》第15~19集笔记 运动
  5. 《智能社:JavaScript教程——从入门到精通》第20~21集笔记 鼠标键盘事件
  6. 《智能社:JavaScript教程——从入门到精通》第22~23集笔记 事件高级应用
  7. 《智能社:JavaScript教程——从入门到精通》第24~25集笔记 Ajax
  8. 《智能社:JavaScript教程——从入门到精通》第26~29集笔记 面向对象
  9. 《智能社:JavaScript教程——从入门到精通》第30~31集笔记 坐标和cookie
  10. 《智能社:JavaScript教程——从入门到精通》第32集笔记 JS正则表达式
  • 本文为原创,转载请注明:https://blog.xinpapa.com/2017/12/13/zhinengshe20-21/

详细内容

1.event对象和事件冒泡

  • 什么是event对象
    • 用来获取事件的详细信息:鼠标位置、键盘按键
    • document的本质:document.childNodes[0].tagNamedocument包含整个页面;如果要给整个页面加事件,就可以给document
    • 例子:获取鼠标位置:chientXchientY
        document.onclick = function (ev) {
            //IE兼容event,火狐兼容ev,兼容性写法如下
            var oEvent = ev || event;
            alert(oEvent.clientX + "," + oEvent.clientY)
        };
      
  • 获取event对象(兼容性写法)
    • var oEvent=ev||event;
  • 事件流
    • 事件冒泡
      • 取消冒泡:oEvent.cancelbubble=true
      • DOM事件流
    • 例子:仿select控件
        #div1{
            width: 400px;
            height: 300px;
            background: #CCC;
            display: none;
        }
      
        <body>
            <input id="btn1" type="button" value="显示" />
            <div id="div1"></div>
        </body>
      
        window.onload = function () {
            var oBtn = document.getElementById("btn1");
            var oDiv = document.getElementById("div1");
            oBtn.onclick = function (ev) {
                var oEvent = ev || event;
                oDiv.style.display = "block";
                //取消oBtn的事件冒泡
                oEvent.cancelBubble = true;
            };
            document.onclick = function () {
                oDiv.style.display = "none";
            };
        };
      

2.鼠标事件

  • 鼠标位置
    • 可视区位置:clientXclientY
    • 例子1:跟随鼠标的div
      • 消除滚动条的影像
      • 滚动条的意义——可视区与页面顶部的距离
          #div1{
              width: 200px;
              height: 200px;
              background: red;
              position:absolute;
          }
        
          <body>
              <div id="div1"></div>
          </body>
        
          document.onmousemove = function (ev) {
              var oEvent = ev || event;
              var oDiv = document.getElementById("div1");
              var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
              //clientY是鼠标到可视区顶端的距离
              //oDiv.style.top是div到页面顶端的距离
              //scrollTop是可视区到页面顶端的距离
              //不加scrollTop页面上下滚动时会出问题
              //只要用到clientX和clientY时,一定要加上scrollTop
              oDiv.style.left = oEvent.clientX + "px";
              oDiv.style.top = oEvent.clientY + scrollTop + "px";
          };
        
      • 封装后js如下:
          document.onmousemove = function (ev) {
              var oEvent = ev || event;
              var oDiv = document.getElementById("div1");
              var pos = getPos(oEvent);
              var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
              oDiv.style.left = pos.x + "px";
              oDiv.style.top = pos.y + "px";
          };
          //得到鼠标位置的方法
          function getPos(ev) {
              var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
              var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
              return {x: ev.clientX + scrollLeft, y: ev.clientY + scrollTop};
          };
        
  • 获取鼠标在页面的绝对位置
    • 封装函数
    • 例子2:一串跟随鼠标的div
        div{
            width: 10px;
            height: 10px;
            background: red;
            position:absolute;
        }
      
        </head>```javascript<body>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
            <div></div>
        </body>
      
        document.onmousemove = function (ev) {
            var aDiv = document.getElementsByTagName("div");
            var oEvent = ev || event;
            var pos = getPos(ev);
            for (var i = aDiv.length - 1; i > 0; i--) {
                aDiv[i].style.left = aDiv[i - 1].offsetLeft + "px";
                aDiv[i].style.top = aDiv[i - 1].offsetTop + "px";
            }
            aDiv[0].style.left = pos.x + "px";
            aDiv[0].style.top = pos.y + "px";
        };
        //得到鼠标位置的方法
        function getPos(ev) {
            var scrollTop = document.documentElement.scrollTop || document.body.scrollTop;
            var scrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft;
            return {x: ev.clientX + scrollLeft, y: ev.clientY + scrollTop};
        };
      

3.键盘事件

  • keyCode
    • 获取用户按下键盘的哪个按键
    • 例子(键盘控制div移动):
        div{
            width: 100px;
            height: 100px;
            background: #CCC;
            position:absolute;
        }
      
        <body>
            <div id="div1"></div>
        </body>
      
        document.onkeydown = function (ev) {
            var oEvent = ev || event;
            var oDiv = document.getElementById("div1");
            if (oEvent.keyCode == 37) {
                oDiv.style.left = oDiv.offsetLeft - 10 + "px";
            } else if (oEvent.keyCode == 39) {
                oDiv.style.left = oDiv.offsetLeft + 10 + "px";
            }
        };
      
  • 其他属性
    • ctrlKeyshiftKeyaltKey
    • 例子(回车ctrl + 回车提交留言):
        <body>
            <input id="txt1" type="text" /><br/>
            <textarea id="txt2" rows="10" cols="40"></textarea>
        </body>
      
        window.onload = function () {
            var oTxt1 = document.getElementById("txt1");
            var oTxt2 = document.getElementById("txt2");
            oTxt1.onkeydown = function (ev) {
                var oEvent = ev || event;
                //oEvent.ctrlKey是按下ctrl的属性
                if (oEvent.keyCode == 13 && oEvent.ctrlKey) {
                    oTxt2.value += oTxt1.value + "\n";
                    oTxt1.value = "";
                }
            };
        };
      

4.默认行为

  • 默认行为就是浏览器自带的行为
  • 阻止默认行为
    • 普通写法:returnfalse;
        document.oncontextmenu = function () {
            return false;
        };
      
    • 例子1(屏蔽右键菜单)
        *{
            margin: 0;
            padding: 0;
            list-style: none;
        }
        #div1{
            position: absolute;
            width: 80px;
            background: #CCC;
            border: 1px black solid;
            display: none;
        }
      
        <body>
            <div id="div1">
                <ul>
                    <li>aaa</li>
                    <li>bbb</li>
                    <li>ccc</li>
                    <li>ddd</li>
                </ul>
            </div>
        </body>
      
        document.oncontextmenu = function (ev) {
            var oEvent = ev || event;
            var oDiv = document.getElementById("div1");
            oDiv.style.display = "block";
            oDiv.style.left = oEvent.clientX + "px";
            oDiv.style.top = oEvent.clientY + "px";
            return false;
        };
        document.onclick = function () {
            var oDiv = document.getElementById("div1");
            oDiv.style.display = "none";
        };
      
    • 例子2(只能输入数字的输入框,keydownkeyup事件的区别):
        <body>
            <input id="txt1" type="text" />
        </body>
      
        window.onload = function () {
            var oTxt = document.getElementById("txt1");
            oTxt.onkeydown = function (ev) {
                var oEvent = ev || event;
                if (oEvent.keyCode != 8 && (48 > oEvent.keyCode || oEvent.keyCode > 57) && (96 > oEvent.keyCode || oEvent.keyCode > 105)) {
                    //如果输入的不是数字键并且不是删除键,则不能输入
                    return false;
                }
            };
        };
      

5.拖拽

  • 简易拖拽
    • 拖拽原理
      • 距离不变
      • 三个事件
  • 靠谱拖拽
    • 原有拖拽的问题
      • 直接给document加事件
    • FF下,空div拖拽的bug
      • 阻止默认事件
    • 防止拖出页面
      • 修正位置
    • 代码如下:
        #div1{
            width: 200px;
            height: 200px;
            background: red;
            position: absolute;
        }
      
        <body>
            <div id="div1"></div>
        </body>
      
        window.onload = function () {
            var oDiv = document.getElementById("div1");
            var disX = 0;//得到鼠标按下时鼠标到div左边的距离
            var disY = 0;//得到鼠标按下时鼠标到div上边的距离
            oDiv.onmousedown = function (ev) {
                var oEvent = ev || event;
                disX = oEvent.clientX - oDiv.offsetLeft;
                disY = oEvent.clientY - oDiv.offsetTop;
                //当鼠标按下拖拽时,用鼠标的位置移动div
                document.onmousemove = function (ev) {
                    var oEvent = ev || event;
                    var l = oEvent.clientX - disX;
                    var t = oEvent.clientY - disY;
                    if (l < 0) {
                        l = 0;
                    } else if (l > document.documentElement.clientWidth - oDiv.offsetWidth) {
                        l = document.documentElement.clientWidth - oDiv.offsetWidth;
                    }
                    if (t < 0) {
                        t = 0;
                    } else if (t > document.documentElement.clientHeight - oDiv.offsetHeight) {
                        t = document.documentElement.clientHeight - oDiv.offsetHeight;
                    }
                    oDiv.style.left = l + "px";
                    oDiv.style.top = t + "px";
                };
                //鼠标抬起时,清除事件
                document.onmouseup = function () {
                    document.onmousemove = null;
                    document.onmouseup = null;
                };
                return false;//阻止默认事件,解决火狐空div拖拽bug
            };
        };
      

对于本文内容有问题或建议的小伙伴,欢迎在文章底部留言交流讨论。