JavaScript面对对象构造函数实战之drag实现元素拖拽操作,事件绑定中的this指向

首先先来看一下面对过程语句中对拖拽操作的代码实现,然后再看面对对象进行对比

 

先来看个图解,也就是下面用到的变量解释

对应代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        #div1{
            height: 200px;
            width: 200px;
            background: blueviolet;
            position: absolute;
            left: 20px;
            top: 100px;
        }
    </style>
    <script>
        
        window.onload = function(){
            var oDiv = document.getElementById("div1");    //获取元素

            oDiv.onmousedown = function(ev){          //在oDiv元素上设置onmousedown事件
                var e = ev || window.event;            //应对浏览器兼容问题
                var offsetX = e.pageX - oDiv.offsetLeft;      //计算X轴上的坐标,使页面上的X轴的坐标减去oDiv的left偏离,来得到鼠标在当前oDiv上的位置
注意:不是鼠标在页面上的位置,而是以oDiv的左上角为基准计算鼠标在oDiv上的X轴对应位置
var offsetY = e.pageY - oDiv.offsetTop;      //计算Y轴    document.onmousemove = function(ev){ //在document上设置onmousemove事件 var e = ev || window.event;     oDiv.style.left = e.pageX - offsetX + "px";    //计算oDiv这个物体应得的left定位值,鼠标在页面上的X轴位置减去鼠标在oDiv上的X轴位置就等于oDiv的left值 oDiv.style.top = e.pageY - offsetY + "px";      //由于返回number类型所以要拼接px单位 } } oDiv.onmouseup = function(){      //当鼠标抬起时取消document.onmousemove的对应功能,这一切都发生document上 document.onmousemove = null; } } </script> </head> <body> <div id="div1"></div> </body> </html>

 

 

再来看一下实现相同功能的面对对象的相对应代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        *{
            margin: 0;
            padding: 0;
        }
        #div1{
            height: 200px;
            width: 200px;
            background: blueviolet;
            position: absolute;             
            left: 20px;
            top: 100px;
        }
    </style>
    <script>
        
        function Drag(id) {
            this.oDiv = document.getElementById(id);   //通过传入一个可以自定义的id值来实现相对应的参数,以便于使用,id名千万不能写死
            var _this = this;                           //通过中间变量_this来存储当前对象的this
            this.oDiv.onmousedown = function(ev){       //获取事件
                _this.funcDown(ev);                     //调用通过new来创建的对象的funcDown方法,如果此处没有中间变量_this,则指向oDiv元素对象,应该指向的是Drag函数生成的object对象,如果指向oDiv,oDiv中没有funcDown方法,无法实现拖拽
            };
            document.onmouseup = this.funcUp;           //这个不使用中间变量的原因是this指向document,而我们需要它指向的就是document
        }

        Drag.prototype.funcDown = function(ev){
            var e = ev || window.event;
            this.offsetX = e.pageX - this.oDiv.offsetLeft;
            this.offsetY = e.pageY - this.oDiv.offsetTop;

            var _this = this;                       //改变this指向,使它指向对象而不是document,因为需要调用的funcMove是Drag对象的方法
            document.onmousemove = function(ev){
                _this.funcMove(ev);
            };
        }
        Drag.prototype.funcMove = function(ev){
            var e = ev || window.event;

            this.oDiv.style.left = e.pageX - this.offsetX + "px";
            this.oDiv.style.top = e.pageY - this.offsetY + "px";
        }
        Drag.prototype.funcUp = function(){
            document.onmousemove = null;
        }

        window.onload = function(){
            new Drag("div1");
        }
    </script>
</head>
<body>
    <div id="div1"></div>
</body>
</html>

 

 

总结:

  1、什么时候属性需要定义为函数的属性?也就是this.属性名的形式

   构造函数中那些属性需要跨函数使用则声明成构造函数的属性

  2、什么时候需要声明中间变量来改变this指向

   首先我们要明确自己的需求,案例中通过中间变量来改变this属性的都使用了对象中的方法funcMove,funcUp等等,而如果不声明中间变量那么此时this的主人不是drag对象,当然也没有drag中对应的方法,最终最会报错无法执行,所以首先要学习当前this指向了谁,然后确定自己的需求也就是需要this指向谁

  3、除了声明中间变量还有那些方法可以改变this指向?

   可以通过bind()方法来改变this指向,也可以通过箭头函数来改变,具体原理可以通过百度知晓,一句两句话概括不完

  4、为什么要使用面对对象构造方法

   因为面对对象构造方法拥有继承和多态的特性,有利于后期开发和拓展,极大降低修改时间与成本,所以面对对象的趋势愈发猛烈。虽然过程有些许抽象,但是最终调用只需要一两句代码即可实现!花大量时间封装自己的js库也可以提升自身的开发效率

 

有其他疑问可以留言私信哦。

 

posted @ 2020-11-13 21:19  丨树街猫  阅读(186)  评论(0编辑  收藏  举报