css 点击(onMouseDown和onMouseUp)后,hover失效

当使用onMouseDown和onMouseUp事件改变CSS背景色时,会导致hover效果失效,因为内联样式优先级高于:hover。解决方法是避免使用!important来保持事件效果和悬停效果的正常工作。

希望结果

正常情况蓝色,悬停时浅蓝,onMouseDown时深蓝,onMouseUp时蓝色

最初代码

<style>
#div{
	background:蓝色;
}
#div:hover{
	background:浅蓝;	
}
<div id="div" onmousedown="mouseDown()" onmouseup="mouseUp()"></div>
<script>
function mouseDown(){
   $("#add").css({
     "background":"深蓝",
   });
 }
function mouseUp(){
   $("#add").css({
     "background":"蓝色",
   });
 }
</script>

最初代码结果

未触发onMouseDown、onMouseUp之前,正常时蓝色,悬停时浅蓝。
触发onMouseDown、onMouseUp之后,悬停效果消失

悬停效果消失原因

js代码修改css样式,等同于html中设置style的background属性,此时是内联样式,根据css样式优先级、特指度,内联样式的优先级要高于hover的优先级,所以hover失效了

解决办法

上面代码不动,修改部分如下:

function mouseUp(){
   $("#add").css({
     "background":"",
   });
 }

注意

不能采用在hover的css中加上!important的方式 #div:hover{ background:浅蓝 !important; }。由于!important优先级最高,onMouseDown和onMouseUp的效果会失效

