h5常用功能总结

一、微信自定义分享

1、问题:微信和浏览器间如何分享?

解决办法:首先,需要下载weixin-js-sdk库,并在分享文件中使用。在分享文件里面修改所需要的标题、图片、链接等信息,并引入到每个页面中。然后还需要在微信公众号平台配置网站链接等信息,这样就实现了微信内的分享。至于从浏览器分享到微信,则需要在index.html中配置名字、描述信息、网址、图片等meta头才可以实现。

代码:

 //放在index.html里面(图片无效)
 <meta property="og:type" content="website" />
  <meta name="title" content="为爱撑伞 一起防艾" />
  <meta name="description" content="防艾大有爱!百度营销携手杰士邦带你开启防艾旅途" />
  <meta name="url" content="https://jieshibang.jdpes.cn/h5/#/" />
  <meta name="image" content="https://jieshibang.jdpes.cn/h5/static/share_icon.jpg" />

//放在utils文件夹里面
import wx from "weixin-js-sdk";
function weixinSDK() {
    let url = location.href.split("#")[0];
    let title = "为爱撑伞 一起防艾";
    let desc = "防艾大有爱!百度营销携手杰士邦带你开启防艾旅途";
    let link = "https://jieshibang.jdpes.cn/h5/#/";
    let imgUrl = "https://jieshibang.jdpes.cn/h5/static/share_icon.jpg";
    uni.request({
        url: "https://chunfeng.jdpes.cn/Wxshare/share",
        method: "POST",
        data: {
            url: url
        }
    }).then((e) => {
        const [err, data] = e;
        if (err) {
            //请求失败
        }
        let response = data.data.data;
        // console.log(e);
        const config = {
            debug: false,
            appId: "wx79d2a8497dfd2a3c", // APPID
            timestamp: response.timestamp, // 上面main方法中拿到的时间戳timestamp
            nonceStr: response.nonceStr, // 上面main方法中拿到的随机数nonceStr
            signature: response.signature, // 上面main方法中拿到的签名signature
            jsApiList: [
                "updateAppMessageShareData",
                "updateTimelineShareData",
            ],
        };
        // console.log("config:::::::", config);
        wx.config(config);
        // ready
        wx.ready(function() {
            // 需在用户可能点击分享按钮前就先调用
            // console.log("ready..............................................");
            // 自定义“分享给朋友”及“分享到QQ”按钮的分享内容
            wx.updateAppMessageShareData({
                title: title,
                desc: desc,
                link: link,
                imgUrl: imgUrl,
                success: function() {
                    console.log("设置成功");
                },
            });
            // 自定义“分享到朋友圈”及“分享到QQ空间”按钮的分享内容
            wx.updateTimelineShareData({
                title: desc,
                desc: desc,
                link: link,
                imgUrl: imgUrl,
                success: function() {
                    console.log("设置成功");
                },
            });
        });
        wx.error(function(err) {    
            // alert(JSON.stringify(err))
            console.log("出错啦!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!", err);
        });
    });
}
export default weixinSDK;

2、问题:浏览器分享到微信时,在index.html中配置图片没有生效,分享链接不存在图片?

解决办法:给每个页面顶部设置一个1px的图片,浏览器就自动获取到首页第一个元素的图片,从而解决问题。

代码:

//给每个页面顶部设置一个1px的图片
<img class="share_icon" src="@/static/share_icon.jpg" />
.share_icon {
width: 1px;
height: 1px;    }

二、移动端视频播放

1、问题一:因为百度等浏览器会挟持原生video标签,给它设置默认的、无法更改的样式和功能等,如果有别的需求的话,没办法改变video标签,因此需要使用一些不同的办法在微信内置浏览器、百度等其他浏览器上实现自定义视频样式的播放?

解决办法 :目前使用了三种办法来播放视频,分别针对微信内置浏览器(不分ios和android)、ios系统下的其他浏览器和安卓系统下的其他浏览器。

1、微信内置浏览器

微信浏览器可以直接使用video标签来播放视频,ios端和安卓端都可以适配。主要是通过微信内置的h5同层播放器来拜托浏览器对video标签的挟持,从而实现自定义video标签。代码如下:

    <video class="video" poster="@/static/poster.jpg" :enable-progress-gesture="false" @ended="next" preload :controls="false" x-webkit-airplay="allow" :show-center-play-btn="false" x5-video-player-type="h5" x5-playsinline webkit-playsinline playsinline :src="videoSource" type="video/mp4">

2、ios系统

ios系统下的其他浏览器,需要使用canvas来不断绘制出video视频,再放到页面中去,这样就可以避免video标签被浏览器挟持的问题。

代码:

//ios设置视频的方法
    iosPlay() {
        //创建Video标签
        this.video = document.createElement('video');
        this.video.src = 'https://jieshibang.oss-accelerate.aliyuncs.com/wait.mp4';
        const container = document.getElementsByClassName("container");
        this.canvas = document.createElement("canvas");
        container[0].appendChild(this.canvas);
        // 初始化(创建)canvas
        if (this.canvas.getContext) {
            this.ctx = this.canvas.getContext('2d');
        }
        this.video.width = 750;
        this.video.height = 1624;
       // 设置canvas的宽度,这个设置的越大,画面越清晰,最好是视频大小(相当于绘制的图像大,然后被css缩小)
        this.canvas.width = 750; 
        this.canvas.height = 1624;
        //设置canvas宽高
        this.canvas.style.width = '100vw';
        this.canvas.style.height = 'auto';
        this.render();
        this.video.addEventListener('play', this.playCallBack);
    },
    // 绘制视频
    render() {
        //隐藏填充白屏的背景图
        this.hidden();
        //填充ios黑屏的背景
        this.ctx.fillStyle = '#0fb1df';
        // 绘制背景
        this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
        this.ctx.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
        if (this.video.paused) {
            this.video.play()
        } else {
            this.video.pause()
        }
    },
    playCallBack() {
        if (this.video.paused) {
            return;
        }
        this.ctx.drawImage(this.video, 0, 0, this.canvas.width, this.canvas.height);
        setTimeout(this.playCallBack, 16.7);
    },

3、安卓系统

安卓端播放视频需要使用jsmpeg.min.js这个库来实现,引入这个库之后,需要把视频的地址和canvas标签赋给实例,然后再配置一些需要的参数(如:自动播放、结束时跳转的方法等等),需要注意的是,视频的地址需要和项目的地址是同源的,不然会产生跨域的问题,这是由JSMpeg内部的请求导致的,没办法改变。

代码:

androidPlay() {
    //这里必须使用同一个域名下的视频文件,不然会跨域,这是由JSMpeg内部的请求导致的
    const url = "https://jieshibang.jdpes.cn/video/wait.ts";
    const container = document.getElementsByClassName("container");
    this.canvas = document.createElement("canvas");
    container[0].appendChild(this.canvas);
    // 设置canvas的宽度,这个设置的越大,画面越清晰,最好是视频大小(相当于绘制的图像大,然后被css缩小)
    this.canvas.width = 750; 
    this.canvas.height = 1624;
    //设置canvas宽高、裁剪视频,避免拉伸
    this.canvas.style.width = "100vw";
    this.canvas.style.height = "auto";
    this.player = new JSMpeg.Player(url, {
        canvas: this.canvas,
        loop: false,
        autoplay: true,
        disableGl: false,
        onEnded: () => {
            this.next(); //视频结束时跳转
        },
    });
},

2、问题二:在视频开始播放时出现了短暂黑屏的现象?

解决办法:当第一次播放视频的时候ios端,如果网络慢,视频从开始播到能展现画面会有短暂的黑屏(处理视频源数据的时间),为了避免这个黑屏,可以在视频上加个div浮层(可以是视频的第一帧),然后用timeupdate方法监听,视频播放及有画面的时候再移除浮层。

代码:

this.videoNode.addEventListener('timeupdate', () => {
    // 当视频的currentTime大于0.1时表示黑屏时间已过,已有视频画面,可以移除浮层
    if (this.videoNode.currentTime > 0.1 && !this.playing) {
        this.playing = true
    }
}, false)

3、问题三:视频自动播放?

解决办法:在微信浏览器端,android始终不能自动播放;ios的话,微信提供了一个事件WeixinJSBridgeReady,在微信嵌入webview全局的这个事件触发后,视频仍可以自动播放,这个应该是现在在ios端微信的视频自动播放的比较靠谱的方式,至于其他浏览器,建议引导用户去触屏的行为操作比较好(比如添加一个按钮立即播放,引导用户点击操作)。

4、问题四:视频变形的问题?

解决办法:在设置好视频的大小和canvans的大小之后,为避免不同手机出现视频拉伸变形的现象。可以使用object-fit: cover,它可以对视频进行裁剪,解决拉伸问题。object-fit属性可以解决视频出现上下黑边,不能全屏的问题。

三、预加载

问题:h5资源(图片、音频、视频)太多,加载速度慢,进入每个页面时会有白屏卡顿的现象?

解决办法:封装一个方法,在里面使用link元素,把传入的资源和类型赋给link,利用link的预加载属性来实现资源的预加载。

代码:

    preloadMedia('https://jieshibang.oss-accelerate.aliyuncs.com/wait.mp4', 'video');
    preloadMedia('https://jieshibang.oss-accelerate.aliyuncs.com/bg_home.jpg', 'image');
    preloadMedia('https://jieshibang.oss-accelerate.aliyuncs.com/bg_music.mp3', 'audio');
        
