Write By Monkeyfly
以下内容均为原创,如需转载请注明出处。
问题描述
- 广告位需要在生效时间内进行展示,这就需要将
当前时间
和广告位配置的开始时间以及结束时间
进行比较。 - 如果当前时间位于广告生效期内则展示,否则就隐藏。
问题分析
- 从配置文件中拿到的时间格式为:
2018-07-04 23:17:43.0
- 所以要将获取到的具体时间转化为毫秒数才能进行比较,故使用了
Date
对象的静态方法parse()
。 - 使用时并没有想到该方法会存在兼容性问题,即
IOS
系统会出现无法转换的问题。 - 主要原因是测试时只用了安卓手机,并没有想到
Date.parse()
方法在苹果手机上会有问题。
具体代码如下所示:
//从后台配置的静态js文件中获取广告位的配置项(随意写的,仅供参考)
var cashBonusArr = adConfig.ad_code;
//用于接收配置项中广告的开始和结束时间
var ad_starttime="",ad_endtime="";
var showAd=false;//是否显示广告的标识
var validAdArr=[];//用于保存在有效时间内的广告
//当前时间
var currentTime = new Date().getTime();
function showAdvertise(cashBonusArr){
if(cashBonusArr){//如果广告位的配置存在则显示
for (var i = 0; i < cashBonusArr.length; i++) {//配置的广告都保存在一个数组里
if(cashBonusArr[i].ad_picture){//如果配置了图片,再判断时间是否有效
ad_starttime = transformTime(cashBonusArr[i].ad_starttime);//广告开始时间
ad_endtime = transformTime(cashBonusArr[i].ad_endtime);//广告结束时间
if(currentTime>ad_starttime && currentTime<ad_endtime){//若在广告生效时间内则展示广告
validAdArr.push(cashBonusArr[i]);
showAd = true;
}
}else{//如果未配置图片,则继续判断数组中的下一个元素
continue;
}
}
}else{//如果广告位的配置不存在则隐藏
showAd = false;
}
if(showAd){//展示广告
for (var i = 0; i < validAdArr.length; i++) {
$(".swiper-wrapper").append('<a href="' +validAdArr[i].ad_link+ '" class="swiper-slide"><img src="' +validAdArr[i].ad_picture+ '" class="cashBonus-pic" id="cashBonus_pic" alt="' +validAdArr[i].ad_title+ '"></a>');
}
$(".advertise-place").show();
startSlide();//开启轮播图(注:使用swiper插件即可实现自定义的轮播图效果)
}else{//隐藏广告
$(".advertise-place").hide();
}
}
/** parse() 方法可解析一个日期时间字符串,并返回 1970/1/1 午夜距离该日期时间的毫秒数。
* 参数:datastring 表示日期和时间的字符串。
* 注:该方法是 Date 对象的静态方法。一般采用 Date.parse() 的形式来调用。
*/
//时间转换方法
function transformTime(t){
return Date.parse(t);
}
//开启轮播图(此处自定义了分页器的样式)
function startSlide(){
var mySwiper = new Swiper ('.swiper-container', {
loop: true,
autoplay:true,
// 如果需要分页器
pagination: {
el: '.swiper-pagination',
type: 'custom',// 自定义分页器,必须的type类型
renderCustom: function (swiper, current, total) {
var paginationHtml = "";
current = current -1;
for(var i= 0; i< total; i++) {
// 判断是不是激活焦点,是的话添加active类,不是就只添加基本样式类
if(i === current){
paginationHtml += '<span class="swiper-pagination-customs swiper-pagination-customs-active"></span>';
continue;
}
paginationHtml += '<span class="swiper-pagination-customs"></span>';
}
return paginationHtml;
}
},
});
}
Date.parse()
方法在安卓和苹果手机上的不同表现
参考资料:详见 Date.parse() - JavaScript | MDN
经过手动测试得知:
- 安卓手机:会正常返回毫秒数,只要是符合要求的时间字符串即可,要求比较宽松。
- 苹果手机:会返回
NaN
。形如2018-07-24 23:17:43
的时间字符串的格式不被支持,不符合标准。
经过查阅资料得知:
1.语法:
//显式调用
Date.parse(dateString)
//隐式调用
new Date(dateString)
/** 参数:dateString
* 一个符合 RFC2822 或 ISO 8601 日期格式的字符串(其他格式也许也支持,但结果可能与预期不符)。
* 返回值:
* 一个表示从1970-1-1 00:00:00 UTC到给定日期字符串所表示时间的毫秒数的数值。
* 注:如果参数不能解析为一个有效的日期,则返回NaN。
*/
2,描述:
Date.parse()
方法接受一个表示时间的字符串,返回相应的时间值。- 如果传入
Date.parse()
方法的参数不能解析为一个有效的日期,则返回NaN
。 - 如果该时间字符串无法识别,或者一些情况下,包含了不合法的日期数值
(如:2015-02-31)
,则返回值为NaN
。 - 字符串的解析完全取决于实现。直到至今,不同宿主
(指各大浏览器厂商)
在如何解析日期字符串上仍存在许多差异。 - 由于在解析日期字符串时存在偏差会导致结果不一致,因此推荐始终手动解析日期字符串。
3,引擎相关的日期格式
ECMAScript
规范规定:如果一个字符串不符合标准格式,则函数可以使用任何由引擎决定的策略或解析算法。Date.parse()
对于因包含有无效元素
而无法识别
的ISO
格式字符串或者日期,应该返回NaN
。- 在如
ECMA-262
规范中定义的情况,如果因为无效值而导致日期字符串不能被识别为ISO
格式时,根据浏览器和给定的值不同,返回值可以是,也可以不是NaN
。 - 如果字符串被识别为
ISO
格式并且包含无效值,则在所有遵循ES5
或者更新标准的浏览器中都会返回NaN
。
解决问题
兼容性提示:为了避免任何可能的同步问题或者有歧义的年份,推荐使用 ISO 8601 格式如 "2017-04-16"。
ECMAScript 5 ISO-8601
日期格式支持
- 日期时间字符串也可以使用
ISO 8601
格式。 - 例如,
"2011-10-10" (仅日期)
或"2011-10-10T14:48:00" (日期和时间)
能够作为参数被传递和解析。 - 如果参数字符串只包含日期格式,那么将会使用
UTC
时区来解析该参数。 - 而如果是
ISO 8601
格式中规定的时间加日期的格式,则将会被作为本地时区处理。
//时间转换方法(改进后的)
function transformTime(t){
//注意:苹果手机不支持以“-”分割的时间形式,故必须进行格式转换。
var time = t.replace(/-/g,"/").substring(0,t.length-2);
return Date.parse(time);
}