摘要:上篇文章分享了如何用面向對象思想編寫選項卡,在文章最后留了一個拖拽的例子,希望大家可以試著寫一下,現在我就談談我在這過程中遇到的一些問題和解決方法。通過以上方法來訓練面向對象的編程思想,多練習,以后寫出面向對象思想的代碼就很簡單了。
上篇文章分享了如何用面向對象思想編寫選項卡,在文章最后留了一個拖拽的例子,希望大家可以試著寫一下,現在我就談談我在這過程中遇到的一些問題和解決方法。(本文主要是想和js初學者分享經驗,代碼中的更改this指向,事件綁定均采用的比較初級的方法,也希望能有大神能指導,分享一下經驗)。
現在我們來看看面向過程式的編程的代碼,HTML只有一個div元素,設置寬高和背景顏色。
#div1{ width: 100px; height: 100px; background: red; position: absolute; } window.onload=function(){ var oDiv=document.getElementById("div1"); var disX=0; var disY=0; oDiv.onmousedown=function(ev){ var ev=ev || window.event; disX=ev.clientX-oDiv.offsetLeft; disY=ev.clientY-oDiv.offsetTop; document.onmousemove=function(ev){ var ev=ev || window.event; oDiv.style.left=ev.clientX-disX+"px"; oDiv.style.top=ev.clientY-disY+"px"; }; document.onmouseup=function(){ document.onmousemove=null; document.onmouseup=null; } return false; } }
還是用上一篇文章提到的方法,先將變量和方法提取出來,不要出現函數的嵌套,出現嵌套的將其中的函數提取出來。變量為oDiv,disX和disY,我將代碼中的三個事件綁定的函數命名為fnDown,fnMove,fnUp,因此將上面的代碼改為如下格式:
var oDiv,disX,disY; window.onload=function(){ oDiv=document.getElementById("div1"); disX=0; disY=0; oDiv.onmousedown=fnDown(); } function fnDown(ev){ var ev=ev || window.event; disX=ev.clientX-oDiv.offsetLeft; disY=ev.clientY-oDiv.offsetTop; document.onmousemove=fnMove(); document.onmouseup=fnUp(); return false; } function fnMove=function(ev){ var ev=ev || window.event; oDiv.style.left=ev.clientX-disX+"px"; oDiv.style.top=ev.clientY-disY+"px"; }; function fnUp=function(){ document.onmousemove=null; document.onmouseup=null; }
然后用面向對象的思想將屬性和方法添加到對象中,并在屬性和方法前面加上this,因此改變的代碼如下:
window.onload=function(){ var d1=new Drag("div1"); d1.init(); }; function Drag(id){ this.oDiv=document.getElementById(id); this.disX=0; this.disY=0; }; Drag.prototype.init=function(){ this.oDiv.onmousedown=this.fnDowm(); }; Drag.prototype.fnDowm=function(ev){ var ev=ev || window.event; this.disX=ev.clientX-this.oDiv.offsetLeft; this.disY=ev.clientY-this.oDiv.offsetTop; document.onmousemove=this.fnMove(); document.onmouseup=this.fnUp(); return false; }; Drag.prototype.fnMove=function(ev){ var ev || window.event; this.oDiv.style.left=ev.clientX-this.disX+"px"; this.oDiv.style.top=ev.clientY-this.disY+"px"; }; Drag.prototype.fnMove=function(){ document.onmousemove=null; document.onmouseup=null; };
和前面一樣,找出其中this的指向錯誤并改正。但是除了this指向問題,上面還有一個關于事件的問題。document.onmousemove=this.fnMove();,向這樣在事件上添加方法的方式是不正確的,正確的調用方式是這樣:document.onmousemove=function(ev){};,因此將方法改為以下形式。
Drag.prototype.init=function(){ this.oDiv.onmousedown=function(ev){ var ev=ev || window.event; this.fnDown(ev); return false; }; }; Drag.prototype.fnDown = function(ev){ this.disX = ev.clientX - this.oDiv.offsetLeft; this.disY = ev.clientY - this.oDiv.offsetTop; document.onmousemove = function(ev){ var ev = ev || window.event; this.fnMove(ev); }; document.onmouseup=function(){ this.fnUp(); } }; Drag.prototype.fnMove=function(ev){ this.oDiv.style.left=ev.clientX-this.disX+"px"; this.oDiv.style.top=ev.clientY-this.disY+"px"; }; Drag.prototype.fnUp=function(){ document.onmousemove=null; document.onmouseup=null; };
最后要找到錯誤的this指向,并改正。關于this指向,我認為最簡單的方法就是看函數是怎么調用的,函數名 "." 左邊的就是this的指向。下面我們來舉個例子:
Drag.prototype.init=function(){ this.oDiv.onmousedown=function(ev){ var ev=ev || window.event; this.fnDown(ev); return false; }; };
原型上面的init()方法的調用方式是d1.init(),因此函數內的this指向就是d1,那么this.oDiv指向就是正確的,但是onmouseover()的調用方式是this.oDiv.onmousedown,其內部this指向就是this.oDiv,而在該函數內部,this.fnDown(ev)語句this指向是oDiv,而oDiv是沒有方法和屬性的,因此這里的this指向就是錯誤的,需要修正。
下面的幾個方法中this也這來來分析,并將其改為正確的指向。修改this的指向還是和上一篇修改的方法一樣。因此改完后代碼為:
window.onload=function(){ var d1=new Drag("div1"); d1.init(); }; function Drag(id){ this.oDiv=document.getElementById(id); this.disX=0; this.disY=0; } Drag.prototype.init=function(){ var This=this; this.oDiv.onmousedown=function(ev){ var ev=ev || window.event; This.fnDown(ev); return false; }; }; Drag.prototype.fnDown = function(ev){ var This = this; this.disX = ev.clientX - this.oDiv.offsetLeft; this.disY = ev.clientY - this.oDiv.offsetTop; document.onmousemove = function(ev){ var ev = ev || window.event; This.fnMove(ev); }; document.onmouseup=function(){ This.fnUp(); } }; Drag.prototype.fnMove=function(ev){ this.oDiv.style.left=ev.clientX-this.disX+"px"; this.oDiv.style.top=ev.clientY-this.disY+"px"; }; Drag.prototype.fnUp=function(){ document.onmousemove=null; document.onmouseup=null; };
這樣就可以正常運行了。
作為一名小白,就應該多動腦,多動手。在這過程中你會學到很多。通過以上方法來訓練面向對象的編程思想,多練習,以后寫出面向對象思想的代碼就很簡單了。
因為以上代碼也是我通過看視頻學的,所以還有點疑問,希望有人能解答一下。上面只有onmousedown時間是綁定在oDiv上,后面的時間都是綁定在document上,我試著將后面的事件也綁定在oDiv中,程序也能運行,但是快速拖動就會產生停頓的問題,而在document上就沒有類似的情況,這是為什么?
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/82399.html
摘要:根據以上代碼的變形,我們現在用面向對象思想來編寫代碼,創建構造函數,添加屬性及方法。首先構造函數中的,由于是用關鍵字,因此指向,沒問題。同時將指向當前點擊的以參數形式傳入中,這樣一個面向對象思想的代碼就寫出來了。 ??本人自學前端近半年,js達到熟練的水平,面向對象思想、this指向有一定的了解,但是要用面向對象思想寫代碼就一臉懵逼了,最近看到某課堂的視頻(里面廣告嫌疑,就不說是啥了)...
摘要:前面幾篇文章,我跟大家分享了的一些基礎知識,這篇文章,將會進入第一個實戰環節利用前面幾章的所涉及到的知識,封裝一個拖拽對象。不封裝對象直接實現利用原生封裝拖拽對象通過擴展來實現拖拽對象。 showImg(https://segmentfault.com/img/remote/1460000008699587); 前面幾篇文章,我跟大家分享了JavaScript的一些基礎知識,這篇文章,...
摘要:個人前端文章整理從最開始萌生寫文章的想法,到著手開始寫,再到現在已經一年的時間了,由于工作比較忙,更新緩慢,后面還是會繼更新,現將已經寫好的文章整理一個目錄,方便更多的小伙伴去學習。 showImg(https://segmentfault.com/img/remote/1460000017490740?w=1920&h=1080); 個人前端文章整理 從最開始萌生寫文章的想法,到著手...
閱讀 3048·2021-11-25 09:43
閱讀 1027·2021-11-24 10:22
閱讀 1353·2021-09-22 15:26
閱讀 682·2019-08-30 15:44
閱讀 2463·2019-08-29 16:33
閱讀 3684·2019-08-26 18:42
閱讀 908·2019-08-23 18:07
閱讀 1832·2019-08-23 17:55