html - 代码阅读,polyfill源码阅读(二)HTML

html部分主要是修改不同浏览器的API的怪异行为。

(function(global) {

'use strict';

if (!('window' in global && 'document' in global))

return;

// do something

})(self)

一段自执行函数的模块封装,内加执行环境的判断确保后面代码的安全。

document.head

返回当前文档中的

元素。如果有多个 元素,则返回第一个。

084ac1269e78

PC兼容性.png

084ac1269e78

移动端兼容性

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

读写节点的自定义属性

084ac1269e78

PC兼容性.png

值得注意的是:移动端都不支持!

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() 方法来编码一个可能在传输过程中出现问题的数据。

084ac1269e78

兼容性.png

(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数组索引的字母,拼接成编码字符串。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值