Skip to content

Instantly share code, notes, and snippets.

@hh54188
Created February 13, 2014 16:06
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hh54188/8977919 to your computer and use it in GitHub Desktop.
Save hh54188/8977919 to your computer and use it in GitHub Desktop.
// http://a.tbcdn.cn/p/mall/2.0/js/direct-promo.js
/**
* 钻石平台定投广告
*
* @creator yubo@taobao.com
* @depends ks-core
*/
KISSY.use('core', function(S){
/**
* 项目名称:营销运营平台定向投放系统
*
* 增加init 参数支持异步加载定投dom,弃用detect方法新增render方法 by tiejun 2011-05-10
* 增加request接口并重构部分代码,用于提前发起请求。 by yunqian 2010-1-11
* 修改接口,符合规范,并用于 2010 首页。 by yubo 2009-12-30
* 增加用户疲劳度控制脚本 by qingyu 2009-08-18
* 重构为通用脚本 by yubo 2009-07-02
* 脱离YUI依赖 modified by yuchun 2009-05-26
* created by chenyu@taobao.com at 2009-06-08
* 脚本说明:
1、在要投放广告的页面中引入本js,投放多个广告仅需引入一次脚本,脚本引入的位置可放于最后一个广告容器之后的任意位置,除首页,其他页面均放于页脚
2、给要投放广告的容器设置为class="J_DirectPromo",并设置自定义属性 data-resid="本广告位的标识码",这些广告的定位等样式可通过css自行设置
示例:<div class="J_DirectPromoFloatBox" data-resid="16"></div>
3、返回的广告代码应为如下形式:
__content_results = [
{ id: 16, content: 'http://pics.taobaocdn.com/path/to/pic.png', 'link':'http://www.taobao1.com' },
{ id: 18, content: 'html code'}
]
其中:
a. 当link存在时,则该条广告为图片广告,content为图片地址,link为图片链接
b. 当link不存在时,则对应的广告容器的innerHTML为content
c. 如果是浮出广告,当content内容是链接时,这时会用iframe引入该链接,大小固定为 330 x 200
4、页面中可以设置浮出广告的形式,一个页面中只能设置一个浮出广告,其html代码为
<div class="J_DirectPromo" id="J_DirectPromoFloatBox" data-resid="本广告位的标识码"></div>
推荐将浮动广告的html代码加至body最末尾,无须设置样式,样式由js写入
**/
var S = KISSY, DOM = S.DOM,
URL_PREFIX = 'http://delta.taobao.com/home/delivery/AllContentByPage.do?resourceIds=',
HOOK_CLASS = 'J_DirectPromo', // 占位容器的ClassName
HOOK_ID_PREFIX = 'J_DirectPromo_', // 占位容器的ID前缀
HOOK_FLOAT_ID = 'J_DirectPromoFloatBox', // 浮出广告容器的ID
HOOK_VAR = '__content_results', // 返回的广告内容的全局变量
RE_URL = /^https?:\/\/\S+$/i,
RE_PIC = /^https?:\/\/\S+(png|jpg|gif)$/i,
win = window,
detecting = false, // 定投广告占位容器是否正在探测
adContainers = {}, // 定投广告在页面上的hook容器
waitingQueue = []; // 定投广告数据渲染等待队列,暂无容器的广告数据得以保存,可以再次渲染
/**
* 合并两个数组,重复只保留一个(仅支持简单数组)
*/
function ArrayCombo(a1,a2){
var len= a1.length,a;
while(len--){
a = a1[len];
if(!S.inArray(a,a2)){
a2.push(a);
}
}
return a2;
}
DirectPromo = {
/**
* 初始化方法
* @param staticIds {Array} 广告资源ID数组,默认会根据dom筛选有时异步加载,需要预先设置
*/
init: function(staticIds) {
var hooks = S.query('.' + HOOK_CLASS),
adIds = [], resId;
if (!hooks || hooks.length === 0) return;
S.each(hooks, function(hook) {
resId = hook.getAttribute('data-resid');
if (resId) { // bug fix: 增加容错性 by yubo 2009-07-23
adIds.push(resId);
adContainers[resId] = hook;
}
});
//for (; i < len; i++) {
// resId = hooks[i].getAttribute('data-resid');
// if (resId) { // bug fix: 增加容错性 by yubo 2009-07-23
// adIds.push(resId);
// adContainers[resId] = hooks[i];
// }
//}
// 预先的一些id 和检测到的合并
staticIds && (adIds = ArrayCombo(staticIds,adIds));
this.request(adIds);
},
/**
* 请求URL,并为adIds的前几张图片优先发起请求
* @param adIds {Array} 广告资源ID数组
* @param priorRequestNum {Number} 优先发起请求的数量 (optional)
* @param floatID {Number} 浮动广告资源ID (optional)
*/
request: function(adIds, priorRequestNum, floatID) {
var that = this,
url = URL_PREFIX + adIds.join(',') + '&t=' + +new Date;
S.getScript(url, function() {
var datas = win[HOOK_VAR], content, i = 0;
if (!datas || datas.length === 0) return;
// 优先加载部分图片
if (priorRequestNum && priorRequestNum > 0) {
for (; i < priorRequestNum; i++) {
content = datas[i].content;
if (content && RE_PIC.test(content)) {
new Image().src = content;
}
}
}
// 将已请求数据加入等待队列
waitingQueue = waitingQueue.concat(datas);
that.render(floatID);
});
},
/**
* 渲染数据至已存在元素
* @param floatID
*/
render: function(floatID){
var i = waitingQueue.length,
data,container,id;
while (i--) {
data = waitingQueue[i];
id = data.id;
if (!adContainers[id]) {
container = S.get('#' + (id === floatID ? HOOK_FLOAT_ID : HOOK_ID_PREFIX + id));
if (container) {
adContainers[id] = container;
} else {
continue;
}
}
// 删除已处理元素
waitingQueue.splice(i, 1);
// 开始填充
this._fill(data);
}
},
/**
* 定时探测占位容器是否ready
*/
detect: function(floatID) {
var DELAY = 100, // 延时时长
MAX_COUNT = 50, // 执行次数
count = 0, // 计时器
that = this;
// 如果已有探测器进行探测,则直接退出
if (detecting) return;
// 开始探测
detecting = true;
(function() {
var id, container;
S.each(waitingQueue, function(data, i) {
id = data.id;
if (!adContainers[id]) {
container = S.get('#' + (id === floatID ? HOOK_FLOAT_ID : HOOK_ID_PREFIX + id));
if (container) {
adContainers[id] = container;
}
}
if (adContainers[id]) {
that._fill(waitingQueue.splice(i, 1)[0]); // bug fix
return false; // 每次for循环仅执行一次填充,因为splice操作的是datas本身
}
});
// 理论上网速越慢,效果越好,图片请求越靠前
if (waitingQueue.length > 0 && ++count < MAX_COUNT) {
setTimeout(arguments.callee, DELAY);
} else {
// 结束探测
detecting = false;
}
})();
},
/**
* 填充广告内容
* @param data {Object}
*/
_fill: function(data) {
var container = adContainers[data.id],
content = data.content,
link = data.link,
wrap;
// 双十一用户地区定投判断
if(data.id == 315 && content){
try{
Tmall.SetUserAreaInfo(content);
}catch(err){}
return ;
}
if (!container || !content) return;
// 广告内容
if (RE_PIC.test(content)) { // 图片链接
wrap = '<img src="' + content + '" />';
}
else if(content == 'http://tms.tms.tms'){ //如果广告系统传来的内容值是 'http://tms.tms.tms',则此广告容器里的内容
return;
}
else if (RE_URL.test(content)) { // 普通链接
wrap = '<ifr'+'ame src="' + content + '" scrolling="no" frameborder="0" width="330" height="200"></iframe>';
link = ''; // iframe外不需要link,强制清空
} else if(data.id == 395) { //商超导航定投
if(content && content =='chaoshi'){
DOM.show(container);
}else{
DOM.remove(container);
}
return;
} else {
wrap = content;
}
// 填充广告
container.innerHTML = link ? '<a target="_blank" href="' + link + '">' + wrap + '</a>' : wrap;
}
};
// 初始时添加异步的ids,保证一次请求
DirectPromo.init();
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment