在自己的项目中嵌入过广告的朋友们可能都用过百度联盟, 只需要嵌入如下一段js
代码片段, 就可以在自己的项目中嵌入广告, 来获得收益.
<script type="text javascript">
var cpro_id ="u2557752";
</script>
<script src="http://cpro.baidustatic.com/cpro/ui/cm.js?id='i9898'" type=“text/javascript”></script>
本文就是主要介绍如何通过嵌入js
片段的方式来嵌入广告等第三方的应用的, 具体的实现方案有两种:
在服务端生成脚本:
服务端接收到请求后, 从url
中提取到参数, 再根据参数从数据库中查找出对应的数据信息,比如是广告的话, 就查找到对应的广告素材, 并将查询到的数据信息插到javascript
模板中,
浏览器执行js
脚本代码,创建出广告
直接引入静态js脚本:
首先js
文件中提取到参数,根据参数向服务端发起请求, 获取到对应的数据, 再通过js
创建html
片段,输出到页面上
两种方案对比:
服务端生成脚本,所有的代码和数据都包含在生成的js
文件中,不需要做额外的请求,适用于内容及样式相对简单的页面.比如只有一个图片的广告展示.
对于内容较多,样式较为复杂的内容展示通过第二种方案实现更加灵活.
两种方案实现起来, 主要以下几步:
1.获取参数 --> 2.获取数据 --> 3.输出html
1.传递参数
下面介绍一下脚本参数传递的几种方式的优缺点:
1.通过拼接URL
传递
<script src="http://cpro.baidustatic.com/cpro/ui/cm.js?cpro_id=u2557752" type=“text/javascript”></script>
优点: 可通过URL
传递到服务器
缺点: 必须进行DOM
查询,无法缓存
2.通过hash
传
<script src="http://cpro.baidustatic.com/cpro/ui/cm.js#cpro_id=u2557752" type=“text/javascript”></script>
优点: 使用URL
,便于缓存
缺点: 必须进行DOM
查询
3.自定义属性
<script data-hxh-coupon-id=‘1234’ src=“http://cpro.baidustatic.com/cpro/ui/cm.js type=“text/javascript”></script>
优点: 可读性强, 便于缓存, 易于识别脚本引入代码的位置
缺点: 必须进行DOM
查询
4.使用全局变量
<script type=“text/javascript”>
var couponId = ‘87393’;
</script>
<script src=“http://cpro.baidustatic.com/cpro/ui/cm.js type=“text/javascript”></script>
优点: 可读性强,便于缓存,参数类型灵活,无需进行DOM
查询
缺点: 使用了全局变量
2.获取数据
关于获取数据, 服务端生成脚本, 服务端直接查询数据, 静态js
脚本方案中, 可使用jsonP
, Cors
等方案进行跨域请求.
3.输出html
1.使用document.write
document.write
直接在当前文档流中写入字符串,一旦文档流已经关闭,就打开新的文档流并写入,原来的文档流会被清空,已渲染好的页面就会被清除,浏览器将重新构建DOM
并渲染页面.所以使用这种方案, 就一必须是同步执行嵌入的这段js
代码, 作为第三方脚本引入,阻塞性的脚本会阻止主页面的渲染,如果js
文件加载迟缓,甚至不可用的, 会给主页面造成严重的性能问题, 所有不建议使用.
2.操作DOM
添加
-
在目标位置嵌入
js
片段, 并使用预先定义的ID,class,data-*
等(如上) -
js
文件中创建DOM
元素,将HTML
字符串赋值给元素的innerHTML
属性 -
根据
ID,calss,data-*
等查询到脚本所在位置,并将元素添加到DOM
中
<script id='hxh-coupon-scandown' type="text/javascript">
(function(){
var script = document.createElement('script');
script.async = true;
script.src = 'http://www.boxmars.com?id=123';
var entry = document.getElementsByTagName('script')[0];
entry.parentNode.insertBefore(script, entry);
})()
</script>
优点:
- 可以异步加载第三方
DOM
, 不阻塞主页面的渲染,即使js
出错,也不会影响到主页面 - 可以将创建的
DOM
动态插入到已存在的元素之后(即可以追加到已知位置)
缺点:
- 使用字符串拼接不利于
HTML
片段的编写和维护 - 会继承父页面样式
- 主页面可更改
DOM
内容
字符串拼接不利于编写和维护的问题,可以通过JavaScript
模板引擎库来编写HTML
片段, 流行模板库:HandlebarsJS,Mustache,BAIDU-Template,artTemplate
等
使用不设置src
的iframe
主页面提供一个不设置src
的iframe
标签,通过iframe
的contentWindow
访问iframe
的DOM
,使用document.write
将HTML
直接写入到iframe
中
var doc = document.getElementsByTagName('iframe')[0].contentWindow.document;
doc.writeln("<button id=\'btn\'>点击</button>");
doc.writeln("<script type=\'text/javascript\'>");
doc.writeln("var btn = document.getElementById(\'btn\');");
doc.writeln("btn.onclick = function(){");
doc.writeln("parent.parentEvent();");
doc.writeln("</script>");
doc.close();
注:
iframe
由浏览器异步处理, 所以此处使用document.write()
并不会阻止父页面的加载
优点:
-
完全独立的
DOM
环境,不会继承父页面的样式 -
完全独立的
window
,避免和主页面其他脚本冲突 -
可直接与主页面进行交互(与iframe引入外部页面对比)
缺点:
Iframe
标签的创建速度慢- 主页面可以访问
iframe
的DOM
环境并可进行更改
嵌入第三方页面两种方案中,另一种方案(http://www.cnblogs.com/yuqing6/p/8462239.html) 都大篇幅介绍使用了
iframe
进行html
输出,iframe
提供了一种最佳的避免样式和脚本冲突的嵌入途径,但是有些情况在主页面的DOM
中去渲染更为合适
不适合使用iframe
的情况:
- 需要在
iframe
外部呈现内容, 场景: 第三方应用中需要弹出对话框时,如果iframe
不是覆盖整个页面的, 就无法正常展示对话框 - 一个页面引入很多个
iframe
嵌入页面, 同一个页面引入许多个iframe
时, 会带来主页面很大的性能开销, 对于只是渲染一两次情况, 这种性能消耗可以忽略不计 - 需要继承父页面的基础样式, 有些时候,希望第三方应用继承父页面的基础样式, 来和主页面的样式风格保持一致,这种情况不适用于使用
iframe