const preloadMedia = (url, type) => {
    var link = document.createElement('link');
    // link.rel = 'preload';
    link.rel = 'prefetch';
    link.href = url;
    link.as = type;
    link.crossorigin = "anonymous";
    // console.log(link.href);
    document.head.appendChild(link);
}
export default preloadMedia

四、rem适配的问题

问题:在使用rem适配方案时,ios和安卓在微信端的字体样式会产生差异 ?

解决办法:通过判断手机类型来改变字体样式。

代码:

isAndroid() {
    //判断手机类型改变按钮样式
    let u = navigator.userAgent;
    if (u.indexOf("Android") > -1 || u.indexOf("Linux") > -1) {
        // console.log("安卓");
        var ua = u.toLowerCase();
        if (ua.match(/MicroMessenger/i) == 'micromessenger') {
            //安卓微信端
            const showNum = document.getElementsByClassName("showNum");
            const lastThank = document.getElementsByClassName("lastThank");
            const save = document.getElementsByClassName("save");
            showNum[0].style.fontSize = "12px";
            lastThank[0].style.fontSize = '11px';
            lastThank[0].style.paddingTop = '13rem';
            save[0].style.fontSize = '10px';
            save[0].style.paddingTop = '20rem';
        }
        const share_button = document.getElementsByClassName("share_button");
        share_button[0].style.height = "110rem";
    }
}

五、音频播放

问题:在播放背景音乐时,因为浏览器的限制无法自动播放,并且需要在离开页面时停止播放音乐,进入页面时播放音乐?

解决办法:下载howler插件,在需要播放的页面下,onLoad中使用,onHide时暂停播放,onShow时播放(在uniapp中开发)。在微信浏览器下,音频资源 load 之后通过微信桥接触发播放;在其他浏览器下通过play()播放。

代码:

// Web Audio 初始化
<script>
onLoad() {
    this.soundBgm = new Howl({
        src: [assetsBgm],//音频地址
        loop: true,
        preload: true,
    })
    // 音频资源 load 之后通过微信桥接触发播放
    this.soundBgm.on('load', () => {
        //判断是否在微信浏览器(已封装)
        const iswx = isWx()
        if (iswx) {
            try {
                window.WeixinJSBridge.invoke('getNetworkType', {}, () => {
                    this.soundBgm.play();
                }, false);
            } catch (e) {
                // alert('error' + e.message)
                this.soundBgm.play();
            }
        } else {
            this.soundBgm.play();
        }
    })
},
onShow: function() {
    this.soundBgm?.stop();
    this.soundBgm?.play();
},
onHide: function() {
    this.soundBgm?.stop();
},
</script>

六、弹幕

问题:如何让弹幕在屏幕上移动,但是不能重复,并且无限循环?

解决办法:主要就是通过使用animation,让文字在屏幕从0移动到100的宽度,先把所有的弹幕放在一个等待的数组里面,从数组取出第一个弹幕,然后让每条弹幕跟上一个弹幕的弹道错开(+1),再不断的放到显示的数组里面,当动画执行完成之后清空数组。

代码:

showNextBullet() {
    if (!this.waitBullets.length) {
        return;
    }
    // 先确定弹道,跟上一个弹道错开即可
    this.currentLine = (this.currentLine % this.lines) + 1;
    // 从等待集合里取出第一个
    const currentBullet = this.newlist.shift();
    // 想要无限循环的话
    this.isInfinite &&
        this.newlist.push({
            id: +currentBullet.id + getUUID(),
            label: currentBullet.label,
            line: 0
        });
    // 设置弹幕的弹道
    currentBullet.line = this.currentLine;
    // 弹幕放进显示集合里,弹幕开始滚动
    this.showingBullets.push(currentBullet);

},
pxoveBullet(e) {
    this.showingBullets.shift();
}

七、生成海报

1、问题:如何把页面的dom结构转换成一张海报?

解决办法:通过引入html2canvas这个库,使用它的方法,先获取需要生成海报的dom节点,然后放入html2canvas(dom,{})这个方法中,然后再设置宽高、跨域等配置项,最后会生成一个在线的链接,放入页面中即可。

代码:

html2base64() {
            const dom = document.getElementById('osmdContainer');
            html2canvas(dom, {
                width: dom.offsetWidth,
                height: dom.offsetHeight,
                dpi: 300,
                scale: 3,
                useCORS: true,
            }).then((canvas) => {
                this.base64Url = canvas.toDataURL("image/png", 1.0);
            });
        },

2、注意:如果需要给生成的海报图片设置边框,需要使用内边框。因为生成海报的时候是按照dom元素的大小生成的,所以海报不能设置圆角,不然会有白边。

八、限制体验次数

问题:如何让每个人只能体验一次h5生成AI照片?

解决办法:使用localStorage存储生成的图片链接,然后在每个页面尝试取出图片链接,如果值为null,说明是第一次访问,就让用户跳转到首页去;如果值存在的话,就直接让用户跳转到结果页,直接查看图片即可。

  • 31
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值