H5项目开发遇到的问题以及解决方案
bodymovin.js插件制作动画:复杂的动画使用css3来实现往往力不从心,大多数使用svg或canvas来做,但是要对api有一定的了解才能做出来,各种代码,过程繁杂,bodymovin可以实现在After Effect(可视化操作,不用码代码)上面导出 svg的json数据,然后在html上引入bodymovin.js,简单的初始化就可以在网页上面实现svg动画。
var animation = bodymovin.loadAnimation({ container: document.getElementById('wait_img'), renderer: 'svg', //svg、html loop: true, autoplay: true, path: ‘data.json’ //该json就是 After Effect的 bodymovin插件导出的json文件})
根据公司测试环境的配置不同,在提测阶段,代码放在测试环境上出现data.json文件404找不到的情况,经过排查是因为公司的测试环境不能识别.json文件,导致找不到data.json文件
处理方法:
查看了bodymovin.js的源码有一段关于path的配置:
if(params.animationData){ self.configAnimation(params.animationData);}else if(params.path){ if(params.path.substr(-4) != 'json'){ if (params.path.substr(-1, 1) != '/') { params.path += '/'; } params.path += 'data.json'; }}
可以选择传递到外部json文件的路径或通过animationData传递json对象,于是把data.json文件里的代码复制出来赋给一个对象
animationData: jsonData
let static_www = 'http://img.manhua.weibo.com'; //静态资源地址
let json_img = static_www+`/js/images/`; //图片地址
var jsonData = {"v":"5.1.7","fr":24,"ip":0,"op":24,"w":200,"h":200,"nm":"合成 2","ddd":0,"assets":[{"id":"image_0","w":78,"h":144,"u":json_img,"p":"img_0.png"}],"layers":[{"ddd":0,"ind":1,"ty":2,"nm":"组10@2x.png","cl":"png","refId":"image_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":0,"s":[20],"e":[-20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":3,"s":[-20],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":6,"s":[20],"e":[-20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":9,"s":[-20],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":12,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":36,"s":[0],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":37,"s":[20],"e":[-20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":40,"s":[-20],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":43,"s":[20],"e":[-20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":46,"s":[-20],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":49,"s":[0],"e":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":71,"s":[0],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":72,"s":[20],"e":[-20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":75,"s":[-20],"e":[20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":78,"s":[20],"e":[-20]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"n":["0p833_0p833_0p167_0p167"],"t":81,"s":[-20],"e":[0]},{"t":84}],"ix":10},"p":{"a":0,"k":[100,100,0],"ix":2},"a":{"a":0,"k":[39,72,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"ip":0,"op":4397,"st":0,"bm":0}],"markers":[]};
var animation = bodymovin.loadAnimation({
container: document.getElementById('wait_img'),
renderer: 'svg', //svg、html
loop: true,
autoplay: true,
animationData: jsonData //图片路径一定要正确!!!
})
CSS3动画字体淡入:改变opacity值
1.页面加载完成后执行字体淡入动画
.honely_zhi {
opacity: 0; /*实先规定文字的状态是不显示的*/
/*调用名称为fade-in的动画,全程动画显示时间4S,进入方式为ease,延时0S进入,播放次数1次*/
animation: fade-in 2s ease 0s 1;
-webkit-animation: fade-in 2s ease 0s 1;
-moz-animation: fade-in 2s ease 0s 1;
-o-animation: fade-in 2s ease 0s 1;
-ms-animation: fade-in 2s ease 0s 1;
/*规定动画的最后状态为结束状态*/
animation-fill-mode:forwards;
-webkit-animation-fill-mode: forwards;
-o-animation-fill-mode: forwards;
-ms-animation-fill-mode: forwards;
-moz-animation-fill-mode: forwards;
}
@keyframes fade-in{
0%{ opacity: 0;}
100%{opacity:1;}
}
淡入动画执行完后对该动画元素点击添加opacity会存在一个问题:
opacity添加不成功,因为之前淡入的动画影响的
解决方法:动态添加className
$(this).addClass("quest01_active").addClass("quest01_hover");
$(this).siblings().removeClass("quest01_active");
.quest01_active {
opacity: 0.4!important;
}
.quest01_hover {
animation-play-state:paused;
animation:none!important;
-webkit-animation:none!important;
opacity: 1;
}
2.animate动画图片淡入:fadeIn
在页面加载完成后执行animate动画在网络慢的情况会出现页面静态刷一次再重新刷一次页面出现动画
处理方法:还没找到具体原因,换成用CSS3动画代替
注意:CSS3动画在iphone8 p上不展示动画,另一个iphone8 p动画展示,经过排查是用户开启了手机里的减弱动态效果:设置 ------通用 ------辅助功能------ 减弱动态效果
解决方法:-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
解决方法:如果图片有点击事件,换做div元素插背景图;如果图片没有事件添加阻止事件的默认动作e.preventDefault();
1. 图片尺寸变大
2.图片宽高使用px做单位
3.去除页面上所有的边距样式
4.rem在安卓手机上渲染的不是很精准 ,图标是图片建议只设置宽度
复现操作:将安卓的系统字体调离标准大小,导致基础值出现问题。
解决办法:客户端固定webview字体大小。
在每个webview配置webview.getSettings().setTextZoom(100)就可以了
解决方法:
$(".text_bg .text_content").focus(function (){
document.querySelector('.text_content').scrollIntoView(true);
});
解决方法:window.scrollTo(0,0);
解决方法:css:overflow-y: scroll;
解决的方法:用ES6语法需要用babel转译下
1. Html界面与原生界面交互:
交互方法主要有两种,一种是通过JS方法,另一种是通过截取Html的跳转链接,开发过程中可以与前端开发者定义好跳转方法文档,预先埋点,便于各个活动中使用。
JS调用Android接口:
WebSettings settings = getSettings();
//默认是false 设置true允许和js交互
settings.setJavaScriptEnabled(true);
public class WebAppInterface {
Context mContext;
/** Instantiate the interface and set the context */
WebAppInterface(Context c) {
mContext = c;
}
/** Show a toast from the web page */
@JavascriptInterface
public void showToast(String toast) {
Toast.makeText(mContext, toast, Toast.LENGTH_SHORT).show();
}
}
SDK >=17(4.2)以上,必须添加@JavaScriptInterface声明,然后通过addJavaScriptInterface()方式供js调用如:
webView.addJavaScriptInterface(new WebAppInterface(this),"android");
活动调用html的JS方法时,7.0以上的手机正常调用,而7.0以下的手机调用无效,发现前端用了ES6语法,低于7.0的WebView运行不了JS,用了ES6语法需要用babel转译下。
解决方法:css:图片标签display:block, img{vertical-align:top}
//HTML页面结构
<meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" />
//js$.ajaxSettings.crossDomain = true
$.ajaxSettings.timeout = 12000$.ajaxSettings.xhrFields = {withCredentials: true}$.ajax({url:ajaxUrl.lucky_index, type:'GET', dataType : 'json', cache:false, //不使用缓存, cache只有GET方式的时候有效data:{},success:function() {},error:function () {},})