이 기사는 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

Netflix는 주로 프레임 워크 선택의 성능, 확장 성, 개발 효율성, 생태계, 기술 부채 및 유지 보수 비용을 고려합니다. 1. 성능 및 확장 성 : Java 및 SpringBoot는 대규모 데이터 및 높은 동시 요청을 효율적으로 처리하기 위해 선택됩니다. 2. 개발 효율성 및 생태계 : React를 사용하여 프론트 엔드 개발 효율성을 향상시키고 풍부한 생태계를 활용하십시오. 3. 기술 부채 및 유지 보수 비용 : Node.js를 선택하여 유지 보수 비용과 기술 부채를 줄이기 위해 마이크로 서비스를 구축하십시오.

Netflix는 주로 VUE가 특정 기능을 위해 보충하는 프론트 엔드 프레임 워크로 React를 사용합니다. 1) React의 구성 요소화 및 가상 DOM은 Netflix 애플리케이션의 성능 및 개발 효율을 향상시킵니다. 2) VUE는 Netflix의 내부 도구 및 소규모 프로젝트에 사용되며 유연성과 사용 편의성이 핵심입니다.

vue.js는 복잡한 사용자 인터페이스를 구축하는 데 적합한 점진적인 JavaScript 프레임 워크입니다. 1) 핵심 개념에는 반응 형 데이터, 구성 요소화 및 가상 DOM이 포함됩니다. 2) 실제 응용 분야에서는 TODO 응용 프로그램을 구축하고 Vuerouter를 통합하여 시연 할 수 있습니다. 3) 디버깅 할 때 VuedeVtools 및 Console.log를 사용하는 것이 좋습니다. 4) 성능 최적화는 V-IF/V- 쇼, 목록 렌더링 최적화, 구성 요소의 비동기로드 등을 통해 달성 할 수 있습니다.

vue.js는 중소형 프로젝트에 적합하지만 REACT는 크고 복잡한 응용 프로그램에 더 적합합니다. 1. Vue.js의 응답 형 시스템은 종속성 추적을 통해 DOM을 자동으로 업데이트하여 데이터 변경을 쉽게 관리 할 수 있습니다. 2. 반응은 단방향 데이터 흐름을 채택하고 데이터 흐름에서 하위 구성 요소로 데이터가 흐르고 명확한 데이터 흐름과 곤란하기 쉬운 구조를 제공합니다.

vue.js는 중소형 프로젝트 및 빠른 반복에 적합한 반면 React는 크고 복잡한 응용 프로그램에 적합합니다. 1) vue.js는 사용하기 쉽고 팀이 불충분하거나 프로젝트 규모가 작는 상황에 적합합니다. 2) React는 더 풍부한 생태계를 가지고 있으며 고성능 및 복잡한 기능적 요구가있는 프로젝트에 적합합니다.

VUE에서 태그의 점프를 구현하는 방법에는 다음이 포함됩니다. HTML 템플릿의 A 태그를 사용하여 HREF 속성을 지정합니다. VUE 라우팅의 라우터 링크 구성 요소를 사용하십시오. javaScript 에서이. $ router.push () 메소드를 사용하십시오. 매개 변수는 쿼리 매개 변수를 통해 전달 될 수 있으며 동적 점프를 위해 라우터 옵션에서 경로가 구성됩니다.

VUE에서 구성 요소 점프를 구현하는 방법은 다음과 같습니다. 라우터 링크 및 & lt; router-view & gt; 하이퍼 링크 점프를 수행하고 대상 경로로 속성을 지정합니다. & lt; router-view & gt; 현재 라우팅 된 렌더링 된 구성 요소를 표시하는 구성 요소. 프로그래밍 방식 탐색을 위해 router.push () 및 router.replace () 메소드를 사용하십시오. 전자는 역사를 구하고 후자는 기록을 떠나지 않고 현재 경로를 대체합니다.

VUE에서 DIV 요소를 점프하는 두 가지 방법이 있습니다. VUE 라우터를 사용하고 라우터 링크 구성 요소를 추가하십시오. @Click 이벤트 리스너를 추가하고 이것을 호출하십시오. $ router.push () 메소드를 점프하십시오.


핫 AI 도구

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

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

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

Clothoff.io
AI 옷 제거제

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

인기 기사

뜨거운 도구

Atom Editor Mac 버전 다운로드
가장 인기 있는 오픈 소스 편집기

ZendStudio 13.5.1 맥
강력한 PHP 통합 개발 환경

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

WebStorm Mac 버전
유용한 JavaScript 개발 도구

VSCode Windows 64비트 다운로드
Microsoft에서 출시한 강력한 무료 IDE 편집기
