原生js實(shí)現(xiàn)拖拽移動(dòng)與縮放效果
本文實(shí)例為大家分享了js實(shí)現(xiàn)拖拽移動(dòng)與縮放效果的具體代碼,供大家參考,具體內(nèi)容如下
效果圖如下-實(shí)現(xiàn)了簡(jiǎn)單的拖拽和縮放功能
第一步—簡(jiǎn)單的拖拽功能
// 創(chuàng)建一個(gè)MoveClass構(gòu)造函數(shù) function MoveClass(id, options = {}) { // 綁定ele屬性 this.ele = document.querySelector(id); this.move(); }
// 給MoveClass原型上綁定move方法 MoveClass.prototype.move = function () { // ele的鼠標(biāo)按下事件調(diào)用mousedown this.ele.onmousedown = e => { // 獲取事件對(duì)象 var e = e || window.event; // 鼠標(biāo)按下時(shí),鼠標(biāo)相對(duì)于元素的x坐標(biāo) var x = e.offsetX; // 鼠標(biāo)按下時(shí),鼠標(biāo)相對(duì)于元素的y坐標(biāo) var y = e.offsetY; // 鼠標(biāo)按下移動(dòng)時(shí)調(diào)用mousemove document.onmousemove = e => { // 元素ele移動(dòng)的距離l var l = e.clientX - x; // 元素ele移動(dòng)的距離l var t = e.clientY - y; this.ele.style.left = l + "px"; this.ele.style.top = t + "px"; } // 當(dāng)鼠標(biāo)彈起時(shí),清空onmousemove與onmouseup document.onmouseup = () => { document.onmousemove = null; document.onmouseup = null; } } } // new一個(gè)MoveClass對(duì)象 var moveClass = new MoveClass("#box");
效果如下,簡(jiǎn)單的拖拽
第二步—簡(jiǎn)單的縮放功能
1.設(shè)置方位
// ele的左,左上,左下,右,右上,右下,上,下 MoveClass.prototype.editoptions = { left_top: true, left: true, right: true, top: true, bottom: true, right_top: true, left_bottom: true, right_bottom: true, }
2.給原型綁定縮放的方法
// 給原型綁定縮放的方法 MoveClass.prototype.editEle = function () { // console.log(this.ele.clientWidth,this.ele.clientHeight); // console.log(this.ele.offsetLeft,this.ele.offsetTop); var that = this; // 創(chuàng)建一個(gè)div var div = document.createElement("div"); // 遍歷this.editoptions for (let attr in this.editoptions) { if (this.editoptions[attr]) { // 循環(huán)創(chuàng)建左,左上,左下,右,右上,右下,上,下方位的小點(diǎn) var dian = document.createElement("div"); dian.className = "dian " + attr; // 設(shè)置類型為對(duì)應(yīng)的attr dian.dataset.type = attr; // 當(dāng)按下對(duì)應(yīng)方位的小點(diǎn)時(shí) dian.onmousedown = e => { var e = e || window.event; // 先獲取鼠標(biāo)距離屏幕的left與top值 var clientXY = { x: e.clientX, y: e.clientY } // 獲取鼠標(biāo)按下時(shí)ele的寬高 var eleWH = { width: this.ele.clientWidth, height: this.ele.clientHeight, } // 阻止事件冒泡(針對(duì)父元素的move) e.stopPropagation(); // 通過(guò)e.target獲取精準(zhǔn)事件源對(duì)應(yīng)的type值 var type = e.target.dataset.type; // 鼠標(biāo)按下對(duì)應(yīng)方位小點(diǎn)移動(dòng)時(shí),調(diào)用mousemove document.onmousemove = function (e) { // 查找type中是否包含”right“ if (type.indexOf('right') > -1) { // console.log("right"); // 如果拖拽后的寬度小于最小寬度,就return出去 if (that.options.minWidth > eleWH.width + e.clientX - clientXY.x) { return; } // ele拖拽后的寬度為:初始width+拖拽后鼠標(biāo)距離屏幕的距離 - 第一次按下時(shí)鼠標(biāo)距離屏幕的距離 that.ele.style.width = (eleWH.width + e.clientX - clientXY.x) + "px"; } // 與”right“相同原理 if (type.indexOf("bottom") > -1) { // console.log("bottom"); if (that.options.minHeight > eleWH.height + e.clientY - clientXY.y) { return; } that.ele.style.height = (eleWH.height + e.clientY - clientXY.y) + "px" } if (type.indexOf("top") > -1) { // console.log("top"); if (that.options.minHeight > eleWH.height - e.clientY + clientXY.y) { return; } // ele拖拽后的高度為:初始height-拖拽后鼠標(biāo)距離屏幕的距離 + 第一次按下時(shí)鼠標(biāo)距離屏幕的距離 that.ele.style.height = (eleWH.height - e.clientY + clientXY.y) + "px"; // 重新設(shè)置ele的top值為此時(shí)鼠標(biāo)距離屏幕的y值 that.ele.style.top = e.clientY + "px"; } // 與”top“相同原理 if (type.indexOf("left") > -1) { // console.log("left"); if (that.options.minWidth > eleWH.width - e.clientX + clientXY.x) { return; } that.ele.style.width = (eleWH.width - e.clientX + clientXY.x) + "px"; // 重新設(shè)置ele的left值為此時(shí)鼠標(biāo)距離屏幕的x值 that.ele.style.left = e.clientX + "px"; } } document.onmouseup = function () { document.onmousemove = null; document.onmouseup = null; } } } // 將類名為”dian“的div添加到div中 div.appendChild(dian); } // 為div設(shè)置類名 div.className = "kuang" // 將類名為”kuang“的div添加到ele中 this.ele.appendChild(div); }
效果圖如下
最終效果,盒子可以拖動(dòng),可以縮放。
盒子上的8個(gè)小點(diǎn)采用定位放上去的,事先寫(xiě)好了樣式
<style> * { margin: 0; padding: 0; } #box { width: 100px; height: 100px; background: orange; position: absolute; left: 100px; top: 100px; } .kuang { box-sizing: border-box; border: 1px solid #0f0; width: 100%; height: 100%; position: relative; } .kuang .dian { position: absolute; width: 10px; height: 10px; border-radius: 50%; background: #0f0; } .left_top { left: -5px; top: -5px; } .right_top { right: -5px; top: -5px; } .left_bottom { left: -5px; bottom: -5px; } .right_bottom { right: -5px; bottom: -5px; } .top { top: -5px; left: 50%; transform: translateX(-50%); } .bottom { bottom: -5px; left: 50%; transform: translateX(-50%); } .left { left: -5px; top: 50%; transform: translateY(-50%); } .right { right: -5px; top: 50%; transform: translateY(-50%); } </style>
<body> <div id="box" class="border"></div> </body>
所有的代碼能直接粘貼使用??s放的原理其實(shí)就是鼠標(biāo)按下去時(shí),獲取當(dāng)前的鼠標(biāo)位置和盒子的寬高,鼠標(biāo)按下并移動(dòng)后獲取此時(shí)的鼠標(biāo)位置。
拖拽后的寬高=初始寬高+(拖拽后鼠標(biāo)距離屏幕的位置 - 第一次按下時(shí)鼠標(biāo)距離屏幕的位置)。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
JS中prototype關(guān)鍵字的功能介紹及使用示例
prototype 關(guān)鍵字可以為JS原有對(duì)象或者自己創(chuàng)建的類中添加方法或者屬性。也可以實(shí)現(xiàn)繼承,下面以實(shí)例的方式為大家詳細(xì)介紹下2013-07-07javascript 簡(jiǎn)單高效判斷數(shù)據(jù)類型 系列函數(shù) By shawl.qiu
javascript 簡(jiǎn)單高效判斷數(shù)據(jù)類型 系列函數(shù) By shawl.qiu...2007-03-03JS實(shí)現(xiàn)動(dòng)態(tài)添加DOM節(jié)點(diǎn)和事件的方法示例
這篇文章主要介紹了JS實(shí)現(xiàn)動(dòng)態(tài)添加DOM節(jié)點(diǎn)和事件的方法,涉及javascript事件響應(yīng)及針對(duì)頁(yè)面dom元素節(jié)點(diǎn)與屬性的動(dòng)態(tài)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下2017-04-04js實(shí)現(xiàn)隨機(jī)div顏色位置 類似滿天星效果
這篇文章主要為大家詳細(xì)介紹了js實(shí)現(xiàn)隨機(jī)div顏色位置,類似滿天星效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-10-10淺談js對(duì)象屬性 通過(guò)點(diǎn)(.) 和方括號(hào)([]) 的不同之處
下面小編就為大家?guī)?lái)一篇淺談js對(duì)象屬性 通過(guò)點(diǎn)(.) 和方括號(hào)([]) 的不同之處。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2016-10-10Javascript中for循環(huán)語(yǔ)句的幾種寫(xiě)法總結(jié)對(duì)比
如果您希望一遍又一遍地運(yùn)行相同的代碼,并且每次的值都不同,那么使用循環(huán)是很方便的,javascript中for循環(huán)也是非常常用的,下面這篇文章主要介紹了Javascript中for循環(huán)的幾種寫(xiě)法,需要的朋友可以參考借鑒,一起來(lái)看看吧。2017-01-01