<template> <div class="sImgEditorBox"> <div class="top" ref="viewDomP"> <a-spin :spinning="isShowLoading" class="fullBox"> <div ref="imageContainer"></div> <canvas id="preview_canvas" class="preview_canvas" :style="canvasStyle" ref="viewDom"></canvas> </a-spin> </div> <div class="bottom"> <div class="actionBox"> <span class="tip">{{isXsCpd?'提示:单击图片放大!':'提示:单击图片放大后,进行遮挡操作!'}}</span> <div class="actionBox1" v-show="status!='WAIT_MAKE_DOCUMENT'&&status!='LEADER_APPROVED'"> <a v-for="item in action" :key="item.action" :disabled="(!active && item.action !== 'upload') || item.disabled || isShowLoading" :class="`btn ${ ((!active && item.action !== 'upload') || item.disabled) && 'disabledBox' }`" @click="onClickAction(item)" > <a-tooltip placement="bottom"> <template slot="title"> <span>{{ item.label }}</span> </template> <a-icon :type="item.icon" /> </a-tooltip> </a> </div> </div> <div class="viewList flex"> <a-tabs :activeKey="active" @change="onChangeTab"> <!-- <a-tab-pane key="upload"> <span slot="tab"> <div class="btnUpload" @click="onUpload"> <a-icon type="plus-circle" /> <input type="file" class="hideDom" ref="upload" /> </div> </span> </a-tab-pane> --> <a-tab-pane v-for="item in imgs" :key="item.fileId"> <span slot="tab"> <img :src="item.src" class="viewListImg" /> </span> </a-tab-pane> </a-tabs> </div> </div> <!-- <a-modal v-model="isFullscreen" :footer="null" :closable="false" :mask="false" wrapClassName="transparent-modal" width="100%" style="top: 0; height: 100vh" :dialog-style="{ top: '0px' }" > --> <div class="fullscreen-container" v-show="isFullscreen"> <!-- 关闭按钮,右上角 --> <a-button class="close-fullscreen-btn" type="danger" icon="close" @click="toggleFullScreen" /> <a-carousel ref="carousel" :dots="false" :arrows="true" v-model="carouselIndex" class="image-carousel" @change="handleCarouselChange" > <!-- 上一张箭头(左侧) --> <div slot="prevArrow" slot-scope="props" class="custom-slick-arrow" style="left: 10px"> <a-icon type="left-circle" /> </div> <div v-for="(item, index) in imgs" :key="item.fileId" class="image-wrapper"> <img :src="item.src" /> </div> <!-- 下一张箭头(右侧) --> <div slot="nextArrow" slot-scope="props" class="custom-slick-arrow" style="right: 10px"> <a-icon type="right-circle" /> </div> </a-carousel> </div> <!-- </a-modal> --> </div> </template> <script> import ImagePreviewModal from './ImagePreviewModal.vue' import _ from "lodash"; export default { components: { ImagePreviewModal }, props: { dataSource: { type: Array, default: () => [], }, disabled: { type: Boolean, default: false, }, isXsCpd: { // 是否线上呈批单 type: Boolean, default: false } }, data() { this.onClickAction = _.debounce(this.onClickAction, 300); return { isShowLoading: false /* 是否显示loading */, canvas: null /* canvas对象 */, active: "" /* 当前编辑图片key */, imgs: [ /* 图片list */ // { // id: "1", // src: "/files/1.png", // }, // { // id: "2", // src: "/files/2.png", // }, ], currentImageUrl: null, currentImageName:null, status: '', // 状态 Yongyin:false, isShowLoading: false /* 是否显示loading */, rotation: 0, // 当前旋转角度(0、90、180、270) cachedImage: null, // 缓存的图片对象 isDraw: false /* 是否开始绘画 */, custAction: "" /* cover画正方形; eraser橡皮擦 */, canvas: null /* canvas对象 */, ctx: null /* 2d画布对象 */, startX: null /* 绘画开始X */, startY: null /* 绘画开始Y */, cache: [] /* 缓存步骤数据 */, cacheNum: 10 /* 缓存步骤数量 */, cacheDoubleBack: false /* 添加完缓存之后点击返回要返回两次 */, isFromCsdsh: false, //是否从措施审核待审核界面进入,是的话图片的所有按钮放开权限 /**拖拽需要的参数 */ dragging: false, // 是否正在拖拽 startX: 0, // 拖拽开始X坐标 startY: 0, // 拖拽开始Y坐标 translateX: 0, // X轴偏移量 translateY: 0, // Y轴偏移量 canvasPosition: { x: 0, y: 0 }, // 用于存储canvas的位置,用于拖拽时计算偏移量 /**缩放需要的参数 */ scale: 1, // 当前缩放比例 minScale: 0.1, // 最小缩放比例 maxScale: 4, // 最大缩放比例 originX: 0, // 缩放原点X originY: 0, // 缩放原点Y /**全屏参数 */ isFullscreen: false, // 是否全屏显示 carouselIndex: 0, }; }, computed: { action() { return [ /* 当前视图的操作 */ { label: "全屏", action: "fullscreen", icon: "fullscreen", disabled: this.disabled, }, { label: "上一个", action: "prev", icon: "left", disabled: this.disabled, }, { label: "下一个", action: "next", icon: "right", disabled: this.disabled, }, { label: "放大", action: "zoomIn", icon: "zoom-in", disabled: this.disabled, }, { label: "缩小", action: "zoomOut", icon: "zoom-out", disabled: this.disabled, }, { label: "逆时针旋转", action: "rotateL", icon: "undo", disabled: this.disabled, }, { label: "顺时针旋转", action: "rotateR", icon: "redo", disabled: this.disabled, }, { label: "撤回", action: "back", icon: "left", disabled: this.disabled, }, { label: "重置", action: "reset", icon: "retweet", disabled: this.disabled, }, { label: "下载", action: "download", icon: "download", disabled: this.disabled, }, { label: "保存", action: "save", icon: "save", disabled: this.disabled, }, { label: "遮挡", action: "cover", icon: "copy", disabled: this.disabled, }, { label: "删除", action: "delete", icon: "delete", disabled: this.disabled, }, { label: "上传", action: "upload", icon: "upload", disabled: this.disabled, }, ]; }, /** 计算canvas的样式 */ canvasStyle() { return { transform: `translate(${this.canvasPosition.x}px, ${this.canvasPosition.y}px)`, }; }, }, watch: { dataSource: { handler(val) { this.imgs = val || []; let hasActive = _.find(this.imgs, { fileId: this.active }); if (hasActive) { this.resetView(this.getItem(this.active)?.src, true, true); return; } if (this.imgs.length > 0) { this.onChangeTab(this.imgs[0]?.fileId); } else { this.active = null; } }, deep: true, // 深度监听 immediate: true, // 立即执行 }, }, created() { this.status = this.$utils.getSearchKeys('status') this.resetView(this.currentImageUrl); }, methods: { handleImage() { this.imgShow = true; // this.currentImageUrl = this.getItem(this.active).src; // this.currentImageName = this.getItem(this.active).downloadFileName; }, onUpload() { /* 点击上传摁扭 */ // let dom = this.$refs.upload; // dom.click(); this.$emit("onUpload"); }, onChangeTab(e) { /* 切换图片 */ if (e === this.active) return; this.cache = [] this.active = e; this.currentImageUrl = this.getItem(this.active).src; this.currentImageName = this.getItem(this.active).downloadFileName; /* 销毁对象 */ this.resetData(); this.resetView(this.getItem(this.active)?.src, true, true); }, onClickAction(item) { if (this.isShowLoading) return; /* 点击当前视图操作 */ const { action } = item; switch (action) { case "fullscreen": this.toggleFullScreen(); break; case "prev": this.prev(); break; case "next": this.next(); break; case "zoomIn": this.zoomIn(); break; case "zoomOut": this.zoomOut(); break; case "rotateL": this.rotateImage(-90); break; case "rotateR": this.rotateImage(90); break; case "back": this.onBackFromCache(); break; case "reset": this.onReset(); break; case "download": this.onSave("download"); break; case "save": this.onSave(); break; case "cover": this.onClickImgAction(item); break; case "upload": this.$emit("onUpload"); break; case "delete": this.onDelete(item); break; } }, onDelete() { this.$emit("onDelete", this.getItem(this.active)); }, onReset() { this.resetData(); this.$emit("onReset", this.getItem(this.active)); }, onSave(type) { /* 保存、下载 */ /* 图片地址需允许跨域或者在同一域名下 */ var canvas = document.querySelector("#preview_canvas"); var data = canvas.toDataURL("image/jpeg"); if (type === "download") { if(window.navigator.msSaveOrOpenBlob){ var bstr = atob(data.split(',')[1]); var n = bstr.length; var u8arr = new Uint8Array(n); while(n--) { u8arr[n] = bstr.charCodeAt(n); } var blob = new Blob([u8arr]); window.navigator.msSaveOrOpenBlob(blob,this.currentImageName) }else { let a = document.createElement("a"); a.download = this.currentImageName; a.href = data; //审批材料下载方法 a.dispatchEvent(new MouseEvent("click")); } } // this.cache = [] this.resetData() this.$emit("onSave", { data, ...this.getItem(this.active) }); }, getItem(fileId) { let item = _.find(this.imgs, { fileId }); return item; }, // 获取合适的比例(要展示完全) getImageRightProportion (imageWidth, imageHeight) { const viewDomP = this.$refs.viewDomP; const padding = 16; const containerWidth = viewDomP.clientWidth - padding; const containerHeight = viewDomP.clientHeight - padding; const widthProportion = containerWidth / imageWidth; const heightProportion = containerHeight / imageHeight; const proportion = Math.min(widthProportion, heightProportion) return Math.floor(proportion * 100) / 100; }, // resetView(path) { // console.log('=============================path', path); // //创建图片 // let image = new Image(); // //设置图片地址 // image.src = path + `?uuid=${this.$utils.getId()}`; // this.isShowLoading = true; // image.onload = (e) => { // const {width, height} = image; // const proportion = this.getImageRightProportion(width, height); // image.width = width * proportion; // image.height = height * proportion; // this.$refs.imageContainer.childNodes.forEach((node) => { // this.$refs.imageContainer.removeChild(node); // }) // this.$refs.imageContainer.appendChild(image) // this.isShowLoading = false; // }; // }, onClickImgAction(item) { if (this.isShowLoading) return; /* 点击图片操作 */ const { action } = item; if (this.custAction === action) { this.custAction = ''; } else { this.custAction = action; } }, resetView(path) { /* 重新绘制图片 */ let canvas, ctx; if (!this.ctx) { canvas = this.$refs.viewDom; ctx = canvas.getContext("2d"); // 设置 willReadFrequently 属性 if (ctx.willReadFrequently) { ctx.willReadFrequently = true; } this.ctx = ctx; this.canvas = canvas; this.initCanvas(); } else { ctx = this.ctx; canvas = this.canvas; } //创建图片 let image = new Image(); //设置图片地址 image.src = path + `?uuid=${this.$utils.getId()}`; this.isShowLoading = true; // 必须要在onLoad之后再进行绘制图片,否则不会渲染 image.onload = (e) => { this.cachedImage = image; // 缓存图片对象 // 绘制图像(考虑旋转角度) this.redrawImage(); this.isShowLoading = false; }; }, initCanvas() { /* 给canvas注入事件 */ //鼠标摁下时 this.canvas.onmousedown = (event) => { const pos = this.getActualPosition(event); if (this.custAction) { // 绘图处理代码 this.isDraw = true; if (this.custAction === "eraser") { this.ctx.lineWidth = "10"; this.ctx.strokeStyle = "#fff"; } if (this.custAction === "cover") { this.ctx.lineWidth = 1; this.ctx.fillStyle = "#ddd"; } this.ctx.beginPath(); this.ctx.moveTo(pos.x, pos.y); this.startX = pos.x; this.startY = pos.y; return; } this.startDrag(event); // 拖拽处理代码 }; //鼠标开始移动时绘图 this.canvas.onmousemove = (event) => { const pos = this.getActualPosition(event); // 如果正在进行绘图操作,跳过拖拽 if (this.custAction && this.isDraw) { if (this.custAction === "eraser") { this.ctx.lineTo(pos.x, pos.y); } if (this.custAction === "cover") { this.ctx.fillRect( this.startX, this.startY, pos.x - this.startX, pos.y - this.startY ); this.ctx.closePath(); } this.ctx.stroke(); return; } this.doDrag(event); }; //鼠标松开时停止绘图 this.canvas.onmouseup = () => { if (this.custAction) { this.isDraw = false; //将此时绘制的信息存储到cache数组中 this.addCache(); } this.endDrag(); }; //鼠标移出this.canvas后停止绘图 this.canvas.onmouseout = () => { if (this.custAction) { this.isDraw = false; } this.endDrag(); }; // 设置初始光标样式 // this.canvas.style.cursor = 'grab'; // 添加滚轮缩放支持 // this.canvas.addEventListener('wheel', this.handleWheel, { passive: false }); }, addCache() { /* 添加缓存 */ let imgCache = this.ctx?.getImageData( 0, 0, this.canvas.width, this.canvas.height ); this.cache.push(imgCache); if (this.cache.length > this.cacheNum) { this.cache.shift(); } this.cacheDoubleBack = true; }, /* 获取最新缓存 */ getCache() { let imgCache; if (this.cache.length === 1) { imgCache = this.cache[0]; } else { imgCache = this.cache.pop(); } return imgCache; }, onBackFromCache() { /* 返回操作 */ let imgCache = this.getCache(); if (this.cacheDoubleBack) { /* 如果需要返回两次,再拿一遍 */ imgCache = this.getCache(); this.cacheDoubleBack = false; } if (!imgCache) return; this.ctx.putImageData(imgCache, 0, 0); }, // 旋转图片方法 rotateImage(degrees) { if (this.isShowLoading || !this.cachedImage) return; // 重置缩放 this.scale = 1; this.originX = 0; this.originY = 0; // 重置位置偏移量 this.translateX = 0; this.translateY = 0; this.lastPosition = { x: 0, y: 0 }; // 保存当前旋转角度 // 更新旋转角度(确保在0-360度范围内) this.rotation = (this.rotation + degrees + 360) % 360; // 清空之前的遮挡操作 this.cache = []; this.custAction = ""; // 重新绘制画布 this.redrawImage(); }, // 重新绘制图像(使用当前旋转角度) redrawImage() { const ctx = this.ctx; const canvas = this.canvas; const image = this.cachedImage; // const imgWidth = image.width; // const imgHeight = image.height; const {width, height} = image; const proportion = this.getImageRightProportion(width, height); const imgWidth = width * proportion; const imgHeight = height * proportion; // 根据旋转角度确定画布大小 if (this.rotation % 180 === 0) { canvas.width = imgWidth; canvas.height = imgHeight; } else { canvas.width = imgHeight; canvas.height = imgWidth; } // 清空画布 ctx.clearRect(0, 0, canvas.width, canvas.height); // 保存当前画布状态 ctx.save(); // 应用平移变换 ctx.translate(this.translateX, this.translateY); // 应用缩放(以画布中心为缩放中心) ctx.translate(this.originX, this.originY); ctx.scale(this.scale, this.scale); ctx.translate(-this.originX, -this.originY); // 计算中心点并平移 ctx.translate(canvas.width / 2, canvas.height / 2); // 执行旋转(转为弧度) ctx.rotate((this.rotation * Math.PI) / 180); // 绘制图片(将图片原点移到中心) ctx.drawImage(image, -imgWidth / 2, -imgHeight / 2, imgWidth, imgHeight); // 恢复画布状态 ctx.restore(); // 设置canvas的显示尺寸(CSS尺寸)为实际像素尺寸乘以缩放比例 canvas.style.width = `${canvas.width * this.scale}px`; canvas.style.height = `${canvas.height * this.scale}px`; // 添加初始缓存(用于撤回操作) this.addCache(); }, resetData() { this.ctx?.clearRect(0, 0, this.canvas.width, this.canvas.height); this.rotation = 0; this.cachedImage = null; this.custAction = ''; this.cache = []; this.canvas = null; this.ctx = null; // 重置拖拽状态 this.dragging = false; this.translateX = 0; this.translateY = 0; this.canvasPosition.x = 0; this.canvasPosition.y = 0; // 重置缩放 this.scale = 1; this.originX = 0; this.originY = 0; }, /**拖拽相关方法 */ startDrag(event) { // 只响应左键拖拽 if (event.button !== 0 || this.custAction) return; this.dragging = true; this.startX = event.clientX; this.startY = event.clientY; this.canvas.style.cursor = 'grabbing'; }, doDrag(event) { if (!this.dragging) return; const deltaX = event.clientX - this.startX; const deltaY = event.clientY - this.startY; // 更新canvas的位置 this.canvasPosition.x += deltaX; this.canvasPosition.y += deltaY; }, endDrag() { if (!this.dragging) return; this.dragging = false; this.canvas.style.cursor = 'default'; }, /**放大缩小相关方法 */ zoomIn() { if (this.scale >= this.maxScale) return; // 计算缩放中心点(画布中心) const canvas = this.canvas; this.originX = canvas.width / 2; this.originY = canvas.height / 2; // 增加缩放比例 this.scale = Math.min(this.scale * 1.2, this.maxScale); this.redrawImage(); }, zoomOut() { if (this.scale <= this.minScale) return; // 计算缩放中心点(画布中心) const canvas = this.canvas; this.originX = canvas.width / 2; this.originY = canvas.height / 2; // 减少缩放比例 this.scale = Math.max(this.scale * 0.8, this.minScale); this.redrawImage(); }, handleWheel(event) { event.preventDefault(); // 计算缩放中心点(鼠标位置) const rect = this.canvas.getBoundingClientRect(); this.originX = event.clientX - rect.left; this.originY = event.clientY - rect.top; // 根据滚轮方向调整缩放比例 if (event.deltaY < 0) { this.zoomIn(); } else { this.zoomOut(); } }, /**上一张下一张所需方法 */ prev(){ let index = this.imgs.findIndex(item => item.fileId == this.active) if (index-1 >= 0) { this.onChangeTab(this.imgs[index-1].fileId) }else{ return } }, next(){ let index = this.imgs.findIndex(item => item.fileId == this.active) if (index+1 < this.imgs.length) { this.onChangeTab(this.imgs[index+1].fileId) }else{ return } }, /**全屏所需方法 */ toggleFullScreen() { if (!this.isFullscreen) { // 打开全屏前设置当前索引 this.carouselIndex = this.imgs.findIndex( img => img.fileId === this.active ); // 如果找不到,默认显示第一张 if (this.carouselIndex === -1) { this.carouselIndex = 0; } // 使用 $nextTick 确保 DOM 更新 this.$nextTick(() => { // 手动设置轮播位置 if (this.$refs.carousel && this.$refs.carousel.goTo) { this.$refs.carousel.goTo(this.carouselIndex); } }); } this.isFullscreen = !this.isFullscreen; }, handleCarouselChange(current) { this.carouselIndex = current; // 更新激活的图片 if (this.imgs[current]) { this.active = this.imgs[current].fileId; this.currentImageUrl = this.imgs[current].src; this.currentImageName = this.imgs[current].downloadFileName; } }, // 添加坐标转换方法 getActualPosition(event) { const rect = this.canvas.getBoundingClientRect(); return { x: (event.clientX - rect.left - this.translateX) / this.scale, y: (event.clientY - rect.top - this.translateY) / this.scale }; } }, }; </script> <style lang="less" scoped> .sImgEditorBox { width: 100%; height: 100%; } .top { height: calc(100% - 120px); padding-top: 16px; width: 100%; text-align: center; overflow: auto; } .bottom { position: relative; height: 120px; background: #fff; z-index: 1; .actionBox { height: 40px; border-top: 1px solid #dadada; border-bottom: 1px solid #dadada; display: flex; justify-content: space-between; } .tip { display: flex; align-items: center; padding-left: 8px; color: red; } .actionBox1 { text-align: right; display: flex; align-items: center; a, div { display: inline-block; margin-right: 16px; font-size: 20px; } } .viewList { height: calc(100% - 40px); padding: 0 16px; .viewListImg, .btnUpload { display: inline-block; width: 40px; height: 60px; } .btnUpload { border: 1px dashed #2160b8; display: flex; justify-content: center; align-items: center; } } } /deep/ .anticon { margin: 0 !important; } /deep/ .ant-tabs-tab { padding: 14px 5px !important; } /deep/ .ant-tabs, /deep/.ant-tabs-bar, /deep/ .ant-tabs-nav-container, /deep/.ant-tabs-nav-wrap, /deep/ .ant-tabs-nav-scroll, /deep/.ant-tabs-nav { height: 100%; } .hideDom { display: inline-block; visibility: hidden; width: 0px; height: 0px; } .btn { color: #555; } .btn:hover { color: #1890ff; } .selBtn { color: #1890ff; } .disabledBox { color: #ddd; } /**全屏样式 */ // 全屏容器 .fullscreen-container { position: fixed; top: 0; left: 0; z-index: 1000; width: 100%; height: 100vh; display: flex; flex-direction: column; justify-content: center; align-items: center; background: rgba(0, 0, 0, 0.6); // 轮播图容器 .image-carousel { width: 100%; height: 100%; .slick-slide { display: flex !important; justify-content: center; align-items: center; height: 100%; } // 自定义左右箭头样式 .custom-slick-arrow { position: absolute; z-index: 1000; top: 50%; transform: translateY(-50%); width: 60px; height: 100px; display: flex !important; align-items: center; justify-content: center; background: rgba(0, 0, 0, 0.4); border-radius: 5px; font-size: 32px; color: white; transition: all 0.3s ease; &:before { display: none; } &:hover { background: rgba(0, 0, 0, 0.7); transform: translateY(-50%) scale(1.1); } } // 左侧箭头 [slot="prevArrow"] { left: 10px; } // 右侧箭头 [slot="nextArrow"] { right: 10px; } } } // 图片包装 .image-wrapper { // max-width: 90%; // max-height: 90%; overflow: auto; display: flex !important; justify-content: center; align-items: center; height: 100%; img { max-width: 100%; max-height: 100vh; object-fit: contain; box-shadow: 0 0 20px rgba(0, 0, 0, 0.3); } } // 关闭按钮样式(右上角) .close-fullscreen-btn { position: absolute; top: 20px; right: 20px; z-index: 1001; // 确保在最上层 background: rgba(255, 255, 255, 0.3); border: none; color: white; font-size: 24px; width: 48px; height: 48px; display: flex; align-items: center; justify-content: center; border-radius: 50%; transition: all 0.3s ease; &:hover { background: rgba(255, 0, 0, 0.7); transform: scale(1.1); } } </style> 这个是我改完的,先遮挡后放大,遮挡丢失为什么?
06-16
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值