注意事项
- Banner宽度缩放的范围是
300
到屏幕宽度
- Banner不要直接设置
style.height
而是通过设置style.width
由系统自由缩放Banner的height
- Banner不可以直接设置
style
属性,(直接设置style
属性会覆盖掉原有的style
属性,导致后续的style.width
/style.top
/style.left
无效)
//错误写法
let style:any = {width:300, top: 0, left:0};
Banner.style = style;
//正确的写法
let style:any = {width:300, top: 0, left:0};
Banner.style.width = style.width;
Banner.style.left = style.left;
Banner.style.top = style.top;
- Banner广告更新时要对旧的广告进行释放
Banner.destroy()
。
相关链接
相关类库
/**
* 微信Banner广告处理类
* 作者:大树
* 时间:2019-03-08
* 开源地址:https://my.oschina.net/17cto/blog/3020025
*
* [版本号:v1.0.0]
* 时间:2018-03-08
* 封装内容:
* 1.异常处理
* 2.添加定时刷新的功能
* 3.show的结束回调
* 4.屏幕尺寸与游戏场景尺寸的转化
*
* [版本号:v1.0.1]
* 时间:2018-03-09
* 1.添加对iphone X底部横条的处理
* 2.show()操作,添加开启与关闭定时器的功能
*
*/
export default class WxBannerAd {
//构造函数
constructor() { }
//当前已实例的Banner广告状态
static showStatus: boolean = false;
static loadStatus: boolean = false;
//当前已实例的Banner广告
static cache: any = null;
//初始化Banner广告
static init(obj: any = {}): void {
//初始化单位转化
let systemInfo: any = wx.getSystemInfoSync();
WxBannerAd.curModel = systemInfo.model;
WxBannerAd.windowHeight = systemInfo.windowHeight;
WxBannerAd.windowWidth = systemInfo.windowWidth;
WxBannerAd.stageHeight = Laya.stage.height;
WxBannerAd.stageWidth = Laya.stage.width;
//设置adUnitId列表
if (obj.adUnitId) {
if (typeof obj.adUnitId === "string") obj.adUnitId = obj.adUnitId.split(",");
console.log("obj.adUnitId", obj.adUnitId);
WxBannerAd.adUnitIds = obj.adUnitId;
if (WxBannerAd.adUnitIds.length) {
for (let v of WxBannerAd.adUnitIds) {
WxBannerAd.adUnitIdFailNum[v] = 0;
WxBannerAd.adUnitIdStatus[v] = true;
}
WxBannerAd.curAdUnitId = WxBannerAd.ramdonAdUnitId();
}
}
//设置Banner广告加载失败判定为id失效的最大请求失败数
if (obj.adUnitIdMaxFailNum) WxBannerAd.adUnitIdFailNum = obj.adUnitIdMaxFailNum;
//设置布局样式自定义样式
if (obj.style) {
WxBannerAd.styleCustom = obj.style;
//设置布局样式模式
if (obj.style.styleMode && WxBannerAd.styleModeList.indexOf(obj.style.styleMode) !== -1) WxBannerAd.styleMode = obj.style.styleMode;
}
//设置刷新定时器时间间隔
if (obj.interval) {
WxBannerAd.interval = obj.interval;
if (WxBannerAd.interval < WxBannerAd.intervalMin) WxBannerAd.interval = WxBannerAd.intervalMin;
}
//设置刷新定时器开启状态
if (obj.timerStatus) WxBannerAd.timerStatus = obj.timerStatus;
//初始化刷新定时
WxBannerAd.load();
if (WxBannerAd.timer) clearInterval(WxBannerAd.timer);
WxBannerAd.timer = setInterval(() => {
if (WxBannerAd.timerStatus && WxBannerAd.showStatus) {
WxBannerAd.timerSecond++;
if (WxBannerAd.timerSecond > WxBannerAd.interval) {
WxBannerAd.isTimerLoad = true;
WxBannerAd.load();
}
}
}, 1000);
}
//加载banner广告
static load(): void {
if (WxBannerAd.cache) WxBannerAd.cache.destroy();
let style: any;
if (WxBannerAd.isTimerLoad) {
style = WxBannerAd.styleCache.style;
WxBannerAd.styleHasBottom = WxBannerAd.styleCache.hasBottom;
WxBannerAd.styleBottomNum = WxBannerAd.styleCache.bottomNum;
WxBannerAd.isTimerLoad = false;
} else {
style = WxBannerAd.style;
}
WxBannerAd.cache = wx.createBannerAd({ adUnitId: WxBannerAd.ramdonAdUnitId(), style });
WxBannerAd.cache.onLoad(WxBannerAd.onLoad);
WxBannerAd.cache.onError(WxBannerAd.onError);
WxBannerAd.cache.onResize(WxBannerAd.onResize);
}
//显示banner广告
static show(options: any = {}, end: Function = null): void {
//设置布局样式自定义样式
if (options.style) {
WxBannerAd.styleCustom = options.style;
//设置布局样式模式
if (options.style.styleMode && WxBannerAd.styleModeList.indexOf(options.style.styleMode) !== -1) WxBannerAd.styleMode = options.style.styleMode;
}
//设置定时刷新的状态
if (options.timerStatus) WxBannerAd.timerStatus = options.timerStatus;
//是否实时更新
if (options.realtime) {
WxBannerAd.load();
if (end) WxBannerAd._onLoad = () => { WxBannerAd.cache.show(); end(); }
} else {
if (options.style && options.style.width && WxBannerAd.stage2windowWidth(options.style.width) !== WxBannerAd.cache.style.width)
WxBannerAd.onResize(WxBannerAd.onResize);
//[注意事项](https://my.oschina.net/17cto/blog/3020025)
let style = WxBannerAd.style;
WxBannerAd.cache.style.width = style.width;
WxBannerAd.cache.style.top = style.top;
WxBannerAd.cache.style.left = style.left;
WxBannerAd.cache.show();
if (end) end();
}
//设置开启状态
WxBannerAd.showStatus = true;
}
//隐藏banner广告
static hide(): void {
//隐藏Banner广告
if (WxBannerAd.cache) WxBannerAd.cache.hide();
//设置开启状态
WxBannerAd.showStatus = false;
}
//销毁banner广告
static destroy(): void { }
//监听banner广告尺寸变化事件
static onResize(res: any): void {
console.log("WxBanner onResize", res, WxBannerAd.styleHasBottom, WxBannerAd.styleBottomNum, WxBannerAd.cache);
WxBannerAd.cache.offResize(WxBannerAd.onResize);
console.log("WxBannerAd.cache.style.top", WxBannerAd.cache.style.top, "|", WxBannerAd.windowHeight, res.height, WxBannerAd.styleBottomNum)
if (WxBannerAd.styleHasBottom)
WxBannerAd.cache.style.top = WxBannerAd.windowHeight - res.height - WxBannerAd.styleBottomNum - (WxBannerAd.modelList.indexOf(WxBannerAd.curModel) !== -1 ? 5 : 0);
if (WxBannerAd._onResize) { WxBannerAd._onResize(res); WxBannerAd._onResize = null }
console.log("WxBanner onResize", res, WxBannerAd.cache);
}
static _onResize: Function = null;
//监听banner广告加载事件
static onLoad(): void {
console.log("WxBanner onLoad bannerCache", WxBannerAd.cache);
WxBannerAd.loadStatus = true;
WxBannerAd.cache.offLoad(WxBannerAd.onLoad);
if (WxBannerAd._onLoad) {
WxBannerAd._onLoad(WxBannerAd.cache.style);
WxBannerAd._onLoad = null;
}
}
static _onLoad: Function = null;
//监听banner广告错误事件
static onError(res: any): void {
WxBannerAd.cache.offError(WxBannerAd.onError);
switch (res.errCode) {
case 1002://广告单元无效
case 1005://广告组件审核中
case 1006://广告组件被驳回
case 1007://广告组件被封禁
case 1008://广告单元已关闭
WxBannerAd.adUnitIdStatus[WxBannerAd.curAdUnitId] = false;
break;
case 1000://后端接口调用失败
case 1001://参数错误
case 1003://内部错误
case 1004://无合适的广告
default:
WxBannerAd.adUnitIdFailNum[WxBannerAd.curAdUnitId]++;
setTimeout(() => {
WxBannerAd.load();
}, 3000);
break;
}
if (WxBannerAd._onError) { WxBannerAd._onError(res); WxBannerAd._onError = null; }
}
static _onError: Function = null;
//+----------------------------------------------------------------------------------------------------
//| Banner广告刷新机制
//+----------------------------------------------------------------------------------------------------
//是否开启自动切换广告
static timerStatus: boolean = false;
//定时器实例
static timer: any;
//自动切换的时间间隔(单位:s)
static interval: number = 600;
static intervalMin: number = 60;
//是否为自动刷新
static isTimerLoad: boolean = false;
//更新的秒数
static timerSecond: number = 0;
//+----------------------------------------------------------------------------------------------------
//| Banner广告ID处理
//+----------------------------------------------------------------------------------------------------
//当前使用的广告id
static curAdUnitId: string = null;
//有效的广告id列表
static adUnitIds: string[] = [];
//已经被检验失效的广告id
static adUnitIdsErr: string[] = [];
//每一个广告id最大的失败数
static adUnitIdMaxFailNum: number = 3;
//不同广告id的使用状态 格式:{广告ID:状态(false表示广告ID不可用、true表示广告ID可用)}
static adUnitIdStatus: any = {};
//不同广告id的加载失败次数 格式:{广告ID:失败次数}
static adUnitIdFailNum: any = {};
//随机获取一个adUnitId
static ramdonAdUnitId() {
if (WxBannerAd.adUnitIds.length) {
return WxBannerAd.adUnitIds[Math.floor(Math.random() * WxBannerAd.adUnitIds.length)];
} else {
return null;
}
}
//移除当前使用的广告id
static removeCurAdUnitId(): void {
if (WxBannerAd.adUnitIds.length && WxBannerAd.adUnitIds.indexOf(WxBannerAd.curAdUnitId) !== -1) {
if (WxBannerAd.adUnitIdsErr.indexOf(WxBannerAd.curAdUnitId) === -1)
WxBannerAd.adUnitIdsErr.push(WxBannerAd.curAdUnitId);
WxBannerAd.adUnitIds.splice(WxBannerAd.adUnitIds.indexOf(WxBannerAd.curAdUnitId), 1);
}
WxBannerAd.curAdUnitId = null;
}
//切换前当的广告id
static switchCurAdUnitId(adUnitId: string = null) {
if (adUnitId && WxBannerAd.adUnitIds.indexOf(adUnitId) !== -1) {
WxBannerAd.curAdUnitId = adUnitId;
} else {
WxBannerAd.curAdUnitId = WxBannerAd.ramdonAdUnitId();
}
}
//+----------------------------------------------------------------------------------------------------
//| 布局样式处理
//+----------------------------------------------------------------------------------------------------
//当前手机型
static curModel: string = "";
//需要做上移操作的手机型号
static modelList: string[] = ["iPhone X"];
//设备可使用窗口宽度
static windowWidth: number;
//设备可使用窗口高度
static windowHeight: number;
//游戏场景宽度
static stageWidth: number;
//游戏场景高度
static stageHeight: number;
//游戏场景宽度转设备可使用窗口宽度的转化
static stage2windowWidth(sw: number) { return sw * WxBannerAd.windowWidth / WxBannerAd.stageWidth; }
//游戏场景高度转设备可使用窗口高度的转化
static stage2windowHeight(sh: number) { return sh * WxBannerAd.windowHeight / WxBannerAd.stageHeight; }
//设备可使用窗口宽度转游戏场景宽度的转化
static window2stageWidth(ww: number) { return ww * WxBannerAd.stageWidth / WxBannerAd.windowWidth; }
//设备可使用窗口高度转游戏场景高度的转化
static window2stageHeight(wh: number) { return wh * WxBannerAd.stageHeight / WxBannerAd.windowHeight; }
//布局样式模式列表
static styleModeList: string[] = [
"left-top",//左上角布局
"center-top",//顶部居中布局
"right-top",//右上角布局
"left-bottom",//左下角布局
"center-bottom",//底部居中布局[默认值]
"right-bottom",//右下角布局
"top",//顶部居中布局
"bottom",//底部居中布局
];
//布局样式模式 none使用自定义样式 left-bottom左下角布局 center-bottom/bottom底部居中布局[默认值] right-bottom右下角布局
static styleMode: string = "center-bottom";
//自定义布局样式 (样式规则:有bottom则top无效,有right则left无效,有ceter则left与right无效)
static styleCustom: any = {};
//布局样式缓存(上一次show时的样式)
static styleCache: any = {};
//布局样式是否使用bottom布局
static styleHasBottom: boolean = false;//如果styleHasBottom=true的情况,当下一次onLoad完成之后将会进行Banner广告Bottom校验
static styleBottomNum: number = 0;//使用的单位类型为“可使用窗口高度”
//布局样式整理
static get style(): any {
WxBannerAd.styleHasBottom = false;
WxBannerAd.styleBottomNum = 0;
let style: any = {};
//设置宽度
style.width = WxBannerAd.styleCustom.width ? WxBannerAd.stage2windowWidth(WxBannerAd.styleCustom.width) : WxBannerAd.windowWidth;
if (style.width > WxBannerAd.windowWidth) style.width = WxBannerAd.windowWidth;
//设置位置
switch (WxBannerAd.styleMode) {
case "none":
if (WxBannerAd.styleCustom.bottom !== undefined) {
WxBannerAd.styleHasBottom = true;
WxBannerAd.styleBottomNum = WxBannerAd.stage2windowHeight(WxBannerAd.styleCustom.bottom);
style.top = WxBannerAd.windowHeight - style.width / 3 - WxBannerAd.styleBottomNum;
} else if (WxBannerAd.styleCustom.top !== undefined) {
style.top = WxBannerAd.stage2windowHeight(WxBannerAd.styleCustom.top);
} else {
WxBannerAd.styleHasBottom = true;
style.top = WxBannerAd.windowHeight - style.width / 3;
}
if (WxBannerAd.styleCustom.center !== undefined) {
style.left = WxBannerAd.windowWidth / 2 + WxBannerAd.stage2windowWidth(WxBannerAd.styleCustom.center) - style.width / 2;
if (style.left < 0) {
style.left = 0;
} else if (style.left > WxBannerAd.windowWidth - style.width) {
style.left = WxBannerAd.windowWidth - style.width;
}
} else if (WxBannerAd.styleCustom.right !== undefined) {
style.left = WxBannerAd.windowWidth - WxBannerAd.stage2windowWidth(WxBannerAd.styleCustom.right) - style.width;
} else if (WxBannerAd.styleCustom.left !== undefined) {
style.left = WxBannerAd.stage2windowWidth(WxBannerAd.styleCustom.left);
} else {
style.left = (WxBannerAd.windowWidth - style.width) / 2;
}
break;
case "left-top":
style.top = 0;
style.left = 0;
break;
case "right-top":
style.top = 0;
style.left = WxBannerAd.windowWidth - style.width;
case "top":
case "center-top":
style.top = 0;
style.left = (WxBannerAd.windowWidth - style.width) / 2;
break;
case "left-bottom":
WxBannerAd.styleHasBottom = true;
style.top = WxBannerAd.windowHeight - style.width / 3;
style.left = 0;
break;
case "right-bottom":
WxBannerAd.styleHasBottom = true;
style.top = WxBannerAd.windowHeight - style.width / 3;
style.left = WxBannerAd.windowWidth - style.width;
break;
case "bottom":
case "center-bottom":
default:
WxBannerAd.styleHasBottom = true;
style.top = WxBannerAd.windowHeight - style.width / 3;
style.left = (WxBannerAd.windowWidth - style.width) / 2;
break;
}
//缓存本次
WxBannerAd.styleCache = {
style,
hasBottom: WxBannerAd.styleHasBottom,
bottomNum: WxBannerAd.styleBottomNum,
};
return style;
}
}