中国招标信息网seo内容优化是什么意思
背景
大家或多或少应该有遇到过通过拖拽改变DOM大小的需求:比如说页面的侧边栏支持拖拽调整大小,使内容可视区变大。之所以讲这个需求,是因为在我个人开发的开源项目中有做到这个需求,所以在这里和大家聊一聊我的实现。以下内容均以向右拖拽为例。
思路
既然要实现拖拽,那就需要在DOM内有一个支持拖拽的节点,然后通过addEventListener
来监听鼠标点击
、鼠标点击后移动事件
、鼠标松开事件
。在鼠标点击后监听移动事件,在移动事件中计算鼠标点击位置与移动后的位置间的距离:这个距离就是DOM需要增加或者减少的宽度。
简单实现
思路清楚了,剩下的就是实现了,最主要的就是计算的部分了。贴上实现代码:
<template><div class="container"><div><div ref="box" class="box"><div ref="drag" class="drag"></div></div></div></div>
</template><script setup>
import { ref, onMounted, onBeforeUnmount } from "vue"const box = ref()
const drag = ref()const width = ref()
const downPageX = ref()const moveHandle = (event) => {document.documentElement.style.cursor = 'col-resize'const value = event.pageX - downPageX.valueconst size = width.value + valuebox.value.style.width = size + 'px'
}const upHandle = () => {// 移除监听document.removeEventListener('mousemove', moveHandle)document.removeEventListener('mouseup', upHandle)// 移除鼠标样式document.documentElement.style.cursor = ''
}const downListener = () => {drag.value.addEventListener('mousedown', (event) => {// 获取水平参数width.value = box.value.offsetWidthdownPageX.value = event.pageX// 添加鼠标移动事件document.addEventListener('mousemove', moveHandle)// 添加鼠标松开事件document.addEventListener('mouseup', upHandle)})
}onMounted(() => {downListener()
})onBeforeUnmount(() => {// 移除监听document.removeEventListener('mousemove', moveHandle)document.removeEventListener('mouseup', upHandle)// 移除鼠标样式document.documentElement.style.cursor = ''
})</script><style scoped>
// 省略...
</style>
拖拽指令
上面已经完成了简单的实现,但是在我们实际开发过程中不会就某一个地方需要用到这个实现。虽然可以CV
,但这绝对不是最优解,在这基础之上进一步优化。
我们可以将这个功能封装成自定义指令,思路与上文的思路相差无几。在所有节点都挂载完成之后,在使用了指令的节点里面插入一个可拖拽的节点,然后通过addEventListener
来监听各个鼠标事件,再进行一些计算,最后在节点卸载后移除相关监听。
本着精益求精的态度,必然不能只做到上面提到的那些。在实际开发中或许会遇到一些其它情况:比如我们拖拽的方向、可拖拽的最大最小距离、具体事件的回调等等问题都需要考虑在内。就有了以下完整的实现:
/*** @description: 拖拽改变大小指令* @param {*}* @return {*}* @author: gumingchen*/
const horizontal = ['left', 'right']
const vertical = ['top', 'bottom']
const positions = [...horizontal, ...vertical]// 默认参数
const defaultOptions = {// 拖拽位置position: positions[1],// 拖拽区域大小areaSize: '3px',// 拖拽区域背景色areaBackground: 'transparent',// Element的最小宽度/高度min: 200,// Element的最大宽度/高度max: 460,// 处理器downHandler: null,moveHandler: null,upHandler: null
}// 初始化数据
let data = {el: null,dom: null,options: null,width: null,downPageX: null,height: null,downPageY: null
}/*** 拖拽区域位置处理* @param {*} div* @param {*} position*/
const positionHandle = (div, position, size) => {// 水平方向if (horizontal.includes(position)) {div.style.top = '0px'div.style.bottom = '0px'div.style[position] = '0px'div.style.cursor = 'col-resize'div.style.width = size}// 垂直方向if (vertical.includes(position)) {div.style.right = '0px'div.style.left = '0px'div.style[position] = '0px'div.style.cursor = 'row-resize'div.style.height = size}
}/*** 创建节点* @returns Element*/
const createElement = (options) => {const div = document.createElement('div')div.style.position = 'absolute'div.style.userSelect = 'none'const { position, areaSize, areaBackground } = optionspositionHandle(div, position, areaSize)div.style.background = areaBackgroundreturn div
}/*** 鼠标移动监听事件* @param {*} event* @returns*/
const moveHandle = (event) => {const { el, dom, options, width, downPageX, height, downPageY } = dataconst { moveHandler, position, max, min } = options// 事件回调if (typeof moveHandler === 'function') {moveHandler(event)}// 设置鼠标样式document.documentElement.style.cursor = dom.style.cursor// 水平方向处理if (horizontal.includes(position)) {const value = position === horizontal[0] ? downPageX - event.pageX : event.pageX - downPageXconst size = width + valueif (size >= max) {return}if (size <= min) {return}el.style.width = size + 'px'}// 垂直方向处理if (vertical.includes(position)) {const value = position === vertical[0] ? downPageY - event.pageY : event.pageY - downPageYconst size = height + valueif (size >= max) {return}if (size <= min) {return}el.style.height = size + 'px'}
}
/*** 鼠标松开监听事件* @param {*} event*/
const upHandle = (event) => {// 事件回调const { upHandler } = data.optionsif (typeof upHandler === 'function') {upHandler(event)}// 移除监听document.removeEventListener('mousemove', moveHandle)document.removeEventListener('mouseup', upHandle)// 移除鼠标样式document.documentElement.style.cursor = ''
}/*** 鼠标按下事件* @param {*} el 当前节点* @param {*} dom 可拖拽节点* @param {*} options 参数*/
const downListener = (el, dom, options) => {dom.addEventListener('mousedown', (event) => {// 事件回调const { downHandler } = optionsif (typeof downHandler === 'function') {downHandler(event)}// 获取水平参数const width = el.offsetWidthconst downPageX = event.pageX// 获取垂直参数const height = el.offsetHeightconst downPageY = event.pageY// 设置数据data = { el, dom, options, width, downPageX, height, downPageY }// 添加鼠标移动事件document.addEventListener('mousemove', moveHandle)// 添加鼠标松开事件document.addEventListener('mouseup', upHandle)})
}export default {mounted(el, binding) {el.style.position = 'relative'const { arg, value } = bindingconst options = value ? { ...defaultOptions, ...value } : { ...defaultOptions }if (arg) {options.position = arg}if (!positions.includes(options.position)) {console.warn(`[Directive warn]: Invalid arg: validation failed for arg. Expected one of ${ JSON.stringify(positions) }, got value "${ options.position }".`)return}const dom = createElement(options)downListener(el, dom, options)el.appendChild(dom)},unmounted() {// 移除监听document.removeEventListener('mousemove', moveHandle)document.removeEventListener('mouseup', upHandle)// 移除鼠标样式document.documentElement.style.cursor = ''}
}
以上就是本次分享的内容,附上源码。
感谢看官看到这里,如果觉得文章不错的话,可以给小生的几个开源项目点个Star⭐!
- 基于 Vue3 + Element-plus 管理后台基础功能框架
- 预览:http://admin.gumingchen.icu
- Github:https://github.com/gmingchen/agile-admin
- Gitee:https://gitee.com/shychen/agile-admin
- 基础版后端:https://github.com/gmingchen/java-spring-boot-admin
- 文档:http://admin.gumingchen.icu/doc/
- 基于 Vue3 + Element-plus + websocket 即时聊天系统
- 预览:https://chatterbox.gumingchen.icu/
- 代码:https://github.com/gmingchen/chatterbox
- 基于 node 开发的后端服务:https://github.com/gmingchen/node-server