Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
言
實現炫酷的的拖行拖拽
1.需求分析:設計一個元素,可以跟隨鼠標的移動,元素也進行移動,并且能夠在鼠標按上與按下元素的時候,元素可以進行改變樣式顏色。
2. 設計思路:先是需要獲取元素,給元素綁定鼠標按下的事件,在綁定的事件中,兼容event事件,獲取鼠標的坐標和元素的坐標,通過鼠標的坐標減去元素的坐標就可以得到鼠標在元素中的坐標。在綁定事件中,寫上一個元素的移動事件,獲取元素的移動坐標。最后,在鼠標按上的事件函數中,可以調用元素的移動事件就可以了。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>圖層拖拽</title> <style> .box { width: 200px; height: 200px; background-color: skyblue; border: 2px solid #ccc; cursor: pointer; position: absolute; top: 20px; left: 100px; } </style> </head> <body> <div class="box" id="box"></div> </body> <script> var box = document.getElementById("box"); box.onmousedown = function(env){ // 兼容event事件 var env = env || window.event; // 獲取鼠標的坐標 var x = env.clientX; var y = env.clientY; // 獲取元素的坐標 var left = box.offsetLeft; var top = box.offsetTop; // 獲取鼠標在元素中的坐標 var x_left = x - left; var y_top = y -top; // 鼠標點擊后改變顏色 box.style.background = "red"; // 元素的移動事件函數 box.onmousemove = function(env){ // 兼容event事件 var env = env || window.event; // 獲取元素移動時的鼠標的坐標 var x = env.clientX; var y = env.clientY; // 元素的移動坐標 box.style.left = (x - x_left)+"px"; box.style.top = (y - y_top)+"px"; } }; // 鼠標彈出的事件函數 box.onmouseup = function(){ box.style.background = "skyblue"; // 在鼠標彈出后再次調用元素的鼠標移動事件 box.onmousemove = function(){}; }; </script> </html>
學習從來不是一個人的事情,要有個相互監督的伙伴,想要學習或交流前端問題的小伙伴可以私信回復小明“學習” 獲取資料,一起學習!
要用到的 JS 事件有:
onmousedown:鼠標點下事件
onmousemove:鼠標移動事件
onmouseup:鼠標放開事件
具體代碼如下:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>列拖動</title> <style type="text/css"> body,ul,li {padding: 0; margin: 0;} ul, li {list-style: none;} .left {width: 300px; float: left;margin: 3px;} .right {width: 300px; float: left; margin:3px;} .column {width: 200px;height: 30px; line-height: 30px; background-color: #AACCFF; margin: 8px 5px; text-align: center; cursor: pointer;} .columnOld {width: 200px; height: 30px; line-height: 30px; background-color: #CCC; margin: 8px 5px; text-align: center;} .target {border: 1px solid #CCC; background-color: #FFF5EE;box-shadow: 0 0 8px #CCC; -moz-box-shadow: 0 0 8px #CCC; -webkit-box-shadow: 0 0 8px #CCC;} .container {width: 600px; height: 200px; display: block;} </style> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> window.onload = function(){ var Lis = document.getElementsByClassName("column"); var container = document.getElementsByClassName("container")[0]; for (var i = Lis.length - 1; i >= 0; i--) { var obj = Lis[i]; var source = obj.parentNode; var target = document.getElementById("container"); moveColumn(obj, target, source); } } /** * 字段拖拽事件 */ function moveColumn(obj, target, source) { // 1. 獲取事件 obj.onmousedown = function(event) { var ev = event || window.event; // 2. 復制新節點,設置透明度和innerHTML,class var newObj = document.createElement("li"); newObj.className = 'column'; newObj.style.opacity = '0.5'; newObj.style.filter = 'alpha(opacity:50)'; newObj.innerHTML = obj.innerHTML; newObj.style.margin = '0'; newObj.style.position = 'absolute'; newObj.style.zIndex = '5'; newObj.source = source; // 3. 計算點擊點在 obj 上的位置 var disH = ev.clientY - obj.offsetTop; var disL = ev.clientX - obj.offsetLeft; // 4. 設置絕對定位的top和left newObj.style.top = obj.offsetTop + 'px'; newObj.style.left = obj.offsetLeft + 'px'; // 5. 添加節點 obj.parentNode.appendChild(newObj); // 6. 鼠標移動事件 document.onmousemove = function(e) { // 1. 獲取事件 var e = e || window.event; // 2. 獲取鼠標位置,設置newObj的定位 var L = e.clientX - disL; var T = e.clientY - disH; newObj.style.top = T + 'px'; newObj.style.left = L + 'px'; // 3. source 背景色和邊框變換 $(target).addClass("target"); obj.className = "columnOld"; } // 7. 鼠標松開事件 document.onmouseup = function() { $(target).removeClass("target"); // target.class = ''; var not = newObj.offsetTop; var nol = newObj.offsetLeft; var tot = target.offsetTop; var tol = target.offsetLeft; if (not >= tot && nol >= tol && not <= tot + target.offsetHeight && nol <= tol + target.offsetWidth) { newObj.removeAttribute('style'); newObj.className = "column"; newObj.style.float = "left"; target.appendChild(newObj); backColumn(newObj, source, target); var id = obj.id; newObj.id = id; obj.id = id + "_old"; obj.onmousedown = null; } else { obj.className = "column"; obj.parentNode.removeChild(newObj); } document.onmouseup = null; document.onmousemove = null; } } } function backColumn(obj, target, source) { var Lis = source.getElementsByTagName('li'); var lineNum = Math.floor(source.offsetWidth / 210); var liFirst = Lis[0].offsetTop; var liHeight = Lis[0].offsetHeight; var liWidth = Lis[0].offsetWidth; // 1. 獲取事件 obj.onmousedown = function(event) { var ev = event || window.event; // 2. 復制新節點,設置透明度和innerHTML,class var newObj = document.createElement("li"); newObj.className = 'column'; newObj.style.opacity = '0.5'; newObj.style.filter = 'alpha(opacity:50)'; newObj.innerHTML = obj.innerHTML; newObj.style.margin = '0'; newObj.style.position = 'absolute'; newObj.style.zIndex = '5'; // 3. 計算點擊點在 obj 上的位置 var disH = ev.clientY - obj.offsetTop; var disL = ev.clientX - obj.offsetLeft; // 4. 設置絕對定位的top和left newObj.style.top = obj.offsetTop + 'px'; newObj.style.left = obj.offsetLeft + 'px'; // 5. 添加節點 obj.parentNode.appendChild(newObj); // 6. 添加空白節點(占位) var blank = document.createElement("li"); blank.className = 'column'; blank.style.backgroundColor = '#63B8FF'; blank.style.float = "left"; // 6. 鼠標移動事件 document.onmousemove = function(e) { // 1. 獲取事件 var e = e || window.event; // 2. 獲取鼠標位置,設置newObj的定位 var L = e.clientX - disL; var T = e.clientY - disH; newObj.style.top = T + 'px'; newObj.style.left = L + 'px'; // 3. source 背景色和邊框變換 $(target).addClass("target"); obj.className = "columnOld"; // 根據當前拖拽到的位置計算其重新排序后的位置 var line = lineNum * Math.round((T - liFirst)/liHeight) var n = line + Math.floor(L / liWidth); // 將空白節點插入到該位置 // if () source.insertBefore(blank,source.children[n]); } // 7. 鼠標松開事件 document.onmouseup = function() { $(target).removeClass("target"); // target.class = ''; var not = newObj.offsetTop; var nol = newObj.offsetLeft; var tot = target.offsetTop; var tol = target.offsetLeft; if (not >= tot && nol >= tol && not <= tot + target.offsetHeight && nol <= tol + target.offsetWidth) { var oldObj = document.getElementById(obj.id + '_old'); oldObj.className = 'column'; source.removeChild(newObj); source.removeChild(obj); oldObj.id = obj.id; moveColumn(oldObj, source, target); obj.onmousedown = null; } else { obj.className = "column"; obj.parentNode.removeChild(newObj); // 將被拖拽的元素插入到空白節點的位置 if (blank.parentNode == source) { source.insertBefore(obj,blank); } // 刪除拖拽樣式 // obj.removeAttribute('style'); } if (blank.parentNode == source) { // 刪除空白節點 source.removeChild(blank); } document.onmouseup = null; document.onmousemove = null; } } } function getStyle(obj, attr) { if (obj.currentStyle) { return obj.currentStyle[attr]; } else { return getComputedStyle(obj, false)[attr]; } } </script> </head> <body> <div style="overflow: hidden;"> <ul class="left"> <li class="column" id="c1">字段a-1</li> <li class="column" id="c2">字段a-2</li> <li class="column" id="c3">字段a-3</li> <li class="column" id="c4">字段a-4</li> <li class="column" id="c5">字段a-5</li> </ul> <ul class="right"> <li class="column" id="c6">字段b-1</li> <li class="column" id="c7">字段b-2</li> <li class="column" id="c8">字段b-3</li> <li class="column" id="c9">字段b-4</li> <li class="column" id="c10">字段b-5</li> </ul> </div> <div class="container" id="container"> </div> </body> </html>
最終效果
比較簡單,歡迎留言指正,代碼比較冗余,還沒來得及做整理,往見諒。
【標題】:一文教你用Vue.js輕松實現50行代碼的拖拽式自定義分割布局
---
篇引言
在Web前端開發領域中,構建高度交互和用戶友好的界面是至關重要的一步。Vue.js作為一款流行的漸進式JavaScript框架,以其響應式的數據綁定、組件化開發模式以及易于上手的API深受開發者喜愛。本文將通過一個實戰案例,教你在短短50行Vue.js代碼內,實現一個靈活易用的拖拽式自定義分割布局,讓你的應用瞬間提升用戶體驗。
---
項目初始化與環境搭建
bash
vue create my-split-layout
cd my-split-layout
npm install vuedraggable
1. 引入并注冊組件
javascript
import Vue from 'vue'
import Draggable from 'vuedraggable'
Vue.component('draggable', Draggable)
2. 創建自定義分割布局組件
創建名為`SplitLayout.vue`的組件文件,我們將在這個組件中編寫主要邏輯。
---
3. 設計布局結構
3.1 定義基礎模板
html
<template>
<div class="split-layout">
<draggable v-model="layoutItems">
<div
v-for="(item, index) in layoutItems"
:key="index"
class="layout-item"
:style="{ width: item.width + '%' }"
>
<!-- 這里放置你的內容 -->
</div>
</draggable>
</div>
</template>
這里的`layoutItems`數組將存儲每個布局區域的寬度信息。
3.2 添加樣式
css
.split-layout {
display: flex;
}
.layout-item {
box-sizing: border-box;
height: 100%;
overflow: auto;
}
---
4. 實現拖拽邏輯
4.1 初始化數據
javascript
export default {
data() {
return {
layoutItems: [{ width: 50 }, { width: 50 }] // 初始兩個等寬區域
};
},
// ...
}
4.2 監聽拖拽事件
javascript
mounted() {
this.$nextTick(() => {
this.updateLayout();
});
},
methods: {
updateLayout() {
const totalWidth = 100; // 布局總寬度
let sum = 0;
this.layoutItems.forEach((item, index) => {
if (index !== this.layoutItems.length - 1) {
sum += item.width;
item.width = `${sum}%`;
} else {
item.width = `${totalWidth - sum}%`; // 最后一個元素填充剩余寬度
}
});
},
onDragEnd(newIndex, oldIndex) {
this.updateLayout();
}
},
watch: {
layoutItems: {
handler(newVal) {
this.updateLayout();
},
deep: true
}
}
4.3 綁定拖拽結束事件
html
<draggable @end="onDragEnd" ...>
<!-- ... -->
</draggable>
---
結語
*請認真填寫需求信息,我們會在24小時內與您取得聯系。