移动端h5监测图片长按保存操作实践

在做项目的时候我们都会多多少少写一些监测代码 ,之前也是遇到了一个比较搞的需求,大概就是我需要监测用户长按保存图片,我发现浏览器似乎没有原生提供这样一个API,没办法只能自己模拟写一个了,在实现的过程中也是踩了一些奇奇怪怪的坑,比如说安卓和苹果的表现是不一样的

好了话不多说先看实现效果:

核心代码如下:

ts 复制代码
// 判断是否是IOS设备
const isIos = (): boolean => /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream

// 监测用户图片长按保存操作
const useMonitorImgPressSave = (imgSelectorName: string, callback: () => void) => {

    try {

        /** 类型判断 */
        if (typeof imgSelectorName !== "string") {

            throw 'imgSelectorName 需要传 "string" 类型'

        }
        /** 类型判断 */
        if (typeof callback !== "function") {

            throw 'callback 需要传 "function" 类型'

        }

        const _imgDom = <HTMLImageElement>document.querySelector(imgSelectorName) ?? null
        /** 如果未找到dom元素 */
        if (!_imgDom) {

            throw `没有找到 "${imgSelectorName}" 选择器的dom元素`

        }
        /** 如果不是图片元素 */
        if (!(_imgDom instanceof HTMLImageElement)) {

            throw '不是一个 "图片" 元素,只能接受图片'

        }

        let _touchstartCallback: () => void, _touchendCallback: () => void

        /** FUN: 删除触摸监听 */
        const _imgDomRemoveEventListener = () => {

            _imgDom.removeEventListener("touchstart", _touchstartCallback)
            _imgDom.removeEventListener("touchend", _touchendCallback)

        }

        /** FUN: 设置安卓触摸 */
        const _setAndroidTouchMonitorEvent = () => {

            // 长按定时器
            let _pressTimer: any

            _touchstartCallback = () => {

                console.log("安卓触摸开始")

                clearTimeout(_pressTimer)
                _pressTimer = setTimeout(() => {

                    clearTimeout(_pressTimer)
                    /** 执行监测代码 */
                    callback()
                    _imgDomRemoveEventListener()

                }, 800)

            }

            _touchendCallback = () => {

                console.log("安卓触摸结束")
                clearTimeout(_pressTimer)
                _imgDomRemoveEventListener()

            }

            // 添加长按保存事件监听器(触摸开始)
            _imgDom.addEventListener("touchstart", _touchstartCallback)
            // 添加长按保存事件监听器(触摸结束)
            _imgDom.addEventListener("touchend", _touchendCallback)

        }

        /** FUN: 设置IOS触摸 */
        const _setIosTouchMonitorEvent = () => {

            // 长按开始时间
            let _pressStartTime: any

            _touchstartCallback = () => {

                console.log("苹果触摸开始")

                // ios环境下H5长按保存图片会造成图片悬浮,可以取消默认事件去除这种效果,并不阻止下拉菜单的弹出(注意:微信环境下没有问题,其他APP环境下无法保存)
                // 踩坑:如果是企业微信环境下,需要注释这条代码,否则ios无法长按保存图片
                // isWx() && event.preventDefault()
                _pressStartTime = Date.now()

            }

            _touchendCallback = () => {

                console.log("苹果触摸结束")
                /** 长按时间大于800毫秒执行监测代码 */
                Date.now() - _pressStartTime > 800 && callback()
                _imgDomRemoveEventListener()

            }

            // 添加长按保存事件监听器(触摸开始)
            _imgDom.addEventListener("touchstart", _touchstartCallback)
            // 添加长按保存事件监听器(触摸结束)
            _imgDom.addEventListener("touchend", _touchendCallback)

        }

        /** 由于安卓跟苹果的差异,当用户长按图片保存菜单弹出时,安卓不会触发touchend事件,苹果会,所以这里分2套 */
        isIos() ? _setIosTouchMonitorEvent() : _setAndroidTouchMonitorEvent()

    }
    catch (error) {

        console.error("useMonitorImgPressSave()", error)

    }

}

使用示例:

vue 复制代码
<script setup lang="ts">
onMounted(() => {

    useMonitorImgPressSave(".vue", () => {

        console.log("图片已保存")

    })

})
</script>

<template>
    <img class="vue" src="../assets/image/logo/vue.svg" />
</template>

希望能够给大家带来帮助!

相关推荐
bin91532 小时前
DeepSeek 助力 Vue 开发:打造丝滑的复制到剪贴板(Copy to Clipboard)
前端·javascript·vue.js·ecmascript·deepseek
晴空万里藏片云3 小时前
elment Table多级表头固定列后,合计行错位显示问题解决
前端·javascript·vue.js
曦月合一3 小时前
html中iframe标签 隐藏滚动条
前端·html·iframe
奶球不是球3 小时前
el-button按钮的loading状态设置
前端·javascript
kidding7233 小时前
前端VUE3的面试题
前端·typescript·compositionapi·fragment·teleport·suspense
Σίσυφος19005 小时前
halcon 条形码、二维码识别、opencv识别
前端·数据库
学代码的小前端5 小时前
0基础学前端-----CSS DAY13
前端·css
css趣多多6 小时前
案例自定义tabBar
前端
姑苏洛言8 小时前
DeepSeek写微信转盘小程序需求文档,这不比产品经理强?
前端
林的快手8 小时前
CSS列表属性
前端·javascript·css·ajax·firefox·html5·safari