当一个java来做前端,完成手机端图片不能长按保存,他是这么做的。

119 阅读2分钟

最近刚刚入职新公司,还是以项目实习生的身份入职的。刚来就接到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事件在不同端的兼容性问题。 当然如果通用性比较强我们还可以考虑封装成组件。后续看项目上有没有这方面的需求在做吧

微信图片_20231024131349.jpg

微信图片_20231024131359.jpg