畅言
畅言
最近见到别的网站用了畅言服务了,对其js代码比较感兴趣,特记录下来。其实,主要就是看一下,原生的js如果创建dom,加载dom而已,其他的,好像也没有什么特别高深的。
加载畅言
(function(){
var appid = 'XXXXXX',
conf = 'prod_XXXXXXXX';
var doc = document,
s = doc.createElement('script'),
h = doc.getElementsByTagName('head')[0] || doc.head || doc.documentElement;
s.type = 'text/javascript';
s.charset = 'utf-8';
s.src = 'http://assets.changyan.sohu.com/upload/changyan.js?conf='+ conf +'&appid=' + appid;
h.insertBefore(s,h.firstChild);
window.SCS_NO_IFRAME = true;
})()
上面的代码,没有什么好说的,主要是,使用原生的js创建dom,并加载。另外,使用了闭包防止局部变量泄漏。
上面的代码,使用就是为了加载chqangyan.js脚本而已。具体的代码如下:
(function () {
var createNs = function () {
if (window.changyan !== undefined) {
return;
} else {
window.changyan = {};
window.changyan.api = {};
window.changyan.api.config = function (conf) {
window.changyan.api.tmpIsvPageConfig = conf;
};
window.changyan.api.ready = function (fn) {
window.changyan.api.tmpHandles = window.changyan.api.tmpHandles || [];
window.changyan.api.tmpHandles.push(fn);
};
}
};
var loadVersionJs = function () {
var loadJs = function (src, fun) {
var head = document.getElementsByTagName('head')[0] || document.head || document.documentElement;
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('charset', 'UTF-8');
script.setAttribute('src', src);
if (typeof fun === 'function') {
if (window.attachEvent) {
script.onreadystatechange = function () {
var r = script.readyState;
if (r === 'loaded' || r === 'complete') {
script.onreadystatechange = null;
fun();
}
};
} else {
script.onload = fun;
}
}
head.appendChild(script);
};
var ver = +new Date() + window.Math.random().toFixed(16);
var protocol = (('https:' == window.document.location.protocol) ? "https://" : "http://");
var url = protocol + 'changyan.sohu.com/upload/version-v3.js?' + ver;
loadJs(url);
};
createNs();
loadVersionJs();
}());
这段代码,执行了两个函数createNs、loadVersionJs。
分析
createNs代码变量changyan完全没有必要反复加上window,完全能在最后,再执行一句
window.changyan = changyan;即可完成局部变量的绑定。
分析
loadVersionJs代码:就是创建script,并绑定script加载完成后的回调函数。其主要目的是,加载
version-v3.js。就为了加载,写出了这样的代码,感觉一点也不划算。另外,
window.attachEvent这个函数好像浏览器已经废弃了,但是,有另外一个函数类似的函数window.addEventListener。
那么,接下来,看version-v3.js到底是什么东东。
(function () {
var loadJs = function (src, fun) {
var head = document.getElementsByTagName('head')[0] || document.head || document.documentElement;
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('charset', 'UTF-8');
script.setAttribute('src', src);
if (typeof fun === 'function') {
if (window.attachEvent) {
script.onreadystatechange = function () {
var r = script.readyState;
if (r === 'loaded' || r === 'complete') {
script.onreadystatechange = null;
fun();
}
};
} else {
script.onload = fun;
}
}
head.appendChild(script);
};
var fnGetVersion = function () {
var version = 'v202011181282';
if (version.indexOf('##CY') >= 0) {
version = 'v3-debug-v3';
}
return version;
};
var fnGetCookie = function (fn) {
var cb = 'changyan' + Math.floor(Math.random() * 1000 * 1000 * 1000);
var protocol = (('https:' == window.document.location.protocol) ? "https://" : "http://");
var api = protocol + 'changyan.sohu.com/debug/cookie?callback=' + cb;
window[cb] = function (data) {
var cookie = data && data.cookie || '';
cookie = cookie.split(';');
var i, v;
var map = {};
for (i = 0; i < cookie.length; i++) {
v = cookie[i];
v = v.split('=');
v[0] = v[0] || '';
v[1] = v[1] || '';
v[0] = v[0].replace(/^\s/, '').replace(/\s$/,'');
v[1] = v[1].replace(/^\s/, '').replace(/\s$/,'');
if (v[0] !== '') {
map[v[0]] = v[1];
}
}
if (typeof fn === 'function') {
fn(map);
}
};
loadJs(api, function () {
try {
delete window.cb;
} catch (e) {
window[cb] = undefined;
}
});
};
var fnInit = function () {
var config = {};
config.version = fnGetVersion();
config.protocol = (('https:' == window.document.location.protocol) ? "https://" : "http://");
config.res = config.protocol + 'changyan.sohu.com/v3/' + config.version + '/src/';
config.base = config.protocol + 'changyan.sohu.com/';
config.api = config.protocol + 'changyan.sohu.com/';
if (config.protocol === 'https://') {
config.res = config.protocol + 'changyan.sohu.com/v3/' + config.version + '/src/';
config.base = config.protocol + 'changyan.sohu.com/';
}
fnGetCookie(function (cookie) {
if (cookie.debug_v3 === 'true') {
loadJs(config.res + 'lib/sea.v1.2.0.js', function () {
seajs.use(config.res + '/adapter.js', function (fn) {
fn && fn(config, cookie);
});
});
} else {
loadJs(config.res + 'adapter.min.js', function () {
var adapter = window.changyan.api.getAdapterModules('adapter.js');
adapter(config, cookie);
});
}
});
};
fnInit();
}());
上面代码,我实在不想看了,测试啊尤其是加载的script代码,反复出现。