关于uni-app中的分享,兼容webview页面的分享

最近在uni-app做app的时候做到了分享的功能,基本上实现了,但是在web-view页面的分享是不起效果的(因为uni-app的机制说明了webview的层级是最高的),后来几经周转,终于用 plus.nativeObj.View 做了一个底部弹出,特此记录一下,附带代码

首先写了一个全局的js文件,(因为我好多页面都用到这个分享)

复制代码
//plus.nativeObj.view解决弹窗问题,webview层级压制
var nvMask,nvImageMenu;
export default {
    show({list,cancelText,sharedata},callback){
        if(!list){
            list = [{
                "img":"https://bjetxgzv.cdn.bspapp.com/VKCEYUGU-dc-site/9a952c80-6080-11eb-a16f-5b3e54966275.png",
                "text":"图标文字"
            }]
        }
        if(list.length>8){
            return uni.showToast({
                title: '目前版本最多支持8个图标',
                icon: 'none'
            });
        }
        //数据
        var strShareUrl = sharedata.strShareUrl
        var strShareTitle = sharedata.strShareTitle
        var strShareSummary = sharedata.strShareSummary
        var strShareImageUrl = sharedata.strShareImageUrl
        var shareId = sharedata.id
        //以下为计算菜单的nview绘制布局,为固定算法,使用者无关关心
        var screenWidth = plus.screen.resolutionWidth
        //以360px宽度屏幕为例,上下左右边距及2排按钮边距留25像素,图标宽度55像素,同行图标间的间距在360宽的屏幕是30px,但需要动态计算,以此原则计算4列图标分别的left位置
        //图标下的按钮文字距离图标5像素,文字大小12像素
        //底部取消按钮高度固定为44px
        //TODO 未处理横屏和pad,这些情况6个图标应该一排即可
        var margin = 20,
            iconWidth = 60,
            icontextSpace = 5,
            textHeight = 12
        var left1 = margin / 360 * screenWidth
        var iconSpace = (screenWidth - (left1 * 2) - (iconWidth * 4)) / 3 //屏幕宽度减去左右留白间距,再减去4个图标的宽度,就是3个同行图标的间距
        if (iconSpace <= 5) { //屏幕过窄时,缩小边距和图标大小,再算一次
            margin = 15
            iconWidth = 40
            left1 = margin / 360 * screenWidth
            iconSpace = (screenWidth - (left1 * 2) - (iconWidth * 4)) / 3 //屏幕宽度减去左右留白间距,再减去4个图标的宽度,就是3个同行图标的间距
        }
        var left2 = left1 + iconWidth + iconSpace
        var left3 = left1 + (iconWidth + iconSpace) * 2
        var left4 = left1 + (iconWidth + iconSpace) * 3
        var top1 = left1
        var top2 = top1 + iconWidth + icontextSpace + textHeight + left1
        nvMask = new plus.nativeObj.View("nvMask", { //先创建遮罩层
            top: '0px',
            left: '0px',
            height: '100%',
            width: '100%',
            backgroundColor: 'rgba(0,0,0,0.2)'
        });
        nvMask.addEventListener("click", function() { //处理遮罩层点击
            nvMask.hide();
            nvImageMenu.hide();
        })
        nvImageMenu = new plus.nativeObj.View("nvImageMenu", { //创建底部图标菜单
            bottom: '0px',
            left: '0px',
            height: (iconWidth + textHeight + 2 * margin)*Math.ceil(list.length/4) +44+'px',//'264px',
            width: '100%',
            backgroundColor: 'rgb(255,255,255)'
        });
        
        let myList = []
        list.forEach((item,i)=>{
            myList.push({
                tag: 'img',
                src: item.img,
                position: {
                    top: eval('top'+( parseInt(i/4) +1)),
                    left: eval('left'+(1+i%4)),
                    width: iconWidth,
                    height: iconWidth
                }
            })
            myList.push({
                tag: 'font',
                text: item.text,
                textStyles: {
                    size: textHeight
                },
                position: {
                    top: eval('top'+(parseInt(i/4)+1)) + iconWidth + icontextSpace,
                    left: eval('left'+(1+i%4)),
                    width: iconWidth,
                    height: textHeight
                }
            })
        })
        
        //绘制底部图标菜单的内容
        nvImageMenu.draw([
            {
                tag: 'rect',//菜单顶部的分割灰线
                color: '#e7e7e7',
                position: {
                    top: '0px',
                    height: '1px'
                }
            },
            {
                tag: 'font',
                text: cancelText,//底部取消按钮的文字
                textStyles: {
                    size: '14px'
                },
                position: {
                    bottom: '0px',
                    height: '44px'
                }
            },
            {
                tag: 'rect',//底部取消按钮的顶部边线
                color: '#e7e7e7',
                position: {
                    bottom: '45px',
                    height: '1px'
                }
            },
            ...myList
        ])
        nvMask.show()
        nvImageMenu.show() //5+应支持从底部向上弹出的动画
        
        
        
        nvImageMenu.addEventListener("click",e=>{ //处理底部图标菜单的点击事件,根据点击位置触发不同的逻辑
            // console.log("click menu"+JSON.stringify(e));
            if (e.screenY > plus.screen.resolutionHeight - 44) { //点击了底部取消按钮
                nvMask.hide();
                nvImageMenu.hide();
            } else if (e.clientX < 5 || e.clientX > screenWidth - 5 || e.clientY < 5) {
                //屏幕左右边缘5像素及菜单顶部5像素不处理点击
            } else { //点击了图标按钮
                var iClickIndex = -1 //点击的图标按钮序号,第一个图标按钮的index为0
                var iRow = e.clientY < (top2 - (left1 / 2)) ? 0 : 1
                var iCol = -1
                if (e.clientX < (left2 - (iconSpace / 2))) {
                    iCol = 0
                } else if (e.clientX < (left3 - (iconSpace / 2))) {
                    iCol = 1
                } else if (e.clientX < (left4 - (iconSpace / 2))) {
                    iCol = 2
                } else {
                    iCol = 3
                }
                if (iRow == 0) {
                    iClickIndex = iCol
                } else {
                    iClickIndex = iCol + 4
                }
                // console.log("点击按钮的序号: " + iClickIndex);
                // if (iClickIndex >= 0 && iClickIndex <= 5) { //处理具体的点击逻辑,此处也可以自行定义逻辑。如果增减了按钮,此处也需要跟着修改
                // }
                // callback(iClickIndex)
                if (iClickIndex >= 0 && iClickIndex <= 5) { //处理具体的点击逻辑,此处也可以自行定义逻辑。如果增减了按钮,此处也需要跟着修改
                    var strProvider="",strScene=""
                    switch (iClickIndex) {
                        case 0:
                            strProvider = "weixin"
                            strScene = "WXSceneSession"
                            break;
                        case 1:
                            strProvider = "weixin"
                            strScene = "WXSenceTimeline"
                            break;
                        case 2:
                            strProvider = "sinaweibo"
                            break;
                        case 3:
                            strProvider = "qq"
                            break;
                        case 4:
                            uni.setClipboardData({
                                data: strShareUrl,
                                complete() {
                                    uni.showToast({
                                        title: "已复制到剪贴板"
                                    })
                                }
                            })
                            break;
                        case 5:
                            plus.share.sendWithSystem({
                                content: strShareUrl,
                            })
                            break;
                    }
                    if (strProvider!="") { //点击了0-3序号的这4个按钮
                        uni.share({
                            provider: strProvider,
                            scene:strScene,
                            type: 0,
                            href: strShareUrl,
                            title: strShareTitle,
                            summary: strShareSummary,
                            imageUrl: strShareImageUrl,
                            success: function(res) {
                                console.log("success:" + JSON.stringify(res));
                                callback(shareId)
                            },
                            fail: function(err) {
                                console.log("fail:" + JSON.stringify(err));
                            }
                        })
                    }
                }
                this.hide()
            }
        })
        /* nvImageMenu.addEventListener("touchstart", function(e) {
            if (e.screenY > (plus.screen.resolutionHeight - 44)) {
                //TODO 这里可以处理按下背景变灰的效果
            }
        })
        nvImageMenu.addEventListener("touchmove", function(e) {
            //TODO 这里可以处理按下背景变灰的效果
            if (e.screenY > plus.screen.resolutionHeight - 44) {}
        })
        nvImageMenu.addEventListener("touchend", function(e) {
            //TODO 这里可以处理释放背景恢复的效果
        })
        */
    },
    hide(){
        nvMask.hide()
        nvImageMenu.hide()
    }
}
复制代码

然后在你的父组件引用

 

 在你的methods中引入方法

复制代码
share(item){
                var that = this
                var sharedata = {
                    strShareUrl: that.$port.bbs_h5,
                    strShareTitle: item.type,
                    strShareSummary: item.topName,
                    strShareImageUrl: item.img,
                    id:item.id
                }
                uniImageMenu.show({
                    list:that.$global.shareList,  //底部的分享列表数组
                    cancelText:that.$global.resertText,   //取消分享的文字
                    sharedata:sharedata    //分享的内容
                }, index => {
                    // that.shareNum(index)
                    //此处是你执行的操作
                })
            },
复制代码

红色标注的是必须引用的,好了,亲测可用,欢迎讨论

 

posted @   星宝攸宁  阅读(2110)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示