Vue 연습: 사용자 정의 지침을 사용하여 마우스 드래그 요소 효과 얻기
이 기사는 Vue 실제 전투를 공유하며 Vue의 사용자 정의 지침을 사용하여 마우스 드래그 요소의 효과를 얻고 모바일 단말기 적응 문제를 해결하는 방법을 소개합니다.
핵심 속성
-
Element.clientWidth
Element.clientWidth
:元素可视宽度。 -
Element.clientHeight
:元素可视高度。 -
MouseEvent.clientX
:鼠标相对于浏览器左上顶点的水平坐标。 -
MouseEvent.clientY
:鼠标相对于浏览器左上顶点的垂直坐标。 -
Touch.clientX
:触点相对于浏览器左上顶点的水平坐标(移动端属性)。 -
Touch.clientY
:触点相对于浏览器左上顶点的垂直坐标(移动端属性)。 -
HTMLElement.offsetLeft
:当前元素左上角相对于父节点(HTMLElement.offsetParent
)的左边偏移的距离。当元素脱离文档流时(position: fixed
)则相对于原点(浏览器左上顶点)偏移。【相关推荐:vuejs视频教程】 -
HTMLElement.offsetTop
:当前元素左上角相对于父节点(HTMLElement.offsetParent
)的顶部偏移的距离。当元素脱离文档流时(position: fixed
)则相对于原点(浏览器左上顶点)偏移。 -
Element.style.top
:可读可写,值为offsetTop
。 -
Element.style.left
:可读可写,值为offsetLeft
。
实现思路
待滑动元素必须设置
position: fixed or absolute
元素滑动需要依赖于鼠标的移动,鼠标的移动位置决定了元素滑动的位置,元素的位置是通过调整左上顶点坐标来的,所以我们要知道元素滑动后的左上顶点坐标,这样才能将元素移动到指定位置(鼠标悬停的位置)。
首先要计算出鼠标在移动元素前相对元素的位置 (x, y)
:
// 鼠标当前的位置减去元素当前的位置 (x, y) = (e.clientX - el.offsetLeft, e.clientY - el.offsetTop)
鼠标相对元素位置是指相对于元素左上顶点的位置。
e
指鼠标事件,el
指滑动的元素。
知道了鼠标的相对位置,后续的鼠标移动,只要知道移动后的鼠标坐标,就能很容易的把元素的左上顶点坐标算出来。
计算元素移动后的左上顶点坐标 (x', y')
:
// 鼠标当前的位置减去滑动前的相对位置 (x‘, y’) = (e.clientX - x, e.clientY - y)
(x', y')
就是要移动的最终坐标,然后调整元素位置即可
el.style.left = x' + 'px' el.style.top = y' + 'px'
代码
<template> <div> <!-- 省略... --> </div> </template> <script> export default { data() { return { isDrag: false }, methods: { click() { if (this.isDrag) { return } // 省略... } }, directives: { drag(el, binding, vnode) { /** * 获取客户端可见内容的高度 * * @returns {number} */ const getClientHeight = () => { return window.innerHeight || Math.min(document.documentElement.clientHeight, document.body.clientHeight) } /** * 获取客户端可见内容的宽度 * * @returns {number} */ const getClientWidth = () => { return window.innerWidth || Math.min(document.documentElement.clientWidth, document.body.clientWidth) } /** * startX = null:获取鼠标相对于元素(左上顶点)的x轴坐标(移动前坐标) * startX != null:获取移动后的左上顶点x轴坐标 * * e.clientX:鼠标相对客户端(客户端左上顶点)的x轴坐标 * el.offsetLeft:元素顶点(左上顶点)相对客户端(客户端左上顶点)的x轴坐标(元素必须脱离文档流,position: fixed or absolute) * el.clientWidth:元素宽度 * * @param el * @param e * @param startX * @returns {number} */ const getX = (el, e, startX) => { if (startX === null) { // 返回鼠标相对于元素(左上顶点)的x轴坐标 return e.clientX - el.offsetLeft } // 客户端可视宽度 const clientWidth = getClientWidth() // 元素自身宽度 const elWidth = el.clientWidth // 移动到x轴位置 let x = e.clientX - startX // 水平方向边界处理 if (x <= 0) { // x轴最小为0 x = 0 } else if (x + elWidth > clientWidth) { // x是左上顶点的坐标,是否触碰到右边边界(超出可视宽度)要通过右顶点判断,所以需要加上元素自身宽度 x = clientWidth - elWidth } return x } /** * startY = null:获取鼠标相对于元素(左上顶点)的y轴坐标(移动前坐标) * startY != null:获取移动后的左上顶点y轴坐标 * * e.clientY:鼠标相对客户端(客户端左上顶点)的y轴坐标 * el.offsetTop:元素顶点(左上顶点)相对客户端(客户端左上顶点)的y轴坐标(元素必须脱离文档流,position: fixed or absolute) * el.clientHeight:元素高度 * * @param el * @param e * @param startY * @returns {number} */ const getY = (el, e, startY) => { if (startY === null) { // 返回鼠标相对于元素(左上顶点)的y轴坐标 return e.clientY - el.offsetTop } // 客户端可视高度 const clientHeight = getClientHeight() // 元素自身高度 const elHeight = el.clientHeight // 移动到y轴位置 let y = e.clientY - startY // 垂直方向边界处理 if (y <= 0) { // y轴最小为0 y = 0 } else if (y + elHeight > clientHeight) { // 同理,判断是否超出可视高度要加上自身高度 y = clientHeight - elHeight } return y } /** * 监听鼠标按下事件(PC端拖动) * * @param e */ el.onmousedown = (e) => { vnode.context.isDrag = false // 获取当前位置信息 (startX,startY) const startX = getX(el, e, null) const startY = getY(el, e, null) /** * 监听鼠标移动事件 * * @param e */ document.onmousemove = (e) => { // 标记正在移动,解决元素移动后点击事件被触发的问题 vnode.context.isDrag = true // 更新元素位置(移动元素) el.style.left = getX(el, e, startX) + 'px' el.style.top = getY(el, e, startY) + 'px' } /** * 监听鼠标松开事件 */ document.onmouseup = () => { // 移除鼠标相关事件,防止元素无法脱离鼠标 document.onmousemove = document.onmouseup = null } } /** * 监听手指按下事件(移动端拖动) * @param e */ el.ontouchstart = (e) => { // 获取被触摸的元素 const touch = e.targetTouches[0] // 获取当前位置信息 (startX,startY) const startX = getX(el, touch, null) const startY = getY(el, touch, null) /** * 监听手指移动事件 * @param e */ document.ontouchmove = (e) => { // 获取被触摸的元素 const touch = e.targetTouches[0] // 更新元素位置(移动元素) el.style.left = getX(el, touch, startX) + 'px' el.style.top = getY(el, touch, startY) + 'px' } /** * 监听手指移开事件 */ document.ontouchend = () => { // 移除touch相关事件,防止元素无法脱离手指 document.ontouchmove = document.ontouchend = null } } } } } </script> <style> .ball-wrap { position: fixed; } </style>
drag
是我们自定义的指令,在需要滑动的元素上绑定 v-drag
即可。
注意
自定义指令this指向问题
在自定义指令 directives
内不能访问 this
,如果需要修改 data
里的值,需要通过 vnode.context.字段名 = 值
修改。
滑动后点击事件被触发
鼠标事件触发顺序:
mouseover - mousedown - mouseup - click - mouseout
滑动的前提是鼠标必须按下再滑动,所以在我们滑动完毕松开鼠标时,click
事件会被触发。
解决方法:定义一个标志变量,表示是否是滑动,点击事件执行时,将此变量作为前置条件,如果是在滑动则不执行。
// ... data() return { isDrag: false } } // ... el.onmousedown = (e) => { // ... vnode.context.isDrag = false document.onmousemove = (e) => { // 标记正在移动,解决元素移动后点击事件被触发的问题 vnode.context.isDrag = true // ... } } // ... methods: { click() { if (this.isDrag) { return } // ... } }
移动端滑动问题
移动端滑动时会触发默认事件,导致滑动卡顿。
在要触发滑动的元素上加上 @touchmove.prevent
: 요소 표시 너비.
Element.clientHeight
: 요소의 표시 높이입니다.
MouseEvent.clientX
: 브라우저의 왼쪽 상단 정점을 기준으로 한 마우스의 수평 좌표입니다.
MouseEvent.clientY
: 브라우저의 왼쪽 상단 정점을 기준으로 한 마우스의 수직 좌표입니다. Touch.clientX
: 브라우저의 왼쪽 상단 정점을 기준으로 한 터치 포인트의 수평 좌표입니다(모바일 속성). Touch.clientY
HTMLElement.offsetLeft
🎜: 상위 노드(HTMLElement.offsetParent
)의 왼쪽 오프셋을 기준으로 현재 요소의 왼쪽 상단 모서리까지의 거리 . 요소가 문서 흐름을 벗어나면(위치: 고정
) 원점(브라우저의 왼쪽 상단 정점)을 기준으로 오프셋됩니다. [관련 권장사항: vuejs 비디오 튜토리얼🎜]🎜 🎜HTMLElement.offsetTop
🎜: 상위 노드(HTMLElement.offsetParent
)의 상단을 기준으로 현재 요소의 왼쪽 상단 모서리의 오프셋 거리입니다. 요소가 문서 흐름을 벗어나면(위치: 고정
) 원점(브라우저의 왼쪽 상단 정점)을 기준으로 오프셋됩니다. 🎜🎜Element.style.top
🎜: 읽기 및 쓰기 가능, 값은 offsetTop
입니다. 🎜🎜Element.style.left
🎜: 읽고 쓸 수 있으며 값은 offsetLeft
입니다. 🎜
🎜구현 아이디어🎜🎜🎜🎜슬라이드할 요소는 위치: 고정 또는 절대
🎜🎜🎜요소 슬라이딩 요구 사항으로 설정되어야 합니다. 마우스에 의존하려면 마우스의 움직임에 따라 요소의 슬라이딩 위치가 결정되므로 요소의 왼쪽 위 꼭지점의 좌표를 조정하여 요소의 위치가 결정되므로 요소의 왼쪽 위 꼭지점의 좌표를 알아야 합니다. 슬라이딩 후 요소가 지정된 위치(마우스 오버) 위치로 이동할 수 있도록 합니다. 🎜🎜먼저 (x, y)
요소를 이동하기 전에 요소를 기준으로 한 마우스의 위치를 계산합니다. 🎜rrreee🎜 요소를 기준으로 한 마우스의 위치는 요소를 기준으로 한 마우스의 위치를 나타냅니다. 요소의 왼쪽 위 꼭지점. 🎜🎜e
는 마우스 이벤트를 나타내고, el
은 슬라이딩 요소를 나타냅니다. 🎜🎜마우스의 상대적 위치와 그에 따른 마우스 움직임을 알면, 이동 후 마우스의 좌표만 알면 요소의 왼쪽 위 정점 좌표를 쉽게 계산할 수 있습니다. 🎜🎜이동 후 요소의 왼쪽 상단 정점 (x', y')
의 좌표를 계산합니다. 🎜rrreee🎜(x', y')
가 최종입니다. 좌표를 이동한 다음 요소의 위치를 조정하세요🎜rrreee🎜Code🎜🎜rrreee🎜drag
는 우리의 사용자 지정 명령입니다. 슬라이드해야 하는 요소에 v-drag
그게 다입니다. 🎜🎜Attention🎜🎜🎜사용자 지정 지시문은 문제를 가리킵니다🎜
🎜사용자 지정 지시문에서 지시문 <code>this
은 내에서 액세스할 수 없습니다. data
의 값을 수정해야 하는 경우 vnode.context.Field 이름을 통해 수정해야 합니다. = 값
. 🎜🎜슬라이딩 후에 클릭 이벤트가 트리거됩니다🎜
🎜마우스 이벤트 트리거 시퀀스: 🎜🎜mouseover - mousedown - mouseup - click - mouseout
🎜 🎜슬라이딩의 전제조건은 마우스를 누른 후 슬라이딩해야 한다는 것이므로, 슬라이딩 후 마우스를 놓으면 클릭
이벤트가 트리거됩니다. 🎜🎜해결책: 🎜슬라이딩 여부를 나타내는 플래그 변수를 정의합니다. 클릭 이벤트가 실행될 때 이 변수는 슬라이딩 중이면 실행되지 않습니다🎜. 🎜rrreee🎜모바일 측 슬라이딩 문제🎜
🎜모바일 측이 슬라이드할 때 기본 이벤트가 트리거되어 슬라이딩이 정지됩니다. 🎜🎜기본 이벤트가 발생하지 않도록 슬라이딩을 트리거하려면 요소에 @touchmove.prevent
를 추가하세요. 🎜🎜🎜소스코드🎜🎜🎜🎜https://github.com/anlingyi/xeblog-vue/blob/master/src/comComponents/xe-pokeball/index.vue🎜🎜🎜(학습영상공유 : 🎜웹프런트- 개발 종료🎜 ,🎜기본 프로그래밍 영상🎜)🎜
drag
는 우리의 사용자 지정 명령입니다. 슬라이드해야 하는 요소에 v-drag
그게 다입니다. 🎜🎜Attention🎜🎜🎜사용자 지정 지시문은 문제를 가리킵니다🎜
🎜사용자 지정 지시문에서 지시문 <code>this
은 내에서 액세스할 수 없습니다. data
의 값을 수정해야 하는 경우 vnode.context.Field 이름을 통해 수정해야 합니다. = 값
. 🎜🎜슬라이딩 후에 클릭 이벤트가 트리거됩니다🎜
🎜마우스 이벤트 트리거 시퀀스: 🎜🎜mouseover - mousedown - mouseup - click - mouseout
🎜 🎜슬라이딩의 전제조건은 마우스를 누른 후 슬라이딩해야 한다는 것이므로, 슬라이딩 후 마우스를 놓으면 클릭
이벤트가 트리거됩니다. 🎜🎜해결책: 🎜슬라이딩 여부를 나타내는 플래그 변수를 정의합니다. 클릭 이벤트가 실행될 때 이 변수는 슬라이딩 중이면 실행되지 않습니다🎜. 🎜rrreee🎜모바일 측 슬라이딩 문제🎜
🎜모바일 측이 슬라이드할 때 기본 이벤트가 트리거되어 슬라이딩이 정지됩니다. 🎜🎜기본 이벤트가 발생하지 않도록 슬라이딩을 트리거하려면 요소에 @touchmove.prevent
를 추가하세요. 🎜🎜🎜소스코드🎜🎜🎜🎜https://github.com/anlingyi/xeblog-vue/blob/master/src/comComponents/xe-pokeball/index.vue🎜🎜🎜(학습영상공유 : 🎜웹프런트- 개발 종료🎜 ,🎜기본 프로그래밍 영상🎜)🎜
위 내용은 Vue 연습: 사용자 정의 지침을 사용하여 마우스 드래그 요소 효과 얻기의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











HTML 템플릿의 버튼을 메소드에 바인딩하여 VUE 버튼에 함수를 추가 할 수 있습니다. 메소드를 정의하고 VUE 인스턴스에서 기능 로직을 작성하십시오.

vue.js에서 JS 파일을 참조하는 세 가지 방법이 있습니다. & lt; script & gt; 꼬리표;; mounted () 라이프 사이클 후크를 사용한 동적 가져 오기; Vuex State Management Library를 통해 수입.

vue.js의 시계 옵션을 사용하면 개발자가 특정 데이터의 변경 사항을들을 수 있습니다. 데이터가 변경되면 콜백 기능을 트리거하여 업데이트보기 또는 기타 작업을 수행합니다. 구성 옵션에는 즉시 콜백을 실행할지 여부와 DEEP를 지정하는 즉시 포함되며, 이는 객체 또는 어레이에 대한 변경 사항을 재귀 적으로 듣는 지 여부를 지정합니다.

vue.js에서 bootstrap 사용은 5 단계로 나뉩니다 : Bootstrap 설치. main.js.의 부트 스트랩 가져 오기 부트 스트랩 구성 요소를 템플릿에서 직접 사용하십시오. 선택 사항 : 사용자 정의 스타일. 선택 사항 : 플러그인을 사용하십시오.

vue.js는 이전 페이지로 돌아갈 수있는 네 가지 방법이 있습니다. $ router.go (-1) $ router.back () 사용 & lt; router-link to = & quot;/quot; Component Window.history.back () 및 메소드 선택은 장면에 따라 다릅니다.

CSS 애니메이션 또는 타사 라이브러리를 사용하여 VUE에서 Marquee/Text Scrolling Effects를 구현하십시오. 이 기사는 CSS 애니메이션 사용 방법을 소개합니다. & lt; div & gt; CSS 애니메이션을 정의하고 오버플로를 설정하십시오 : 숨겨진, 너비 및 애니메이션. 키 프레임을 정의하고 변환을 설정하십시오 : Translatex () 애니메이션의 시작과 끝에서. 지속 시간, 스크롤 속도 및 방향과 같은 애니메이션 속성을 조정하십시오.

Vue DevTools를 사용하여 브라우저 콘솔에서 vue 탭을 보면 VUE 버전을 쿼리 할 수 있습니다. npm을 사용하여 "npm list -g vue"명령을 실행하십시오. package.json 파일의 "종속성"객체에서 vue 항목을 찾으십시오. Vue Cli 프로젝트의 경우 "vue -version"명령을 실행하십시오. & lt; script & gt에서 버전 정보를 확인하십시오. vue 파일을 나타내는 html 파일의 태그.

VUE 멀티 페이지 개발은 vue.js 프레임 워크를 사용하여 응용 프로그램을 구축하는 방법입니다. 여기서 응용 프로그램은 별도의 페이지로 나뉩니다. 코드 유지 보수 : 응용 프로그램을 여러 페이지로 분할하면 코드를보다 쉽게 관리하고 유지 관리 할 수 있습니다. 모듈 식 : 각 페이지는 쉬운 재사용 및 교체를 위해 별도의 모듈로 사용할 수 있습니다. 간단한 라우팅 : 페이지 간의 탐색은 간단한 라우팅 구성을 통해 관리 할 수 있습니다. SEO 최적화 : 각 페이지에는 자체 URL이있어 SEO가 도움이됩니다.
