原生js實現(xiàn)拖拽移動與縮放效果
本文實例為大家分享了js實現(xiàn)拖拽移動與縮放效果的具體代碼,供大家參考,具體內(nèi)容如下
效果圖如下-實現(xiàn)了簡單的拖拽和縮放功能

第一步—簡單的拖拽功能
// 創(chuàng)建一個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 => {
// 獲取事件對象
var e = e || window.event;
// 鼠標(biāo)按下時,鼠標(biāo)相對于元素的x坐標(biāo)
var x = e.offsetX;
// 鼠標(biāo)按下時,鼠標(biāo)相對于元素的y坐標(biāo)
var y = e.offsetY;
// 鼠標(biāo)按下移動時調(diào)用mousemove
document.onmousemove = e => {
// 元素ele移動的距離l
var l = e.clientX - x;
// 元素ele移動的距離l
var t = e.clientY - y;
this.ele.style.left = l + "px";
this.ele.style.top = t + "px";
}
// 當(dāng)鼠標(biāo)彈起時,清空onmousemove與onmouseup
document.onmouseup = () => {
document.onmousemove = null;
document.onmouseup = null;
}
}
}
// new一個MoveClass對象
var moveClass = new MoveClass("#box");
效果如下,簡單的拖拽

第二步—簡單的縮放功能
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)建一個div
var div = document.createElement("div");
// 遍歷this.editoptions
for (let attr in this.editoptions) {
if (this.editoptions[attr]) {
// 循環(huán)創(chuàng)建左,左上,左下,右,右上,右下,上,下方位的小點
var dian = document.createElement("div");
dian.className = "dian " + attr;
// 設(shè)置類型為對應(yīng)的attr
dian.dataset.type = attr;
// 當(dāng)按下對應(yīng)方位的小點時
dian.onmousedown = e => {
var e = e || window.event;
// 先獲取鼠標(biāo)距離屏幕的left與top值
var clientXY = {
x: e.clientX,
y: e.clientY
}
// 獲取鼠標(biāo)按下時ele的寬高
var eleWH = {
width: this.ele.clientWidth,
height: this.ele.clientHeight,
}
// 阻止事件冒泡(針對父元素的move)
e.stopPropagation();
// 通過e.target獲取精準(zhǔn)事件源對應(yīng)的type值
var type = e.target.dataset.type;
// 鼠標(biāo)按下對應(yīng)方位小點移動時,調(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)距離屏幕的距離 - 第一次按下時鼠標(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)距離屏幕的距離 + 第一次按下時鼠標(biāo)距離屏幕的距離
that.ele.style.height = (eleWH.height - e.clientY + clientXY.y) + "px";
// 重新設(shè)置ele的top值為此時鼠標(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值為此時鼠標(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);
}
效果圖如下

最終效果,盒子可以拖動,可以縮放。
盒子上的8個小點采用定位放上去的,事先寫好了樣式
<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放的原理其實就是鼠標(biāo)按下去時,獲取當(dāng)前的鼠標(biāo)位置和盒子的寬高,鼠標(biāo)按下并移動后獲取此時的鼠標(biāo)位置。
拖拽后的寬高=初始寬高+(拖拽后鼠標(biāo)距離屏幕的位置 - 第一次按下時鼠標(biāo)距離屏幕的位置)。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
學(xué)習(xí)Javascript面向?qū)ο缶幊讨庋b
這篇文章主要幫助大家學(xué)習(xí)Javascript面向?qū)ο缶幊讨庋b,由淺入深的介紹了封裝的概念定義,感興趣的小伙伴們可以參考一下2016-02-02
js html css實現(xiàn)復(fù)選框全選與反選
這篇文章主要為大家詳細(xì)介紹了js實現(xiàn)復(fù)選框全選與反選,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-10-10

