最近刚刚入职新公司,还是以项目实习生的身份入职的。刚来就接到vue前端开发的任务,答主的vue经验还是在大学那会儿自个练习项目的程度。如果做的不好的还希望各位提出来。
这个需求的背景是在使用vant ui回显保存的敏感图片信息的时候,领导要求这种图片不能长按出现保存的弹出框。 网上查阅了好几种阻止手机端长按图片不弹出默认的保存/分享框的操作基本有三种
1、样式类
.prohibit-save img {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
思路是用来用户选择文本内容。 user-select: none; 这个属性可以防止用户复制网页上的文本内容,或者在网页中使用鼠标拖动选中文本。通常,这个属性会在网页上的一些不希望被用户修改或复制的内容(例如版权声明、注意事项等)上使用。
2、js阻止默认事件
// 获取所有的图片元素
const images = document.getElementsByTagName('img');
// 遍历图片元素并禁止默认行为
for (let i = 0; i < images.length; i++) {
const image = images[i];
// 监听长按事件
image.addEventListener('contextmenu', function(event) {
// 阻止默认行为
event.preventDefault();
});
// 监听 touchstart 事件
image.addEventListener('touchstart', function(event) { // 阻止默认行为
event.preventDefault();
});
}
第一个阻止打开电脑右键的弹出框,第二个是阻止图片的点击事件。 然而这个方法在移动端无效的,我没有去深究原理,大概是因为阻止电脑右键的弹框并不能阻止长按的移动端默认弹框。
3、添加蒙层
这也是答主的做法。分别在uploader显示小图片的地方添加蒙层,还有大屏预览图片的时候添加蒙层。这样小图片和图片预览会因为长按的是div而不会显示弹出框了。
<div class="container">
<div class="main">
<van-uploader
class="prohibit-save" //给需要添加阻止弹出的组件添加特定的css
ref="businesslicensepath"
v-model="files.businesslicensepath"
:max-count="1"
:after-read="uploadBusinessLicensePath"
:before-read="isImgType"
accept="image/png, image/jpeg"
:preview-options="{ closeable: true }"
/>
</el-form-item>
</div>
<div class="mask" v-show="showMask" @click="closeMask"></div>
</div>
data() {
return {
showMask: false,
}
},
methods: {
closeMask() {
this.showMask = false;
this.$refs["businesslicensepath"].closeImagePreview();
this.$refs["otherlicensepath"].closeImagePreview();
},
stopImgPreventDefault() {
this.$nextTick(() => {
const imgs = this.$el.querySelectorAll(".prohibit-save img");
if (imgs) {
imgs.forEach((img) => {
//在小图片上加遮罩防止长按可以下载图片
const div = this.createSmallMask();
img.parentNode.appendChild(div);
div.addEventListener("click", () => {
this.showMask = true;
});
});
}
});
},
createSmallMask() {
const div = document.createElement("div");
div.className = "small-img-mask";
div.style.position = "absolute";
div.style.top = "0";
div.style.height = "100%";
div.style.width = "100%";
return div;
},
}
<style scoped>
.prohibit-save .van-image {
position: relative;
}
.mask {
position: absolute;
top: 0;
height: 150%;
width: 100%;
z-index: 3000;
}
</style>
这样我们添加了 prohibit-save 类名的组件就都能阻止浏览器的默认弹框了。还不用担心各种css或者js事件在不同端的兼容性问题。 当然如果通用性比较强我们还可以考虑封装成组件。后续看项目上有没有这方面的需求在做吧