html部分主要是修改不同浏览器的API的怪异行为。
(function(global) {
'use strict';
if (!('window' in global && 'document' in global))
return;
// do something
})(self)
一段自执行函数的模块封装,内加执行环境的判断确保后面代码的安全。
document.head
返回当前文档中的 <head>
元素。如果有多个 <head>
元素,则返回第一个。


if (!('head' in document))
document.head = document.getElementsByTagName('head')[0];
这样的写法很容易想到。
对H5元素的支持
[
'abbr', 'article', 'aside', 'audio', 'bdi', 'canvas', 'data', 'datalist',
'details', 'dialog', 'figcaption', 'figure', 'footer', 'header', 'hgroup',
'main', 'mark', 'meter', 'nav', 'output', 'picture', 'progress', 'section',
'summary', 'template', 'time', 'video'].forEach(function(tag) {
document.createElement(tag);
});
确保解释不出的新标签解析为行内标签。
HTMLElement.dataset
读写节点的自定义属性

值得注意的是:移动端都不支持!
if (!('dataset' in document.createElement('span')) &&
'Element' in global && Element.prototype && Object.defineProperty) {
Object.defineProperty(Element.prototype, 'dataset', { get: function() {
var result = Object.create(null);
for (var i = 0; i < this.attributes.length; ++i) {
var attr = this.attributes[i];
if (attr.specified && attr.name.substring(0, 5) === 'data-') {
(function(element, name) {
var prop = name.replace(/-([a-z])/g, function(m, p) {
return p.toUpperCase();
});
result[prop] = element.getAttribute('data-' + name); // Read-only, for IE8-
Object.defineProperty(result, prop, {
get: function() {
return element.getAttribute('data-' + name);
},
set: function(value) {
element.setAttribute('data-' + name, value);
}});
}(this, attr.name.substring(5)));
}
}
return result;
}});
}
实际上是利用get和set监听了每一个自定义属性的改变,对应到节点上。
atob()和btoa()
window.atob()
对用base-64编码过的字符串进行解码。window.btoa()
方法来编码一个可能在传输过程中出现问题的数据。

(function() {
if ('atob' in global && 'btoa' in global)
return;
var B64_ALPHABET = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
function atob(input) {
// do something
};
function btoa(input) {
// do something
};
global.atob = atob;
global.btoa = btoa;
}());
atob()
function atob(input) {
input = String(input);
var position = 0,
output = [],
buffer = 0, bits = 0, n;
input = input.replace(/\s/g, '');
if ((input.length % 4) === 0) { input = input.replace(/=+$/, ''); }
if ((input.length % 4) === 1) { throw Error("InvalidCharacterError"); }
if (/[^+/0-9A-Za-z]/.test(input)) { throw Error("InvalidCharacterError"); }
while (position < input.length) {
n = B64_ALPHABET.indexOf(input.charAt(position));
buffer = (buffer << 6) | n;
bits += 6;
if (bits === 24) {
output.push(String.fromCharCode((buffer >> 16) & 0xFF));
output.push(String.fromCharCode((buffer >> 8) & 0xFF));
output.push(String.fromCharCode(buffer & 0xFF));
bits = 0;
buffer = 0;
}
position += 1;
}
if (bits === 12) {
buffer = buffer >> 4;
output.push(String.fromCharCode(buffer & 0xFF));
} else if (bits === 18) {
buffer = buffer >> 2;
output.push(String.fromCharCode((buffer >> 8) & 0xFF));
output.push(String.fromCharCode(buffer & 0xFF));
}
return output.join('');
};
这就要说到BASE64解码过程了,解码时四个字符为一组(每个字符索引0-63,共24位二进制),每个字符按顺序转成BASE64数组对应索引的二进制形式,此时将二十四位二进制八位一组,对应ASCII码可译出三个字符。=为占位,可以忽略。
function btoa(input) {
input = String(input);
var position = 0,
out = [],
o1, o2, o3,
e1, e2, e3, e4;
if (/[^\x00-\xFF]/.test(input)) { throw Error("InvalidCharacterError"); }
while (position < input.length) {
o1 = input.charCodeAt(position++);
o2 = input.charCodeAt(position++);
o3 = input.charCodeAt(position++);
// 111111 112222 222233 333333
e1 = o1 >> 2;
e2 = ((o1 & 0x3) << 4) | (o2 >> 4);
e3 = ((o2 & 0xf) << 2) | (o3 >> 6);
e4 = o3 & 0x3f;
if (position === input.length + 2) {
e3 = 64;
e4 = 64;
}
else if (position === input.length + 1) {
e4 = 64;
}
out.push(B64_ALPHABET.charAt(e1),
B64_ALPHABET.charAt(e2),
B64_ALPHABET.charAt(e3),
B64_ALPHABET.charAt(e4));
}
return out.join('');
};
编码的过程,将字符串三个一组依次对应ASCII码转成二进制串(位数不足补0,缺整6的倍数补=
),六位二进制一组,对应BASE64数组索引的字母,拼接成编码字符串。
网友评论