虾米音乐(xiami.com)模拟登录

需要准备的东西不多:

  1. 先get以下url
    https://login.xiami.com/member/login
  2. 获取到cookie数组(有3个)和csrf_token
    csrf_token元素:input[name=_xiamitoken]
  3. 生成随机60位字符串(以A开头),存到cookie数组中,cookie名为isg
  4. 再post以下url,带上参数,cookie和header:
    https://login.xiami.com/passport/login
    $login_params = array(
       'account' => 'xxx',
       'pw' => 'xxx',
       'done' => 'http%3A%2F%2Fwww.xiami.com',
       'verifycode' => '',
       'submit' => '登 录',
       '_xiamitoken' => $csrf_token
    );
    $o_curl->http_header('X-Requested-With', 'XMLHttpRequest');
    $o_curl->http_header('Referer', 'https://login.xiami.com/member/login?spm=a1z1s.6843761.226669510.9.8Fr05O');
  5. 拿到返回的cookie:login_method、member_auth、user,然后就可以任意请求所有虾米的api接口

indexDB

indexedDB

通过使用IDB,可以更好的构建离线web应用,并且通过将数据存储在浏览器而非服务器一侧,降低了服务器和浏览器的交互次数,提高了性能。
这个规范提供了一个具体的API来执行高级的键值数据管理。它通过使用事务数据库来存储键及其对应的值(每个键可以对应一个或多个值),并且提供以确定性顺序遍历键的方式来实现。这通常通过使用被认为对于插入和删除以及按序遍历非常大量的数据记录有效的持久性B树数据结构来实现。

IndexedDB 分别为同步和异步访问提供了单独的 API 。同步 API 本来是要用于仅供 Web Workers 内部使用,但是还没有被任何浏览器所实现。异步 API 在 Web Workers 内部和外部都可以使用。

1.兼容问题:

window.indexedDB = window.indexedDB || window.mozIndexedDB || window.webkitIndexedDB || window.msIndexedDB;
window.IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction || window.msIDBTransaction;
window.IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange || window.msIDBKeyRange
// (Mozilla has never prefixed these objects, so we don't need window.mozIDB*)

2.数据库链接:
在使用IDB之前需要创建一个数据库。由于数据库是异步工作模式,调用open()方法将会返回一个IDBRequest对象,通过这个对象可以绑定成功或错误的事件处理程序。

版本号是一个 unsigned long long 数字,这意味着它可以是一个非常大的整数(不能使用浮点数)。

IndexedDB 在浏览器的隐私模式(Firefox 的 Private Browsing 模式)下是被完全禁止的。 隐私浏览的全部要点在于不留下任何足迹,所以在这种模式下打开数据库的尝试就失败了。

要更新数据库的 schema,也就是创建或者删除对象存储空间,需要实现 onupgradeneeded 处理程序。onupgradeneeded 是我们唯一可以修改数据库结构的地方。在这里面,我们可以创建和删除对象存储空间以及构建和删除索引。

3)创建对象存储空间
一个IDB数据库可以包含对个对象存储空间,一个对象存储空间类似于关系型数据库(如MySQL中)中的表。可以使用IDBRequest对象的createObjectStore()方法创建对象空间,该方法包含两个参数,第一个参数是对象空间的名字,另一个是选项对象,包含keyPath属性和keyGenerator值,keyPath属性是存储空间的键值。如果对象中没有具有确切名字的属性可以keyPath,可以使用autoIncrement作为keyGeneraotr。
对象存储空间可以具有进行数据检索的索引,索引可以通过对象存储空间的createIndex()创建,具有三个参数:索引名、放置索引的属性名、以及选项对象。

 

Key Path Key Generator Description
No No 这种对象存储空间可以持有任意类型的值,甚至是像数字和字符串这种基本数据类型的值。每当我们想要增加一个新值的时候,必须提供一个单独的键参数。
Yes No 这种对象存储空间只能持有 JavaScript 对象。这些对象必须具有一个和 key path 同名的属性。
No Yes 这种对象存储空间可以持有任意类型的值。键会为我们自动生成,或者如果你想要使用一个特定键的话你可以提供一个单独的键参数。
Yes Yes 这种对象存储空间只能持有 JavaScript 对象。通常一个键被生成的同时,生成的键的值被存储在对象中的一个和 key path 同名的属性中。然而,如果这样的一个属性已经存在的话,这个属性的值被用作键而不会生成一个新的键。

4) 检索数据—创建事务
var IDBTransaction = window.IDBTransaction || window.webkitIDBTransaction;

在你可以对新数据库做任何事情之前,你需要开始一个事务。事务来自于数据库对象,而且你必须指定你想让这个事务跨越哪些对象存储空间。另外,你需要决定你是否将要对数据库进行更改或者你只是需要从它里面进行读取。虽然事务具有三种模式(只读,读写,和版本变更),无必要的情况最好还是使用只读事务,因为它们可以并发运行。

取得了事务的索引之后,通过objectStore()方法并传入存储空间的名称,就可以访问特定的存储空间,然后就可以通过get()/add()/put()/delete()/clear()方法进行数据的检索、增加、删除。事务处理是异步响应,因此返回请求对象,对这个请求对象可以绑定onerror、onsuccess和oncomplete事件处理程序。

 

