Skip to content

Instantly share code, notes, and snippets.

@zmmbreeze
Last active August 29, 2015 13:57
Show Gist options
  • Save zmmbreeze/9526405 to your computer and use it in GitHub Desktop.
Save zmmbreeze/9526405 to your computer and use it in GitHub Desktop.
执行远程或内敛javascript,支持script中包含document.write。用于将js广告渲染到target, 基于tangram
/**
* 执行远程或内敛javascript,支持script中包含document.write
* 用于将js广告改为渲染到target, 基于tangram
*
* executeScript({
* 'target': baidu.g('ad'),
* 'url': 'http://ecma.bdimg.com/adtest/0116fb68cf061c3ec55516d4c79946ca.js'
* });
*
* executeScript({
* 'target': baidu.g('ad'),
* 'text': 'alert("alert");document.open();document.write('open');document.close();'
* });
*
* @param {Object} scriptOpt options.
* @param {Element|string} scriptOpt.target target节点.
* @param {string} scriptOpt.url javascript脚本的链接地址.
* @param {string} scriptOpt.text 内敛javascript脚本.
* @param {function} scriptOpt.callback 远程javascript脚本执行后的回调函数.
* @param {string=} scriptOpt.opt_type script dom和生成的html的插入位置
* 默认为inside,还有before和after
*/
executeScript = function (scriptOpt) {
var target = baidu.g(scriptOpt['target']);
var insertType = scriptOpt['opt_type'] || 'inside';
var scriptUrl = scriptOpt['url'];
var inlineScript = scriptOpt['text'];
var doc = target.ownerDocument;
var oldWrite = doc.write;
var writeMethodName = {
'inside': 'beforeEnd',
'before': 'beforeBegin',
'after': 'afterEnd'
};
// 重设document.write
doc.write = function (txt) {
// TODO
// 如果write的输入中包含document.write就无法执行了
baidu.dom.insertHTML(target, writeMethodName[insertType], txt);
};
var callback = function () {
// 恢复document.write;
doc.write = oldWrite;
if (scriptOpt['callback']) {
scriptOpt['callback']();
}
};
if (scriptUrl) {
// remote script
var script = document.createElement('script');
var readyStates = {
'complete': 1,
'loaded': 1,
'undefined': 1 // for non-ie
};
script.src = scriptUrl;
var insertScriptNode = {
'inside': function (script) {
target.appendChild(script);
},
'before': function (script) {
baidu.dom.insertBefore(script, target);
},
'after': function (script) {
baidu.dom.insertAfter(script, target);
}
};
script.onload = script.onerror = script.onreadystatechange =
function() {
if (readyStates[script.readyState]) {
callback();
script.onload = script.onerror = script.onreadystatechange = null;
try {
if (script.clearAttributes) {
script.clearAttributes();
}
else {
for (var p in script) {
delete script[p];
}
}
}
catch (x) {}
script = null;
}
};
insertScriptNode[insertType](script);
}
else if (inlineScript) {
// 获取target所在环境的window对象的eval
(doc.defaultView || doc.parentWindow).eval(inlineScript);
callback();
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment