document.onselectstart=function(){return false;} 引起的拖动问题

本文介绍了一个JavaScript技巧,通过设置document.onselectstart来阻止网页内容被选中,但该方法同时引发了滚动条无法正常工作的副作用。寻求解决方案以确保在禁用选中的情况下,滚动条仍能正常使用。
在网页中拖动时,会引起某些文字或一些内容被选中,导致网页中蓝蓝的一片,视觉效果很差,所以我加了个
document.onselectstart=function(){return false;}这样子,拖动时网页中的内容是不会被选中了,但也随之带来了另一个问题:
在拖动时,如果遇到滚动条的话,那我就拖不下去了,因为滚动条不会自动的向下滚或是向上滚了,我只能在当前视线范围内拖动,这个问题在没加document.onselectstart=function(){return false;}之前是没有的,大家有没有办法解决此滚动条滚动问题,万分感谢!!!

:(
请根据代码片段仿写实现div左下角拖拽移动用具体代码实现,import Vue from 'vue' Vue.directive('dialogZoomOut', { bind(el, binding, vnode, oldVnode) { let minWidth = 400;let minHeight = 300;let isFullScreen = false; let nowWidth = 0;let nowHight = 0;let nowMarginTop = 0;const dialogHeaderEl = el.querySelector('.el-dialog__header');const dragDom = el.querySelector('.el-dialog');dragDom.style.overflow = "auto";dialogHeaderEl.onselectstart = new Function("return false");dialogHeaderEl.style.cursor = 'move';const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null);let moveDown = (e) => {const disX = e.clientX - dialogHeaderEl.offsetLeft;const disY = e.clientY - dialogHeaderEl.offsetTop;let styL, styT;if (sty.left.includes('%')) {styL = +document.body.clientWidth * (+sty.left.replace(/%/g, '') / 100);styT = +document.body.clientHeight * (+sty.top.replace(/%/g, '') / 100);} else {styL = +sty.left.replace(/px/g, '');styT = +sty.top.replace(/px/g, '');};document.onmousemove = function (e) {const l = e.clientX - disX;const t = e.clientY - disY;dragDom.style.left = `${l + styL}px`;dragDom.style.top = `${t + styT}px`;};document.onmouseup = function (e) {document.onmousemove = null;document.onmouseup = null;};}dialogHeaderEl.onmousedown = moveDown;dialogHeaderEl.ondblclick = (e) => {if (isFullScreen == false) {nowHight = dragDom.clientHeight;nowWidth = dragDom.clientWidth;nowMarginTop = dragDom.style.marginTop;dragDom.style.left = 0;dragDom.style.top = 0;dragDom.style.height = "100VH";dragDom.style.width = "100VW";dragDom.style.marginTop = 0;isFullScreen = true;dialogHeaderEl.style.cursor = 'initial';dialogHeaderEl.onmousedown = null;} else {dragDom.style.height = "auto";dragDom.style.width = nowWidth + 'px';dragDom.style.marginTop = nowMarginTop;isFullScreen = false;dialogHeaderEl.style.cursor = 'move';dialogHeaderEl.onmousedown = moveDown;}}let resizeEl = document.createElement("div");dragDom.appendChild(resizeEl);resizeEl.style.cursor = 'se-resize';resizeEl.style.position = 'absolute';resizeEl.style.height = '10px';resizeEl.style.width = '10px';resizeEl.style.right = '0px';resizeEl.style.bottom = '0px';resizeEl.style.zIndex = '99';resizeEl.onmousedown = (e) => {let clientX = e.clientX;let disX = e.clientX - resizeEl.offsetLeft;let disY = e.clientY - resizeEl.offsetTop;document.onmousemove = function (e) {e.preventDefault(); let x = e.clientX - disX + (e.clientX - clientX);let y = e.clientY - disY;dragDom.style.width = x > minWidth ? `${x}px` : minWidth + 'px';dragDom.style.height = y > minHeight ? `${y}px` : minHeight + 'px';};document.onmouseup = function (e) {document.onmousemove = null;document.onmouseup = null;};}}})
06-01
import Vue from 'vue' console.log('dialong.js') // 需要在对话框中添加 v-dialogDrag Vue.directive('dialogDrag', { bind(el, binding, vnode, oldVnode) { console.log('dialogDrag') //弹框可拉伸最小宽高 let minWidth = 400; let minHeight = 300; //初始非全屏 let isFullScreen = false; //当前宽高 let nowWidth = 0; let nowHight = 0; //当前顶部高度 let nowMarginTop = 0; //获取弹框头部(这部分可双击全屏) const dialogHeaderEl = el.querySelector('.el-dialog__header'); console.log('dialogHeaderEl',dialogHeaderEl) //弹窗 const dragDom = el.querySelector('.el-dialog'); //给弹窗加上overflow auto;不然缩小时框内的标签可能超出dialog; dragDom.style.overflow = "auto"; //清除选择头部文字效果 dialogHeaderEl.onselectstart = new Function("return false"); //头部加上可拖动cursor dialogHeaderEl.style.cursor = 'move'; // 获取原有属性 ie dom元素.currentStyle 火狐谷歌 window.getComputedStyle(dom元素, null); const sty = dragDom.currentStyle || window.getComputedStyle(dragDom, null); let moveDown = (e) => { // 鼠标按下,计算当前元素距离可视区的距离 const disX = e.clientX - dialogHeaderEl.offsetLeft; const disY = e.clientY - dialogHeaderEl.offsetTop; // 获取到的值带px 正则匹配替换 let styL, styT; // 注意在ie中 第一次获取到的值为组件自带50% 移动之后赋值为px if (sty.left.includes('%')) { styL = +document.body.clientWidth * (+sty.left.replace(/%/g, '') / 100); styT = +document.body.clientHeight * (+sty.top.replace(/%/g, '') / 100); } else { styL = +sty.left.replace(/px/g, ''); styT = +sty.top.replace(/px/g, ''); }; document.onmousemove = function (e) { // 通过事件委托,计算移动的距离 const l = e.clientX - disX; const t = e.clientY - disY; // 移动当前元素 dragDom.style.left = `${l + styL}px`; dragDom.style.top = `${t + styT}px`; //将此时的位置传出去 //binding.value({x:e.pageX,y:e.pageY}) }; document.onmouseup = function (e) { document.onmousemove = null; document.onmouseup = null; }; } dialogHeaderEl.onmousedown = moveDown; //双击(头部)效果不想要可以注释 dialogHeaderEl.ondblclick = (e) => { if (isFullScreen == false) { nowHight = dragDom.clientHeight; nowWidth = dragDom.clientWidth; nowMarginTop = dragDom.style.marginTop; dragDom.style.left = 0; dragDom.style.top = 0; dragDom.style.height = "100VH"; dragDom.style.width = "100VW"; dragDom.style.marginTop = 0; isFullScreen = true; dialogHeaderEl.style.cursor = 'initial'; dialogHeaderEl.onmousedown = null; } else { dragDom.style.height = "auto"; dragDom.style.width = nowWidth + 'px'; dragDom.style.marginTop = nowMarginTop; isFullScreen = false; dialogHeaderEl.style.cursor = 'move'; dialogHeaderEl.onmousedown = moveDown; } } //拉伸(右下方)效果不想要可以注释 let resizeEl = document.createElement("div"); dragDom.appendChild(resizeEl); //在弹窗右下角加上一个10-10px的控制块 resizeEl.style.cursor = 'se-resize'; resizeEl.style.position = 'absolute'; resizeEl.style.height = '10px'; resizeEl.style.width = '10px'; resizeEl.style.right = '0px'; resizeEl.style.bottom = '0px'; resizeEl.style.zIndex = '99'; //鼠标拉伸弹窗 resizeEl.onmousedown = (e) => { // 记录初始x位置 let clientX = e.clientX; // 鼠标按下,计算当前元素距离可视区的距离 let disX = e.clientX - resizeEl.offsetLeft; let disY = e.clientY - resizeEl.offsetTop; document.onmousemove = function (e) { e.preventDefault(); // 移动时禁用默认事件 // 通过事件委托,计算移动的距离 let x = e.clientX - disX + (e.clientX - clientX);//这里 由于elementUI的dialog控制居中的,所以水平拉伸效果是双倍 let y = e.clientY - disY; //比较是否小于最小宽高 dragDom.style.width = x > minWidth ? `${x}px` : minWidth + 'px'; dragDom.style.height = y > minHeight ? `${y}px` : minHeight + 'px'; }; //拉伸结束 document.onmouseup = function (e) { document.onmousemove = null; document.onmouseup = null; }; } //拉伸(右边)效果不想要可以注释 let resizeElR = document.createElement("div"); dragDom.appendChild(resizeElR); //在弹窗右下角加上一个10-10px的控制块 resizeElR.style.cursor = 'w-resize'; resizeElR.style.position = 'absolute'; resizeElR.style.height = '100%'; resizeElR.style.width = '10px'; resizeElR.style.right = '0px'; resizeElR.style.top = '0px'; //鼠标拉伸弹窗 resizeElR.onmousedown = (e) => { let elW = dragDom.clientWidth; let EloffsetLeft = dragDom.offsetLeft; // 记录初始x位置 let clientX = e.clientX; document.onmousemove = function (e) { e.preventDefault(); // 移动时禁用默认事件 //右侧鼠标拖拽位置 if (clientX > EloffsetLeft + elW - 10 && clientX < EloffsetLeft + elW) { //往左拖拽 if (clientX > e.clientX) { if (dragDom.clientWidth < minWidth) { } else { dragDom.style.width = elW - (clientX - e.clientX) * 2 + 'px'; } } //往右拖拽 if (clientX < e.clientX) { dragDom.style.width = elW + (e.clientX - clientX) * 2 + 'px'; } } }; //拉伸结束 document.onmouseup = function (e) { document.onmousemove = null; document.onmouseup = null; }; } //拉伸(左边)效果不想要可以注释 let resizeElL = document.createElement("div"); dragDom.appendChild(resizeElL); //在弹窗右下角加上一个10-10px的控制块 resizeElL.style.cursor = 'w-resize'; resizeElL.style.position = 'absolute'; resizeElL.style.height = '100%'; resizeElL.style.width = '10px'; resizeElL.style.left = '0px'; resizeElL.style.top = '0px'; //鼠标拉伸弹窗 resizeElL.onmousedown = (e) => { let elW = dragDom.clientWidth; let EloffsetLeft = dragDom.offsetLeft; // 记录初始x位置 let clientX = e.clientX; document.onmousemove = function (e) { e.preventDefault(); // 移动时禁用默认事件 //左侧鼠标拖拽位置 if (clientX > EloffsetLeft && clientX < EloffsetLeft + 10) { //往左拖拽 if (clientX > e.clientX) { dragDom.style.width = elW + (clientX - e.clientX) * 2 + 'px'; } //往右拖拽 if (clientX < e.clientX) { if (dragDom.clientWidth < minWidth) { } else { dragDom.style.width = elW - (e.clientX - clientX) * 2 + 'px'; } } } }; //拉伸结束 document.onmouseup = function (e) { document.onmousemove = null; document.onmouseup = null; }; } // 拉伸(下边)效果不想要可以注释 let resizeElB = document.createElement("div"); dragDom.appendChild(resizeElB); //在弹窗右下角加上一个10-10px的控制块 resizeElB.style.cursor = 'n-resize'; resizeElB.style.position = 'absolute'; resizeElB.style.height = '10px'; resizeElB.style.width = '100%'; resizeElB.style.left = '0px'; resizeElB.style.bottom = '0px'; //鼠标拉伸弹窗 resizeElB.onmousedown = (e) => { let EloffsetTop = dragDom.offsetTop; let ELscrollTop = el.scrollTop; let clientY = e.clientY; let elH = dragDom.clientHeight; document.onmousemove = function (e) { e.preventDefault(); // 移动时禁用默认事件 //底部鼠标拖拽位置 if (ELscrollTop + clientY > EloffsetTop + elH - 20 && ELscrollTop + clientY < EloffsetTop + elH) { //往上拖拽 if (clientY > e.clientY) { if (dragDom.clientHeight < minHeight) { } else { dragDom.style.height = elH - (clientY - e.clientY) * 2 + 'px'; } } //往下拖拽 if (clientY < e.clientY) { dragDom.style.height = elH + (e.clientY - clientY) * 2 + 'px'; } } }; //拉伸结束 document.onmouseup = function (e) { document.onmousemove = null; document.onmouseup = null; }; } } }) export default { data() { return { gridData: [{ date: '2016-05-02', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-04', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-01', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }, { date: '2016-05-03', name: '王小虎', address: '上海市普陀区金沙江路 1518 弄' }], dialogTableVisible: false, dialogFormVisible: false, form: { name: '', region: '', date1: '', date2: '', delivery: false, type: [], resource: '', desc: '' }, formLabelWidth: '120px' }; } }; 为什么我在vue单页面引用可以 拖拽 拉伸 ,但是放到main.js中只能移动
05-31
<template> <div class="video-play-box" style="width: 100%; height: 100%"> <div id="video-wrap-player" v-if="mediaUri"> <video-player class="video-player vjs-custom-skin" ref="videoPlayer" :options="playerOptions" :playsinline="true" @ready="onPlayerReady" @play="onPlayerPlay" @timeupdate="onPlayerTimeupdate" @pause="onPlayerPause" @ended="onPlayerEnded"> </video-player> </div> <div class="watermark">{{ waterText }}</div> </div> </template> <script> import { getCourseLessonsDetail, updateCourseLearning } from '@/api/course' export default { name: 'videoboPlayer', props: ['courseId', 'isDrag', 'doubleSpeed', 'from'], data() { return { coursewareId: this.$route.query.coursewareId, stageId: this.$route.query.stageId, // 阶段ID isPaused: '', // 视频暂停 canDrag: false, // 是否可拖动 只有首次不可拖动 currentTime: 0, // 当前学习位置 nowCurrentTime: '', // 视频当前学习位置 learnProgress: 0, // 学习进度 TimingUpdateProgress: {}, // 定时更新进度计时器 videoTotalLength: 0, // 视频总时长 player: null, // 视频对象 isEnded: false, // 是否触发视频end事件 isUpdateing: false, // 更新课件进度接口请求中 waterText: '', // 水印文字 sourceId: '', // 来源id nextCourseware: {}, // 下一课件的内容 lessonData: {}, mediaUri: '', // 修复:添加isStart到data中 isStart: false, // 修复:添加playerOptions到data中 playerOptions: {}, } }, components: {}, computed: {}, watch: { $route: function () { if (!this.isStart) { this.getVideoDetail() } }, // 视频暂停更新进度 isPaused(val) { if (val) { this.updateLearningTime(this.currentTime) } }, }, mounted() { let _self = this // 水印 _self.waterText = window.localStorage.getItem('companyName') if (this.from == 'train') { this.sourceId = this.$route.query.trainId } else { this.sourceId = this.courseId } // 禁用鼠标右键 document.querySelector('.course-learn-body').onselectstart = document.querySelector('.course-learn-body').oncontextmenu = function () { return false } function KeyDown() { // 屏蔽鼠标右键、Ctrl+n、shift+F10、F5刷新、退格键 if (window.event.altKey && (window.event.keyCode == 37 || window.event.keyCode == 39)) { // 屏蔽 Alt+ 方向键 → event.returnValue = false } } document.onkeydown = KeyDown _self.getVideoDetail() }, beforeDestroy() { var _self = this _self.updateLearningTime(_self.currentTime) // 清除视频30秒记录定时器 clearInterval(_self.TimingUpdateProgress) }, destroyed() { }, methods: { onPlayerReady(player) { let _self = this _self.isStart = false console.log('Player is ready!', player) // 保存播放器实例以便后续使用 _self.player = player $('.vjs-control-bar').children().addClass('needsclick') // 修复:为播放器添加重播事件监听 player.on('replay', function () { console.log('重播事件触发') _self.resetPlayState() }) if (_self.isDrag == 'close' && !_self.canDrag) { // 禁止拖动 document.querySelector('.vjs-progress-control').style.pointerEvents = 'none' console.log('禁止拖动') } else { document.querySelector('.vjs-progress-control').style.pointerEvents = 'auto' console.log('可以拖动') } // 设置初始播放位置 player.currentTime(_self.currentTime) }, /** * 修复:重置播放状态的方法 */ resetPlayState() { console.log('重置播放状态') this.isEnded = false this.isPaused = false // 重置当前时间为0,从头开始播放 this.currentTime = 0 // 如果有播放器实例,重置播放器 if (this.player) { this.player.currentTime(0) } }, onPlayerPlay(player) { console.log('开始播放') // 修复:检查是否是播放结束后重新播放 if (this.isEnded) { this.resetPlayState() } // 设置初始播放位置 player.currentTime(this.currentTime) this.isPaused = false this.isEnded = false // 定时同步进度(30s一次) this.TimingUpdateProgress = setInterval(() => { this.updateLearningTime(this.currentTime) }, 30000) }, onPlayerTimeupdate(player) { console.log('播放中', this.nowCurrentTime) this.nowCurrentTime = player.currentTime().toFixed(2) this.currentTime = this.nowCurrentTime // 暂停时传递进度 if (this.isPaused) { this.currentTime = this.nowCurrentTime } // 修复:检查是否接近视频结尾,如果是,准备重置状态 const remainingTime = this.videoTotalLength - this.currentTime if (remainingTime < 1 && !this.isEnded) { // 即将结束,准备重置状态 console.log('视频即将结束,准备重置状态') } }, onPlayerPause(player) { console.log('暂停播放') // 防止拖动产生的pause事件重复发送请求 if (!this.isPaused) { clearInterval(this.TimingUpdateProgress) this.currentTime = player.currentTime().toFixed(2) this.isPaused = true } }, onPlayerEnded(player) { console.log('视频播放结束') // 添加isEnded判断,防止重复 if (this.isEnded) { return } // 结束播放时自动推出全屏 if (player.isFullscreen()) { player.exitFullscreen() } clearInterval(this.TimingUpdateProgress) // 播放完毕,设置进度条拖动状态 this.canDrag = true this.isEnded = true this.isPaused = true // 修复:更新最后的学习进度 this.updateLearningTime(this.videoTotalLength) // 修复:监听播放器的重播按钮点击 this.setupReplayListener(player) }, /** * 修复:设置重播监听器 */ setupReplayListener(player) { const _self = this // 监听重播按钮点击(video.js的重播按钮) const replayBtn = player.controlBar.replayControl if (replayBtn) { replayBtn.off('click') // 移除之前的监听器 replayBtn.on('click', function () { console.log('重播按钮被点击') _self.resetPlayState() // 延迟播放以确保状态已重置 setTimeout(() => { player.play() }, 100) }) } // 监听大重播按钮(结束时的重播按钮) const bigPlayButton = player.bigPlayButton if (bigPlayButton) { bigPlayButton.off('click') bigPlayButton.on('click', function () { console.log('大播放按钮被点击(可能是重播)') // 如果当前是结束状态,重置 if (_self.isEnded) { _self.resetPlayState() } }) } }, // 获取视频详情 async getVideoDetail() { let _self = this _self.isStart = true _self.coursewareId = _self.$route.query.coursewareId await getCourseLessonsDetail(_self.coursewareId, { from: _self.from, sourceId: _self.sourceId, courseId: _self.courseId, stageId: _self.stageId ? _self.stageId : _self.courseId, }).then(function (res) { let data = res.data _self.lessonData = data _self.nextCourseware = data.nextCourseware ? data.nextCourseware : {} if (data.convertStatus == 1) { let playbackRates = [] if (_self.doubleSpeed == 'open') { // 开启倍速 playbackRates = [0.5, 1.0, 1.5, 2.0] } else { // 不开启倍速 playbackRates = [] } _self.playerOptions = { //视频url设置,直播流为例 sources: [{ src: _self.lessonData.transCodeUri, //视频文件地址 type: 'application/x-mpegURL', //视频类型,这里可以不写,如果写一定要写对,否则会无法播放 }], playbackRates: playbackRates, fluid: false, autoplay: false, muted: false, inactivityTimeout: 2000, controls: true, responsive: true, // 修复:启用重播控制 replay: true } _self.mediaUri = _self.lessonData.transCodeUri let currentTime = _self.lessonData.progressBar ? _self.lessonData.progressBar : 0 _self.currentTime = currentTime _self.videoTotalLength = _self.lessonData.length _self.learnProgress = _self.lessonData.progress if (_self.learnProgress == 100) { _self.canDrag = true if (Number(_self.currentTime) >= Number(_self.videoTotalLength)) { // 如果已完成,且当前位置大于总时长,定位到0 _self.currentTime = 0 } } else { _self.canDrag = false } _self.currentTime = Math.round(_self.currentTime) // 修复:重置结束状态 _self.isEnded = false } else { // 转码失败 _self.$alert('视频文件正在转换中,稍后完成后即可查看', { confirmButtonText: '确定', callback: (action) => { _self.$router.replace({ name: 'knowledgeDetail', query: { uuid: _self.courseId, }, }) }, }) return false } }).catch((err) => { console.log(err) return }) }, // 更新课件播放时间公共方法(nowPlayTime:当前播放的时间) updateLearningTime(nowPlayTime) { let _self = this if (_self.isUpdateing) { return } _self.isUpdateing = true updateCourseLearning({ coursewareId: _self.coursewareId, progressBar: Number(nowPlayTime).toFixed(2), from: _self.from, sourceId: _self.sourceId, courseId: _self.courseId, stageId: _self.stageId ? _self.stageId : _self.courseId, }).then((res) => { setTimeout(() => { _self.isUpdateing = false }, 1000); if (res.data.progress == '100' && res.data.open) { // 已完成 let lessonInfo = {} if (_self.nextCourseware.uuid) { lessonInfo = { title: _self.nextCourseware.title, courseId: _self.nextCourseware.courseId, uuid: _self.nextCourseware.uuid, coursewareType: _self.nextCourseware.type, } } else { lessonInfo = { uuid: '' } } _self.$emit('nextLessonPlay', lessonInfo) } }).catch((err) => { _self.isUpdateing = false }) }, }, } </script> <style src="./video.less" lang="less"></style> <style lang="less"> .vjs-watermark { color: #fff; text-shadow: #000 2px 2px 2px; letter-spacing: 3px; position: relative; width: 200px; display: block; padding-left: 40px; box-sizing: border-box; text-align: center; white-space: nowrap; line-height: 30px; img { width: 30px; height: 30px; position: absolute; top: 0; left: 0; } } /* 修复:确保重播按钮可见 */ .vjs-control-bar .vjs-replay-control { display: block !important; } </style>添加注释,并优化
最新发布
12-12
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值