add() 函数要求数据库中不能已经有相同键的对象存在。如果你正在试图修改一个现有条目,或者你并不关心是否有一个同样的条目已经存在,使用 put()函数。

5) 检索数据—游标
通过事务的get()方法可以检索数据,但是这需要你事先知道数据的keyPath。除此之外还可以通过游标检索数据,在事务指定的对象存储空间上使用openCursor()方法创建游标,该方法也是返回一个请求对象,可以绑定onerror或onsuccess。在onsuccess事件处理程序中通过event.target.result取得存储空间的下一个对象, 在结果集中有下一项时,这个属性中保存一个 IDBCursor 的实例,在没有下一项时,这个属性的值为 null。

你可以在索引上打开两个不同类型的游标。一个常规游标映射索引属性到对象存储空间中的对象。一个键索引映射索引属性到用来存储对象存储空间中的对象的键。

var request = indexedDB.open("library");

request.onupgradeneeded = function() {
  // The database did not previously exist, so create object stores and indexes.
  var db = request.result;
  var store = db.createObjectStore("books", {keyPath: "isbn"});
  var titleIndex = store.createIndex("by_title", "title", {unique: true});
  var authorIndex = store.createIndex("by_author", "author");

  // Populate with initial data.
  store.put({title: "Quarry Memories", author: "Fred", isbn: 123456});
  store.put({title: "Water Buffaloes", author: "Fred", isbn: 234567});
  store.put({title: "Bedrock Nights", author: "Barney", isbn: 345678});
};

request.onsuccess = function() {
  db = request.result;
};
var tx = db.transaction("books", "readwrite"), customers = [];
var store = tx.objectStore("books");store.openCursor().onsuccess = function(event) {
 var cursor = event.target.result;
 if (cursor) {
 customers.push(cursor.value);
 cursor.continue();
 }
 else {
 alert("Got all customers: " + customers);
 }
};

Web Cryptography API

window.crypto


var result = crypto.subtle.encrypt(algorithm, key, data);
var result = crypto.decrypt(algorithm, key, data);

algorithm: {name: “AES-CBC”, iv} 密码分组链接模式(Cipher Block Chaining (CBC))
iv 16-byte BufferSource(ArrayBuffer,TypedArray)
{name: “AES-CTR”, counter, length} 计算器模式(Counter (CTR))
{name: “AES-GCM”, iv[, additionalData, tagLength]} Galois/Counter Mode
{name: “RSA-OAEP”[, label]}
http://www.tuicool.com/articles/AZZjiu
key: 包含要用于签名的密钥的CryptoKey
data: ArrayBuffer or ArrayBufferView(new TextEncoder(“UTF-8”).encode(data))

return:Promise

iv cryptoObj.getRandomValues(typedArray);typedArray: Int8Array, Uint8Array, Int16Array, Uint16Array, Int32Array, Uint32Array.
或自己生成的typedArray

CryptoKey: SubtleCrypto.generateKey(), SubtleCrypto.deriveKey() or SubtleCrypto.importKey()

var key = crypto.subtel.importKey(format, keyData, algo, extractable, usages)
var key = crypto.subtel.generateKey(algo, extractable, usages)
var key = crypto.subtel.deriveKey(algo, masterKey, derivedKeyAlgo, extractablbasee, keyUsages)

format: “raw”, the key as an array of bytes, usually a secret key.
“pkcs8” a private key,Public Key-Cryptographic Standard Encryption #8.
“spki”, usually a public key, in the Simple public key infrastructure
“jwk”, JSON Web Key
keyData: ArrayBuffer 或 JSONWebKey (crypto.subtle.exportKey(format, key))

algo: 同上

extarctable: 是否可以在稍后阶段从CryptoKey对象中提取密钥

usages: 数组,指示可以用键做什么 [“encrypt”, “decrypt”, “sign”, “verify”, “deriveKey”, “deriveBits”, “wrapKey”, “unwrapKey”]
eg:

var iv = window.crypto.getRandomValues(new Uint8Array(16));
var cryptokey;
crypto.subtle.generateKey({
name: "AES-CBC",
length: 256
},
true,
["encrypt", "decrypt"]
).then(function(key){
cryptokey = key
});
crypto.subtle.encrypt({
name: "AES-CBC",
iv: iv
}, cryptokey, new TextEncoder("UTF-8").encode('11')
).then(function(ret) {
var bytes = new Uint8Array(ret);
var hexBytes = [];
for (var i = 0; i < bytes.length; ++i) {
var byteString = bytes[i].toString(16);
if (byteString.length < 2)
byteString = "0" + byteString;
hexBytes.push(byteString);
}
console.log("encrypted", hexBytes.join("")); //fbf9553220dbcd105bca036a673b8f3d
});
var hexString = 'fbf9553220dbcd105bca036a673b8f3d';
var arrayBuffer = new Uint8Array(hexString.length / 2);
for (var i = 0; i < hexString.length; i += 2) {
var byteValue = parseInt(hexString.substr(i, 2), 16);
if (byteValue == NaN)
throw "Invalid hexString";
arrayBuffer[i/2] = byteValue;
}
crypto.subtle.decrypt({
name: "AES-CBC",
iv: iv
}, cryptokey, arrayBuffer).then(function (ret) {
console.log(new TextDecoder("UTF-8").decode(new Uint8Array(ret)))
});

DOM Level 2 Events-部分

Event

1. addEventListener -> removeEventListener
dispatchEvent

它的第一个参数“事件类型”,大小写敏感
dispatchEvent方法在当前节点上触发指定事件,从而触发监听函数的执行。该方法返回一个布尔值
只要有一个监听函数调用了event.preventDefault(),则返回值为false,否则为true。

dom.addEventListener('click', callback, false);

如果将监听函数部署在Element节点的on-属性上面,this不会指向触发事件的元素节点。

2. 事件的传播
捕获阶段 -> 目标阶段 -> 冒泡阶段(event.eventPhase (capture, target, bubble))

3. Event对象

event = new Event(typeArg, eventInit);

eventInit -> bubbles:布尔值,可选,默认为false,表示事件对象是否冒泡。
cancelable:布尔值,可选,默认为false,表示事件是否可以被取消。

旧版本使用(不建议使用)

var event = document.createEvent('Event');
event.initEvent(type, bubbles, cancelable);
dom.dispatchEvent(event);

event.eventPhase 返回一个整数值,表示事件目前所处的节点(1, 2, 3)
event.currentTarget 事件当前所在的节点,即正在执行的监听函数所绑定的那个节点
event.target(ie 6-8 srcElement)
event.detail 表示事件的某种信息。具体含义与事件类型有关(比如双击,值为2)
event.isTrusted 属性返回一个布尔值,表示该事件是否为真实用户触发。

自定义事件传值 CustomEvent(type, {param, bubbles, cancelable});

  • HTMLEvetns : ‘abort’,’blur’,’change’,’error’,’focus’,
    ‘load’,’reset’,’resize’,’scroll’,’select’,
  • UIEvents : ‘DOMActivate’,’DOMFocusIn’,’DOMFocusOut’,’keydown’,’keypress’,’keyup’
  • MouseEvents : ‘click’,’mousedown’,’mousemove’,’mouseout’,’mouseover’,’mouseup’
  • MutationEvents :
    • DOMAttrModified
    • DOMNodeInserted insert之后触发, target为插入元素
    • DOMNodeRemoved removed 之前触发, target为移除元素
    • DOMCharacterDataModified 对元素的文本内容的更改
    • DOMNodeInsertedIntoDocument 同DOMNodeRemovedFromDocument原理,此事件在DOMNodeInserted之后触发
    • DOMNodeRemovedFromDocument 和DOMNodeRemoved不同是DOMNodeRemoved可以移除非当前dom树上的元素,此事件在
    • DOMNodeRemoved之后触发
    • DOMSubtreeModified 它可能在对文档进行一次修改后触发,或者在执行多个更改之后自行决定
      这个事件的target是发生变化的最低的共同父元素,并且上面的mutation事件触发后才会触发这个事件
    • dom3不建议使用,dom4中使用Mutation observers来代替它 https://www.w3.org/TR/dom/#mutation-observer


var mutationObserver = new MutationObserver(callback);
mutationObserver.observe(someElement, options);

options:{childList: true, attribute: true, characterData: true, subtree: true }

MouseEvent中
event.relatedTarget 属性返回事件的次要相关节点。对于那些没有次要相关节点的事件,该属性返回null

进度事件 abort, error, load, loadstart, loadend, progress, timout (img)
拖拽事件 drag, dragstart, dragend, dragenter, dragover, dragleave, drop
属性:dataTransfer(dropEffect, effectAllowed, files, types
setData(“text/plain”, “Text to drag”)
getData(“text/plain”)
clearData(“text/plain”)
setDragImage(img/canvas, 鼠标相对图片左上角横坐标, 鼠标相对图片左上角纵坐标)

第二期

1. PointerLock API 以及 FullScreen API

讲述Js全屏API以及指针锁定API的浏览器兼容以及调用方法,链接:

PointerLock API 以及 FullScreen API

2.DOM Level 2 Events

讲述dom事件触发,捕获与冒泡,及多种dom事件类型,链接:

DOM Level 2 Events-部分不常用(后续完善Level3、4)

3.ES6新语法之解构赋值

讲述ES6解构赋值语法以及主要用途,链接:

ES6新语法之解构赋值

4.Javascript中delete关键字使用详解

讲述delete关键字删除对象的属性的细致研究,链接:

http://jishu.website/javascript%E4%B8%ADdelete%E5%85%B3%E9%94%AE%E5%AD%97%E4%BD%BF%E7%94%A8%E8%AF%A6%E8%A7%A3/

5.移动端webapp 最佳实践

讲述移动端web开发的注意事项及优化方法。以及http请求头user-Agent和Accept的字段涵义,链接:

移动端webapp 最佳实践

 

移动端webapp 最佳实践

 

Mobile Web Application Best Practices

  1. 谨慎使用Cookie(每次请求都会向服务器端发送cookie,数量过多会影响性能)
  2. 对本地数据使用适当的客户端存储技术(当应用启动的时候,数据可以立即展示;在网络不稳定时,可以请求数据先存在本地,网络连接可用时再继续发起请求)
  3. 不执行未转义或不受信任的JSON数据
  4. 确保已通知用户使用个人信息和设备信息
  5. 启用自动登录
  6. 使用传输压缩
  7. 最小化应用程序和数据大小
  8. 避免重定向
  9. 优化网络请求
  10. 最小化外部资源
  11. 将静态图像聚合成单个复合资源(Sprites)
  12. 在CSS样式表中内嵌背景图片(使用base64来减少请求)
  13. 通过指纹资源引用来缓存资源(通过将Expires标头设置为远期的日期,将资源缓存策略设置为“永不过期”。
    使用包含内容的哈希的URI来引用资源。 如果内容更改,此引用将更改,浏览器将提取更新的数据。)
  14. 缓存AJAX数据
  15. 不要发送Cookie信息(静态资源不需要Cookie信息,因此可以通过从应用程序的Cookie超出范围的路径或子域提供服务来提高性能。)
  16. 保持DOM大小合理
  17. 优化应用程序启动时间(较大的js拆分开)
  18. 最小化感知延迟(分步渲染,loading动画)
  19. 多重交互方法的设计
  20. 保持对动态页面更新的关注(谨慎使用自动focus)
  21. 使用片段ID来驱动应用程序视图(使用锚点来定位页面视图)
  22. 使电话号码“点击通话”(电话,邮件,短信)
  23. 确保段落文本流(水平方向滚动条会引起页面重绘)
  24. 确保不同设备的一致性
  25. 考虑启动Web应用程序的移动专用技术(短信,二维码,替代供应商的特定措施)
  26. 使用viewport来标识所需的屏幕大小
  27. 首选服务器端检测(如果可能)( 在可能的情况下,使用服务器上提供的证据来确定传递上下文的属性,并在传输之前调整客户端的响应,从而改善用户体验,避免传输不必要或不兼容的数据。
  28. 在必要时使用客户端检测(不太明白呢。。。
    3.6.2.1 What it means

    Where it is not possible to determine certain properties of the Delivery Context from the server, this information may be available at the client. Once obtained at the client, the information can be used directly to adapt the presentation, or it can used to request alternative, adapted content from the server.

    3.6.2.2 How to do it

    There are a few client-side solutions available to the developer:

    JavaScript: this is the most common solution. A script determines the device / browser properties and manipulates the content and behaviour of the application accordingly. This can be done in two ways:

    1. By encapsulating the differing behaviors in the control logic of the application (e.g. if (some_api_exists) { ...). Typically the Delivery Context information is gathered at the start of the session, though dynamic information (e.g. current screen orientation) should be refreshed during the session.
    2. By passing the gathered information back to the server and requesting alternative content (e.g. either by dynamically adding a new <script> element to the DOM or by an XHR request).

    CSS Media Types: CSS Media Types allow different stylesheets to be associated with different media types (e.g. print, screen, mobile) and are traditionally used to repurpose content for these destinations. Since the list of recognized media types is limited, however, and devices are notoriously idiosyncratic in their interpretation of types, it is in general not a helpful technology in this context. See Media Types [CSSMT] for more details.

    CSS Media Queries: Media queries are an extension to the “media-types” paradigm that allow developers to apply specific style rules based on the device display characteristics (e.g. screen width, orientation, or resolution). At the time of writing this specification is not fully supported, but can provide a useful way to modify the page layout (for example to re-flow sections of text) in a more maintainable, declarative way than is possible with script. See Media Queries [CSSMQ] for more details.

  29. 使用设备分类简化内容适配
  30. 如果适当,支持页面在无JS的情况仍然可以使用
  31. 为用户提供多种接口选择(非JavaScript版本可用于在低带宽情况下的简单操作。)
  32. 对于动态图形,考虑canvas元素或SVG使用
  33. 告知使用者自动网络访问
  34. 提供足够的手段来控制自动网络访问(所有自动访问网络的应用程序都应提供一种方法让用户禁用该活动。 禁用自动网络活动时,定期提示用户发出网络请求。

 

HTTP 请求头:

1.http请求: user-Agent 客户端信息;浏览器作为发起一个请求的实体,即浏览器相关信息。

User-Agent:<product>/<version> (<system-information>) <platform> (<platform-details>) <extensions>

User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/601.7.7 (KHTML, like Gecko) Version/9.1.2 Safari/601.7.7

2.Accept  :描述消息内容类型的因特网标准

Accept: <MIME_type>/<MIME_subtype> ;

Accept   application/json, text/javascript, */*; q=0.01    q是一个0-1之间的数值, q的默认值是1;制定权重值

3.http-equiv :

  • expires
  • refresh
  • set-cookie
  • content-type

当服务器向浏览器发送文档时,会先发送许多名称/值对。虽然有些服务器会发送许多这种名称/值对,但是所有服务器都至少要发送一个:content-type:text/html。这将告诉浏览器准备接受一个 HTML 文档。

<meta http-equiv=”charset” content=”iso-8859-1″>

<meta http-equiv=”expires” content=”31 Dec 2008″>

这样发送到浏览器的头部就应该包含:

content-type: text/html

charset:iso-8859-1

expires:31 Dec 2008

 

<meta http-equiv=”cache-control” content=”no-cache”>

<meta http-equiv=”pragma” content=”no-cache”>

PointerLock API 以及 FullScreen API

1、判断浏览器是否支持全屏
document.fullscreenEnabled = ( function() {

        var doc = document.documentElement;
return ( 'requestFullscreen' in doc ) ||
( 'webkitRequestFullScreen' in doc ) ||
// 对Firefox除了能力判断,还加上了属性判断
( 'mozRequestFullScreen' in doc && document.mozFullScreenEnabled ) ||
false;

    } )();
2、全屏支持情况:
  • 目前 FireFox 10+、Safari 5.1+、Chrome 15+ 支持全屏
  • 可以使任意元素全屏显示,不只是整个页面
  • 全屏只能从事件触发(用户操作),而不能用代码直接触发

将 element 全屏显示。webkit内核浏览器和Firefox表现不同,前者只要求element是DOM元素即可,后者则要求DOM必须是文档流中的元素,比较严格,否则不能全屏显示。

出于安全考虑,全屏状态下默认是不允许用户输入的:

webkit 内核浏览器会阻止除方向键、控制键之外的键盘输入。

FireFox 会在输入时发出要求用户退出全屏状态的提示。

但 Safari 一旦传入该参数,整个 Fullscreen 功能都会坏掉(这应该是 Safari 的一个bug)。

3、PointerLock  API 用处

对于需要大量的鼠标输入来控制运动,旋转物体,以及更改项目的应用程序来说非常有用。对高度视觉化的应用程序尤其重要,例如那些使用第一人称视角的应用程序,以及 3D 视图和建模。

举例来说,你可以创建让你的用户简单地通过移动鼠标而不需要点击任何按钮就可以控制视角的应用。那么这些按钮就可以被用作其他动作。这类鼠标输入对于查看地图,卫星图像,或者第一人称场景(例如在一个游戏中或者一个全景视频中)是非常方便使用的。

 4、 一个元素在能够被指针锁定之前,必须首先进入全屏模式

锁定指针的过程是异步的,使用 (pointerlockchangepointerlockerror) 事件来表明请求是成功还是失败了。这和 Fullscreen API 的工作方式是一致的,它使用 requestFullScreen 方法,以及 fullscreenchange 和 fullscreenerror 事件。

5、锁定状态

当指针锁定被启动之后,正常的 MouseEvent 属性 clientX, clientY, screenX, 和 screenY ,保持不变,就像鼠标没有在移动一样。movementXmovementY 属性持续提供鼠标的位置变化。如果鼠标在一个方向上持续移动,movementXmovementY的值是没有限制的。不存在鼠标光标的概念,而且光标无法移到窗口之外,而且也不会被屏幕边缘所固定。

6、未锁定状态

无论鼠标锁定状态是怎样的, movementX 和 movementY 参数一直有效,并且为了方便起见,甚至在未锁定状态也是有效的。当鼠标被解除锁定,系统光标可以退出并重新进入浏览器窗口。如果发生这种情况,movementX 和 movementY 可能会被设置成0。

demo如下:

<!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <title>Title</title>
   <style>
      #pointer_lock_element:-webkit-full-screen {
         position : fixed;
         top      : 0;
         left     : 0;
         width    : 100%;
         height   : 100%;
         overflow : auto;
         text-align: center;
         line-height: 1000px;
         vertical-align: middle;
      }
      #pointer_lock_element:-moz-full-screen {
         position : fixed;
         top      : 0;
         left     : 0;
         width    : 100%;
         height   : 100%;
         overflow : auto;
         text-align: center;
         line-height: 1000px;
         vertical-align: middle;
      }
      #pointer_lock_element:-ms-fullscreen {
         position : fixed;
         top      : 0;
         left     : 0;
         width    : 100%;
         height   : 100%;
         overflow : auto;
         text-align: center;
         line-height: 1000px;
         vertical-align: middle;
      }
      #pointer_lock_element:fullscreen {
         position : fixed;
         top      : 0;
         left     : 0;
         width    : 100%;
         height   : 100%;
         overflow : auto;
         text-align: center;
         line-height: 1000px;
         vertical-align: middle;
      }
   </style>
</head>
<body>
<button onclick="lockPointer()">锁住它!</button>
<div id="pointer_lock_element">我是要被全屏展示的</div>
<script>
   var elem;

   document.addEventListener("mousemove", function(e) {
      var movementX = e.movementX       ||
            e.mozMovementX    ||
            e.webkitMovementX ||
            0,
         movementY = e.movementY       ||
            e.mozMovementY    ||
            e.webkitMovementY ||
            0;

      // 打印鼠标移动的增量值。
      ///指针锁定参数 movementX = eNow.screenX - ePrevious.screenX 

      console.log("movementX=" + movementX, "movementY=" + movementY);
      console.log("clientX=" + e.clientX, "clientY=" + e.clientY);
      console.log("screenX=" + e.screenX, "screenY=" + e.screenY);
   }, false);

   function fullscreenChange() {
      if (document.webkitFullscreenElement === elem ||
         document.mozFullscreenElement === elem ||
         document.mozFullScreenElement === elem) { // 较旧的 API 大写 'S'.
         // 元素进入全屏模式了,现在我们可以请求指针锁定。
         elem.requestPointerLock = elem.requestPointerLock    ||
            elem.mozRequestPointerLock ||
            elem.webkitRequestPointerLock;
         elem.requestPointerLock();
      }
   }

   document.addEventListener('fullscreenchange', fullscreenChange, false);
   document.addEventListener('mozfullscreenchange', fullscreenChange, false);
   document.addEventListener('webkitfullscreenchange', fullscreenChange, false);

   function pointerLockChange() {
      if (document.pointerLockElement===elem ||
         document.mozPointerLockElement === elem ||
         document.webkitPointerLockElement === elem) {
         console.log("指针锁定成功了。");
      } else {
         console.log("指针锁定已丢失。");
      }
   }

   document.addEventListener('pointerlockchange', pointerLockChange, false);
   document.addEventListener('mozpointerlockchange', pointerLockChange, false);
   document.addEventListener('webkitpointerlockchange', pointerLockChange, false);

   function pointerLockError() {
      console.log("锁定指针时出错。");
   }

   document.addEventListener('pointerlockerror', pointerLockError, false);
   document.addEventListener('mozpointerlockerror', pointerLockError, false);
   document.addEventListener('webkitpointerlockerror', pointerLockError, false);

   function lockPointer() {
      elem  = document.getElementById("pointer_lock_element");
      // 开始于使元素进入全屏模式。目前的实现
      // 要求元素在请求指针锁定前要处于全屏模式下
      // -- 这在以后可能会发生改变。

      requestFullscreen(elem);
   }
   function requestFullscreen( elem ) {
      if (elem.requestFullscreen) {
         elem.requestFullscreen();
      }
      else if (elem.webkitRequestFullscreen) {
         // 对 Chrome 特殊处理,
         // 参数 Element.ALLOW_KEYBOARD_INPUT 使全屏状态中可以键盘输入。

         if ( window.navigator.userAgent.toUpperCase().indexOf( 'CHROME' ) >= 0 ) {
            elem.webkitRequestFullScreen( Element.ALLOW_KEYBOARD_INPUT );
         }
         // Safari 浏览器中,如果方法内有参数,则 Fullscreen 功能不可用。
         else {
            elem.webkitRequestFullScreen();
         }
      }
      else if (elem.mozRequestFullScreen||elem.mozRequestFullscreen) {
         elem.mozRequestFullScreen();
      }
   }

   document.addEventListener('keydown', function(e){
      if(e.which == 13){
         exitFullscreen();
      }
   }, false);
   function exitFullscreen() {
      if (document.exitFullscreen) {
         document.exitFullscreen();
      }
      else if (document.webkitCancelFullScreen) {
         document.webkitCancelFullScreen();
      }
      else if (document.mozCancelFullScreen) {
         document.mozCancelFullScreen();
      }
   }
   
</script>
</body>
</html>

PerformanceNavigation

  1. interface PerformanceNavigation {
        const unsigned short TYPE_NAVIGATE = 0;
        const unsigned short TYPE_RELOAD = 1;
        const unsigned short TYPE_BACK_FORWARD = 2;
        const unsigned short TYPE_RESERVED = 255;
        readonly attribute unsigned short type;
        readonly attribute unsigned short redirectCount;
    }

    TYPE_NAVIGATE:通过点击链接、输入url、提交表单、或者通过一个脚本而非reload,forward和back引起的跳转
    TYPE_RELOAD:通过点击reload或者调用location.reload的跳转
    TYPE_BACK_FORWARD:通过点击前进后退,或者和遍历历史的跳转
    TYPE_RESERVED:除以上case之外的,如http-equiv=”refresh”的跳转

PerformanceTiming

  1. navigationStart:前一个文档unload完成的时间,如果没有前一个文档,则该值为fetchStart的时间。
  2. unloadEventStart:如果有前一个文档,并且同源,则该值为前一个文档的unload事件开始触发的时间,其他情况,该值为0。
  3. unloadEventEnd:与上面事件对应,为unload事件结束的时间,如果在跳转过程中发生了重定向或者类似的跳转,只要这些跳转中存在不同源的,则unloadEventStart和unloadEventEnd都是0。
  4. redirectStart:只有在跳转过程中发生重定向,并且同源,则该值为上一次跳转开始的时间,其他情况,该值为0。
  5. redirectEnd:同上,该值为上一次跳转请求收到最后一个字节的时间。
  6. fetchStart:一个新的资源通过http请求或者其他类似的方式获取时,该值为检查缓存之前的时间,或者发起请求之前的时间。
  7. domainLookupStart:在获取一个文档时,开始查找dns时的时间,如果该文档已经存在于appcache中或者本地资源中,则该值为fetchStart的值。
  8. domainLookupEnd:同上,为dns查询结束的时间。
  9. connectStart:浏览器开始与服务器建立连接获取文档的时间,如果该文档已经存在于appcache中或者本地资源中,则该值为domainLookupEnd的值。
  10. connectEnd:浏览器与服务器建立连接完毕的时间(包含https的握手和socket的认证),如果失败,则创建一个新的链接,即connectStart和connectEnd都会变成新的值。
  11. secureConnectionStart:该值为可选值,如果浏览器没有实现,则是undefined,如果实现了,并且当前页面的协议是https,则该值表示的是开始https握手的时间,否则是0。
  12. requestStart:浏览器开始向服务器请求文档的时间,或者从appcache或本地资源中请求。如果请求失败,则会新建立连接,此时该值变成新的值。为什么没有requestEnd属性?①该属性不能真正代表网络传输的结束时间;②某些浏览器要在http层判断请求的结束时间代价太高
  13. responseStart:浏览器开始接收文档的时间,或者。。。
  14. responseEnd:同上,注:该属性代表的时间要比连接断开的时间要靠前。
  15. domLoading:浏览器设置文档状态为loading之前的时间。
  16. domInteractive:浏览器设置文档状态为interactive之前的时间。
  17. domContentLoadedEventStart:文档load事件触发的时间。
  18. domContentLoadedEventEnd:文档load事件触发结束的时间。
  19. domComplete:浏览器将文档状态设置成complete之前的时间。
  20. 如果文档的readiness状态多次改变,则domLoading, domInteractive, domContentLoadedEventStart, domContentLoadedEventEnd, domComplete这五个时间代表的都是状态第一次变化的时间
  21. loadEventStart:当前文档触发load事件之前的时间。
  22. loadEventEnd:当前文档触发load事件结束的时间。

第一期

Mobile Web Best Practices 1.0

  1. 保证不同的设备通过同一URL可以获得相同的内容和服务
  2. 在页面头部提供最小的导航栏,并且提供用户链接定义明确的导航栏。
  3. 避免一个页面有过多的链接,避免用户需要跳转很多个页面才能获取到他们寻找的内容
  4. 在通知用户之前,不要刷新和改变页面内容
  5. 保持页面加载资源的最小化,不要在页面放置不可获得的图片链接,避免在页面大图
  6. 限制内容只能在一个方向上滚动
  7. 提供一个简短的描述性的标题
  8. 提供错误处理,并且为提供和离开错误页面的提供导航
  9. 为HTTP请求提供缓存信息
  10. 用色彩来传递内容信息,使用背景图时要保证内容的可读性。

PNG

  1. PNG的发展历史和特性
    PNG是20世纪90年代中期开始开发的图像文件存储格式,其目的是企图替代GIF和TIFF文件格式,同时增加一些GIF文件格式所不具备的特性。
    流式网络图形格式(Portable Network Graphic Format,PNG)名称来源于非官方的“PNG’s Not GIF”,是一种位图文件(bitmap file)存储格式,读成“ping”。PNG用来存储灰度图像时,灰度图像的深度可多到16位,存储彩色图像时,彩色图像的深度可多到48位,并且还可存储多到16位的α通道数据。PNG使用从LZ77派生的无损数据压缩算法。
    其包含下面这些特性:
    保留GIF文件格式的以下特性:

    1. 使用彩色查找表或者叫做调色板可支持256种颜色的彩色图像。
    2. 流式读/写性能(streamability):图像文件格式允许连续读出和写入图像数据,这个特性很适合于在通信过程中生成和显示图像。
    3. 逐次逼近显示(progressive display):这种特性可使在通信链路上传输图像文件的同时就在终端上显示图像,把整个轮廓显示出来之后逐步显示图像的细节,也就是先用低分辨率显示图像,然后逐步提高它的分辨率。
    4. 透明性(transparency):这个性能可使图像中某些部分不显示出来,用来创建一些有特色的图像。
    5. 辅助信息(ancillary information):这个特性可用来在图像文件中存储一些文本注释信息。
    6. 独立于计算机软硬件环境。
    7. 使用无损压缩。

    增加的新特性:

    1. 支持每个像素为48位的真彩色图像。 
    2. 支持每个像素为16位的灰度图像。 
    3. 可为灰度图和真彩色图添加α通道。 
    4. 添加图像的γ信息。 
    5. 使用循环冗余码(cyclic redundancy code,CRC)检测损害的文件。 
    6. 加快图像显示的逐次逼近显示方式。 
    7. 标准的读/写工具包。 
    8. 可在一个文件中存储多幅图像。
  2. image的概念
    图片实际上是一个矩阵,而矩阵每个值是一个拥有若干个通道的向量(具体怎么表示根据当前图片的定义,即物理意义上的位图)
    向量中的每个通道又有自己的层数, 向量的叠加最终构成了像素点的颜色。
  3. PNG中对image的处理和转换
    step1:[alpha separation]分离alpha通道
    众所周知,alpha通道表示透明度,alpha越大表示越不透明。
    同时在png中alpha通道是不受gamma矫正影响的。step2: indexing or ( [RGB merging] [alpha compaction] ) 处理其他颜色通道 
    可能这张图片用的是调色板index的原理,也可能是有RGB三通道或RGBA四通道的图片,PNG转换的第二步就是做色彩合并的工作
    调色板index的原理: 先将所有色彩组成一个数组,然后将图片中每个像素的值替换为数组中对应颜色的下标,以此来达到压缩的目的。
    step3: sample depth scaling 颜色统一度量
    在PNG的定义中,RGBA每个通道的位数都是可以自设定的,比如R通道大小可以是4位(取值0~15)而G通道大小可以为3位(取值0~7),那么第三步做的就是统一单位,比如将0~7线性映射到0~15
  4. PNG图片的5种类型
    1) RGBA图片,每个像素点有4个颜色通道
    2) 带alpha通道的灰度图
    3) RGB图片
    4) 灰度图
    5) 调色板index的图片,每个像素点的值为对应调色板数组颜色中的下标

JS API

  1. getComputeStyle / currentStyle(IE)
    获取元素计算后的样式(只读)
    用法:
    window.getComputedStyle(dom, ‘伪元素’)  /  dom.currentStyle
    获得css的值  getPropertyValue / getAttribute
    window.getComputedStyle(dom). getPropertyValue(‘color’)
    可以获得伪元素的值,设置伪元素的值可以用insertRule (ie9 以下使用 addRule)
    用法:document.createElement(‘style’) .sheet.insertRule(“#blanc { color: white }”)场景:在需要js控制修改伪元素的样式(无法用class控制)
  2. SubtleCrypto(下期调研)
    提供原始加密算法。开发人员可以利用基本算法实现各种协议或者其他应用的加密
  3. SourceBuffer(下期调研)
    音频或者视频的字节流
  4. getCurrentPosition
    获取当前地理位置
  5. watchPosition(下期调研)
    监听地理位置的变化,直到clearWatch被调用
  6. Position
    包含一组地理坐标及其关联的精度,以及一组其他可选属性,例如高度和速度
  7. Coordinates
    altitude属性表示所述位置的高度
    accuracy属性表示纬度和经度坐标的精度水平
    heading属性表示所述主机装置的行进方向和以度被指定
    speed属性表示主机设备的当前速度的水平分量的大小,并且以米/秒来指定
  8. PositionError
    PERMISSION_DENIED (数值1)位置获取过程失败,因为文档没有使用Geolocation API的权限。
    POSITION_UNAVAILABLE (数值2)无法确定设备的位置。例如,在位置获取过程中使用的一个或多个位置提供商报告了导致过程完全失败的内部错误。
    TIMEOUT (数值3)timeout 在实现可以成功获取新Position对象之前,属性指定的时间已经过去。
    message属性必须返回一个错误消息,描述遇到的错误的详细信息。此属性主要用于调试,开发人员不应直接在其应用程序用户界面中使用它
  9. pointerlockchange Event(下期调研)
    鼠标指针锁定状态改变
  10. pointerlockerror Event(下期调研)
    鼠标指针锁定错误

 Mathml On Web

  1. MathML 是一个用于标记数学表达式的 XML 词汇表,它包含两个子语言:Presentation MathML 和 Content MathML。Presentation MathML 主要负责描述数学表达式的布局。Content MathML 主要负责标记表达式的某些含义或数学结构。
  2. 可行性和适用性(下期调研)

字符编码

  1. 在web上通常使用的有ISO-8859-1(也叫Latin-1,适用于大多数西欧语言),ISO-8859-5(支持Cyrillic即古代斯拉夫语的字母),SHIFT_JIS和EUC_JP(日语编码),UTF-8(就是ISO 10646编码针对不同的字符使用不同的字节数)
  2. 字符编码的名字对大小写不敏感
  3. 所有HTML4处理器均已支持UTF-8,而所有XHTML和XML处理器支持UTF-8和UTF-16
  4. 当浏览器识别到的编码类型与页面本身的编码类型不符时就会出现乱码,所以应该将页面本身的编码类型与meta中设置的编码类型写为一致的。发送请求的HTTP头部会通过Content-Type字段来告诉用户代理页面使用的是什么字符编码;但是一般很多服务器都不支持发送charset参数或者没有配置发送这个参数。
    问:如果既没有设置文档编码,有没有设置请求编码,浏览器以何种编码解析?(下期调研)
  5. 告知浏览器页面使用的字符编码方式:通过HTTP请求中的Content-type子都的charset参数,在页面中使用meta来声明。
  6. 给页面中的一些对外资源标签设置charset属性,比如<link href=”shanghai.htm” rel=”parent” charset=”en” />
  7. 字符引用:当文档中的字符不能用字符编码来表示的时候,如<,>等,则使用字符引用。字符引用分两种:①数字字符引用(十进制:&#34,十六进制:&#x22);②实体引用(&quot;)
    问:这两类字符引用是否有区别?(下期调研)

ES6语法

  1. let关键字
  2. 块级作用域
  3. const关键字
  4. delete方法的使用(问:返回值true还是false如何去判断?为什么全局var定义的变量不可删除?为何定义的方法不能删除?