function job_1() {
var x = 1 && 0 || 5;
var y = 1 && 3 || 5;
var z = 0 && 1 || 3;
console.log(x, y, z);
}
function job_2() {
var x = 1 && 0;
x = x || 5;
var y = 1 && 3;
y = y || 5;
var z = 0 && 1;
z = z || 3;
console.log(x, y, z);
}
job_1();
job_2();
2017年2月28日 星期二
Deferred(以 promise 為核心)
/**
* promise, deferred 的擴充
*/
(function($) {
if (typeof $.jQuery === 'function') {
/**
* 若有 load jquery
* $.Async(), new $.Async()
*/
$ = $.jQuery;
$.Async = Promise_;
} else if(typeof module === 'object' && module.exports === 'object'){
// for node.js
module.exports = Promise_;
}else {
/**
* 若沒有 load jquery, for window
*
* Deferred(), new Deferred()
*/
$.Deferred = Promise_;
}
////////////////////////////////////////////////////////////////////////////
/**
* 以(promise)為核心
*
*/
////////////////////////////////////////////////////////////////////////////
var PENDING = 1; // 事件仍在處理狀態
var FULFILLED = 2; // 事件已處理完成
var REJECTED = 3; // 事件已處理完,但拋出 reject
////////////////////////////////////////////////////////////////////////////
function Promise_(name) {
if (!(this instanceof Promise_)) {
if (typeof name === 'function') {
var res = (function() {
var promise = new Promise_();
name(promise);
return promise
})();
return res;
} else {
return new Promise_(name);
}
}
/* ------------------------ */
this.prev; // 上一個 promise
this.next; // 下一個 promise
/* ------------------------ */
this.fn = this.constructor;
// this.Job = this.fn.prototype.Job;
this.name = name || 'init';
this.id = this.fn.id++;
/* ------------------------ */
this.jobList = [];
/* ------------------------ */
this.value;
this.reason;
/* ------------------------ */
this.status = PENDING;
/* ================================================================== */
this.resolve = function(value) {
this.status = FULFILLED;
// 刪除 reject(), resolve()
// 避免再次更動狀況
delete this.reject;
delete this.resolve;
this.value = value;
this._doJob();
return this;
};
/* ================================================================== */
this.reject = function(reason) {
this.status = REJECTED;
// 刪除 reject(), resolve()
// 避免再次更動狀況
delete this.reject;
delete this.resolve;
if (arguments.length > 1) {
this.reason = [].slice.call(arguments);
} else {
this.reason = reason;
}
this._doJob();
return this;
};
}
Promise_.id = 0;
/* ====================================================================== */
(function(fn) {
/**
* 整個程式最重要的地方
*
*/
this.then = function(onFulfilled, onRejected) {
// debugger;
var next_promise = this.next = new fn('then');
var self = next_promise.prev = this;
/* ----------------------------- */
if (this.status === PENDING) {
var _callBack = callBack.bind(this, onFulfilled);
var _errorBack = errorBack.bind(this, onRejected);
var job = new this.Job(_callBack, _errorBack);
this.jobList.push(job);
} else if (this.status === FULFILLED) {
// 立馬執行
callBack.call(this, onFulfilled);
} else if (this.status === REJECTED) {
// 立馬執行
errorBack.call(this, onRejected);
}
/* ----------------------------- */
return next_promise;
};
/* ================================================================== */
/**
* call by this
*
* 把 onFulfilled 包起來
*
* 呼叫下一個 promise
*/
function callBack(onFulfilled) {
// debugger;
var return_value, return_promise, next_promise = this.next;
if (typeof onFulfilled === 'function') {
return_value = onFulfilled(this.value);
} else {
// 若沒有設定(onFulfilled)
// 呼叫子 promise
next_promise.resolve(this.value);
return;
}
/* ---------------------------------- */
// 若有設定(onFulfilled)
if (return_value instanceof Promise_) {
return_promise = return_value;
// 等待 ret 執行完
return_promise.then(function(_value) {
// debugger;
next_promise.resolve(_value);
}, function(_reason) {
// debugger;
next_promise.reject(_reason);
});
} else {
// 呼叫子 promise
next_promise.resolve(return_value);
}
}
/* ================================================================== */
/**
* call by this
*
* 把 onRejected 包起來
*
* 呼叫下一個 promise
*/
function errorBack(onRejected) {
// debugger;
var return_value, return_promise, next_promise = this.next;;
if (typeof onRejected === 'function') {
return_value = onRejected(this.reason);
// 若要符合 promise 規則啟用下面註解
// promise 只會執行一次 catch(),皆下來的 catch()都不會執行
// return;
} else {
// 若沒有設定(onRejected)
// 正常程序
next_promise.reject(this.reason);
return;
}
/* ---------------------------------- */
// 若有設定(onRejected)
if (return_value instanceof Promise_) {
return_promise = return_value;
// 等待 return_promise 執行完
return_promise.then(function(_value) {
// debugger;
next_promise.resolve(_value);
}, function(_reason) {
// debugger;
next_promise.reject(_reason);
});
} else {
// 正常程序
next_promise.reject(return_value);
}
}
}).call(Promise_.prototype, Promise_);
////////////////////////////////////////////////////////////////////////////
(function(fn) {
this.catch = function(onRejected) {
var promise = this.then(undefined, onRejected);
return promise;
};
/* ================================================================== */
this.fail = function(onRejected) {
var promise = this.then(undefined, onRejected);
return promise;
};
/* ================================================================== */
this.done = function(onFulfilled) {
var promise = this.then(onFulfilled, undefined);
return promise;
};
/* ================================================================== */
this.always = function(callback) {
var promise = this.then(callback, callback);
return promise;
};
}).call(Promise_.prototype, Promise_);
////////////////////////////////////////////////////////////////////////////
(function(fn) {
/* ================================================================== */
this._doJob = function() {
// debugger;
/**
* 執行註冊過的 job
*/
while (this.jobList.length) {
// 表示有等待他完成後要執行的工作
var callback, outValue;
var job = this.jobList.shift();
/* ---------------------------------- */
if (this.status === FULFILLED) {
outValue = this.value;
callback = job.getResolve();
} else {
outValue = this.reason;
callback = job.getReject();
}
/* ---------------------------------- */
/**
* callback
*/
callback(outValue);
}
};
/* ================================================================== */
}).call(Promise_.prototype, Promise_);
////////////////////////////////////////////////////////////////////////////
(function(fn) {
this.Job = Job;
/**
* class
* 處理 then()
*/
function Job(onFulfilled, onRejected) {
var self = this;
var resolve;
var reject;
__construct();
/**
* 建構式
*/
function __construct() {
(typeof onFulfilled === 'function') && (resolve = onFulfilled);
(typeof onRejected === 'function') && (reject = onRejected);
}
/* ============================================================== */
this.getResolve = function() {
return (typeof resolve === 'function' ? resolve : undefined);
};
/* ============================================================== */
this.getReject = function() {
return (typeof reject === 'function' ? reject : undefined);
};
}
}).call(Promise_.prototype, Promise_);
////////////////////////////////////////////////////////////////////////////
/**
* 類別方法
*/
(function(fn) {
fn.resolve = function(value) {
// debugger;
var promise = new fn();
promise.resolve(value);
return promise;
};
/* ================================================================== */
fn.reject = function(reason) {
// debugger;
var promise = new fn();
promise.reject(reason);
return promise;
};
}).call(Promise_.prototype, Promise_);
////////////////////////////////////////////////////////////////////////////
/**
* 類別方法
*/
(function(fn) {
fn.all = function(promises) {
if (!Array.isArray(promises)) {
throw new TypeError('You must pass an array to all.');
}
var promise = new fn('all');
var jobLength = promises.length;
var data = {
detail: [],
index: undefined,
reason: undefined,
promise: promise,
jobLength: jobLength
};
/* ---------------------------------- */
promises.forEach(function(_promise, i) {
if (!(_promise instanceof Promise_)) {
throw new TypeError('[' + i + '] not instance of Promise_');
}
data.detail[i] = undefined;
var all_ok = get_okFn.call(data, i);
var all_error = get_errorFn.call(data, i);
_promise.then(all_ok, all_error);
});
/* ---------------------------------- */
return promise;
};
/* ================================================================== */
function get_okFn(i) {
return function(value) {
this.detail[i] = value;
if (--this.jobLength < 1) {
// finish
this.promise.resolve(this.detail.slice());
}
}.bind(this);
};
/* ================================================================== */
function get_errorFn(i) {
return function(reason) {
var error_data = {
index: i,
detail: reason,
data: this.detail.slice()
};
this.promise.reject(error_data);
}.bind(this);
};
}).call(Promise_.prototype, Promise_);
////////////////////////////////////////////////////////////////////////////
/**
* 類別方法
*/
(function() {
/* ================================================================== */
this.race = function(promises) {
if (!Array.isArray(promises)) {
throw new TypeError('You must pass an array to all.');
}
var promise = new fn('race');
/* ---------------------------------- */
promises.forEach(function(_promise, i) {
if (!(_promise instanceof Promise_)) {
throw new TypeError('[' + i + '] not instance of Promise_');
}
_promise.then(function(value) {
promise.resolve(value);
}, function(reason) {
promise.reject(reason);
});
});
/* ---------------------------------- */
return promise;
};
}).call(Promise_.prototype, Promise_);
})(this);
* promise, deferred 的擴充
*/
(function($) {
if (typeof $.jQuery === 'function') {
/**
* 若有 load jquery
* $.Async(), new $.Async()
*/
$ = $.jQuery;
$.Async = Promise_;
} else if(typeof module === 'object' && module.exports === 'object'){
// for node.js
module.exports = Promise_;
}else {
/**
* 若沒有 load jquery, for window
*
* Deferred(), new Deferred()
*/
$.Deferred = Promise_;
}
////////////////////////////////////////////////////////////////////////////
/**
* 以(promise)為核心
*
*/
////////////////////////////////////////////////////////////////////////////
var PENDING = 1; // 事件仍在處理狀態
var FULFILLED = 2; // 事件已處理完成
var REJECTED = 3; // 事件已處理完,但拋出 reject
////////////////////////////////////////////////////////////////////////////
function Promise_(name) {
if (!(this instanceof Promise_)) {
if (typeof name === 'function') {
var res = (function() {
var promise = new Promise_();
name(promise);
return promise
})();
return res;
} else {
return new Promise_(name);
}
}
/* ------------------------ */
this.prev; // 上一個 promise
this.next; // 下一個 promise
/* ------------------------ */
this.fn = this.constructor;
// this.Job = this.fn.prototype.Job;
this.name = name || 'init';
this.id = this.fn.id++;
/* ------------------------ */
this.jobList = [];
/* ------------------------ */
this.value;
this.reason;
/* ------------------------ */
this.status = PENDING;
/* ================================================================== */
this.resolve = function(value) {
this.status = FULFILLED;
// 刪除 reject(), resolve()
// 避免再次更動狀況
delete this.reject;
delete this.resolve;
this.value = value;
this._doJob();
return this;
};
/* ================================================================== */
this.reject = function(reason) {
this.status = REJECTED;
// 刪除 reject(), resolve()
// 避免再次更動狀況
delete this.reject;
delete this.resolve;
if (arguments.length > 1) {
this.reason = [].slice.call(arguments);
} else {
this.reason = reason;
}
this._doJob();
return this;
};
}
Promise_.id = 0;
/* ====================================================================== */
(function(fn) {
/**
* 整個程式最重要的地方
*
*/
this.then = function(onFulfilled, onRejected) {
// debugger;
var next_promise = this.next = new fn('then');
var self = next_promise.prev = this;
/* ----------------------------- */
if (this.status === PENDING) {
var _callBack = callBack.bind(this, onFulfilled);
var _errorBack = errorBack.bind(this, onRejected);
var job = new this.Job(_callBack, _errorBack);
this.jobList.push(job);
} else if (this.status === FULFILLED) {
// 立馬執行
callBack.call(this, onFulfilled);
} else if (this.status === REJECTED) {
// 立馬執行
errorBack.call(this, onRejected);
}
/* ----------------------------- */
return next_promise;
};
/* ================================================================== */
/**
* call by this
*
* 把 onFulfilled 包起來
*
* 呼叫下一個 promise
*/
function callBack(onFulfilled) {
// debugger;
var return_value, return_promise, next_promise = this.next;
if (typeof onFulfilled === 'function') {
return_value = onFulfilled(this.value);
} else {
// 若沒有設定(onFulfilled)
// 呼叫子 promise
next_promise.resolve(this.value);
return;
}
/* ---------------------------------- */
// 若有設定(onFulfilled)
if (return_value instanceof Promise_) {
return_promise = return_value;
// 等待 ret 執行完
return_promise.then(function(_value) {
// debugger;
next_promise.resolve(_value);
}, function(_reason) {
// debugger;
next_promise.reject(_reason);
});
} else {
// 呼叫子 promise
next_promise.resolve(return_value);
}
}
/* ================================================================== */
/**
* call by this
*
* 把 onRejected 包起來
*
* 呼叫下一個 promise
*/
function errorBack(onRejected) {
// debugger;
var return_value, return_promise, next_promise = this.next;;
if (typeof onRejected === 'function') {
return_value = onRejected(this.reason);
// 若要符合 promise 規則啟用下面註解
// promise 只會執行一次 catch(),皆下來的 catch()都不會執行
// return;
} else {
// 若沒有設定(onRejected)
// 正常程序
next_promise.reject(this.reason);
return;
}
/* ---------------------------------- */
// 若有設定(onRejected)
if (return_value instanceof Promise_) {
return_promise = return_value;
// 等待 return_promise 執行完
return_promise.then(function(_value) {
// debugger;
next_promise.resolve(_value);
}, function(_reason) {
// debugger;
next_promise.reject(_reason);
});
} else {
// 正常程序
next_promise.reject(return_value);
}
}
}).call(Promise_.prototype, Promise_);
////////////////////////////////////////////////////////////////////////////
(function(fn) {
this.catch = function(onRejected) {
var promise = this.then(undefined, onRejected);
return promise;
};
/* ================================================================== */
this.fail = function(onRejected) {
var promise = this.then(undefined, onRejected);
return promise;
};
/* ================================================================== */
this.done = function(onFulfilled) {
var promise = this.then(onFulfilled, undefined);
return promise;
};
/* ================================================================== */
this.always = function(callback) {
var promise = this.then(callback, callback);
return promise;
};
}).call(Promise_.prototype, Promise_);
////////////////////////////////////////////////////////////////////////////
(function(fn) {
/* ================================================================== */
this._doJob = function() {
// debugger;
/**
* 執行註冊過的 job
*/
while (this.jobList.length) {
// 表示有等待他完成後要執行的工作
var callback, outValue;
var job = this.jobList.shift();
/* ---------------------------------- */
if (this.status === FULFILLED) {
outValue = this.value;
callback = job.getResolve();
} else {
outValue = this.reason;
callback = job.getReject();
}
/* ---------------------------------- */
/**
* callback
*/
callback(outValue);
}
};
/* ================================================================== */
}).call(Promise_.prototype, Promise_);
////////////////////////////////////////////////////////////////////////////
(function(fn) {
this.Job = Job;
/**
* class
* 處理 then()
*/
function Job(onFulfilled, onRejected) {
var self = this;
var resolve;
var reject;
__construct();
/**
* 建構式
*/
function __construct() {
(typeof onFulfilled === 'function') && (resolve = onFulfilled);
(typeof onRejected === 'function') && (reject = onRejected);
}
/* ============================================================== */
this.getResolve = function() {
return (typeof resolve === 'function' ? resolve : undefined);
};
/* ============================================================== */
this.getReject = function() {
return (typeof reject === 'function' ? reject : undefined);
};
}
}).call(Promise_.prototype, Promise_);
////////////////////////////////////////////////////////////////////////////
/**
* 類別方法
*/
(function(fn) {
fn.resolve = function(value) {
// debugger;
var promise = new fn();
promise.resolve(value);
return promise;
};
/* ================================================================== */
fn.reject = function(reason) {
// debugger;
var promise = new fn();
promise.reject(reason);
return promise;
};
}).call(Promise_.prototype, Promise_);
////////////////////////////////////////////////////////////////////////////
/**
* 類別方法
*/
(function(fn) {
fn.all = function(promises) {
if (!Array.isArray(promises)) {
throw new TypeError('You must pass an array to all.');
}
var promise = new fn('all');
var jobLength = promises.length;
var data = {
detail: [],
index: undefined,
reason: undefined,
promise: promise,
jobLength: jobLength
};
/* ---------------------------------- */
promises.forEach(function(_promise, i) {
if (!(_promise instanceof Promise_)) {
throw new TypeError('[' + i + '] not instance of Promise_');
}
data.detail[i] = undefined;
var all_ok = get_okFn.call(data, i);
var all_error = get_errorFn.call(data, i);
_promise.then(all_ok, all_error);
});
/* ---------------------------------- */
return promise;
};
/* ================================================================== */
function get_okFn(i) {
return function(value) {
this.detail[i] = value;
if (--this.jobLength < 1) {
// finish
this.promise.resolve(this.detail.slice());
}
}.bind(this);
};
/* ================================================================== */
function get_errorFn(i) {
return function(reason) {
var error_data = {
index: i,
detail: reason,
data: this.detail.slice()
};
this.promise.reject(error_data);
}.bind(this);
};
}).call(Promise_.prototype, Promise_);
////////////////////////////////////////////////////////////////////////////
/**
* 類別方法
*/
(function() {
/* ================================================================== */
this.race = function(promises) {
if (!Array.isArray(promises)) {
throw new TypeError('You must pass an array to all.');
}
var promise = new fn('race');
/* ---------------------------------- */
promises.forEach(function(_promise, i) {
if (!(_promise instanceof Promise_)) {
throw new TypeError('[' + i + '] not instance of Promise_');
}
_promise.then(function(value) {
promise.resolve(value);
}, function(reason) {
promise.reject(reason);
});
});
/* ---------------------------------- */
return promise;
};
}).call(Promise_.prototype, Promise_);
})(this);
2017年2月25日 星期六
正則
^ $ * + ? { } [ ] \ | ( ) . -
等為正則表達式的保留字元
javascript 的保留字多 /
------------------------------ ------------------------------ ------
等為正則表達式的保留字元
javascript 的保留字多 /
------------------------------
\d : [0-9]
\w : [A-Za-z0-9_](不含中文)
\s : 空白, 換行
\n : 換行
\b : 詞邊界
------------------------------ ------------------------------ ------
\D vs \d
\W vs \w
\s vs \S
\b vs \B
\b => \w頭尾兩端的(\W)
\b => \w頭尾兩端的(\W)
------------------------------ ------------------------------ ------
{0, m} : 前一字元匹配 0 到 n 次
{n, } : 前一字元匹配 n 到 無限 次
------------------------------ ------------------------------ ------
? : 匹配 0-1 次
* : 匹配 0- 次
+ : 匹配 1- 次
------------------------------ ------------------------------ ------
[CD][a-z]+ = (C|D)[a-z]+ = [CD]{1}[a-z]+
/(http.*\\\\.*|http.*\/\/.*)/ ==> 匹配 /http.*\\\\.*/ or /http.*\/\/.*/
(gray|grey) = gr(a|e)y = gr[ae]y
------------------------------ ------------------------------ ------
重複匹配
/(.)(.) \2\1/ => AD DA
------------------------------ ------------------------------ ------
(0 | 1 | 2 | 3 | 4 | 5 ) = [ 0 1 2 3 4 5 ]
------------------------------ ------------------------------ ------
向前查找>>
XXX(?=YYY) ==> XXX 後面要有 YYY 但只有 XXX會被取代
否定向前查找>>
XXX(?!YYY)
向後查找>>
(?<=YYY)XXX ==> XXX 前面要有 YYY 但只有 XXX會被取代
否定向後查找>>
否定向後查找>>
(?<!YYY)XXX
------------------------------ ------------------------------ ------
關閉貪婪搜尋有用的情況:
=> 有兩個以上的長度條件下,去選擇是否採貪婪搜尋
如
*
+
{n,m}
------------------------------ ------------------------------ ------
預設搜索是貪婪法,如 {n, m} => 優先搜索 m 次有符合就放棄
{n, m}? 則是惰性匹配 => 搜索 n 次有搜索到就放棄
------------------------------ ------------------------------ ------
Exp 1>>
(
<hhhh><ggg><hhhh><ggg>
)
(( /<.{4,20}>/ ==> (匹配) array('<hhhh><ggg><hhhh><ggg>' ) ))
==>貪婪搜索會用最大化搜尋
1.當搜尋過第一個字'<'後,到了.{4,20}會先取{4, 20}中最大的 20 來找
2.若20個任意字後面要跟'>'沒找到, 就遞減搜尋直到4個任意字後面有跟'>'
(( /<.{4,20}?>/ ==> (匹配)<hhhh> ))
==>若取消貪婪搜尋
1.當搜尋過第一個字'<'後,到了.{4,20}會先取{4, 20}中最小的 4 來找
2.找到'<hhhh>'
3.剩下'<ggg><hhhh><ggg>'
4.重頭再用'/<.{4,20}?>/'匹配剩下的'< ggg><hhhh><ggg>'
------------------------------ ------------------------------ ------
Exp 2>>
(
<html><head><title></title></ head><body></body></html>
)
/<.*>/ ==> all
/<.*?>/ ==> <html>.........
------------------------------ ------------------------------ ------
Exp 3>>
(
255.255.256.255
)
A => /(.{3}\.|.{3}(?=\.))/
B => /(.{3}(?=\.)|.{3}\.)/
A.B都是再檢查4個字與差不多條件.... 但順序不同結果也不同
規則是由左到右
2017年2月24日 星期五
Ys7
http://www.entertainment14.net/blog/post/88730341-%E3%80%8A%E4%BC%8A%E8%98%877%E3%80%8B%E5%9C%96%E6%96%87%E6%94%BB%E7%95%A5%E5%8F%8A%E5%85%A8%E4%BB%BB%E5%8B%99%E8%AA%AA%E6%98%8E
Ys7
http://www.entertainment14.net/blog/post/92293761-%E4%BC%8A%E8%98%877-%E8%A9%B3%E7%B4%B0%E5%9C%96%E6%96%87%E6%94%BB%E7%95%A5-part4
2017年2月22日 星期三
(js css)getDefaultStyling
var getDefaultStyling = function(tagName){
if(!tagName) tagName = "dummy-tag-name";
// Create dummy iframe
var iframe = document.createElement("iframe");
document.body.appendChild(iframe);
// Create element within the iframe's document
var iframeDocument = iframe.contentDocument;
var targetElement = iframeDocument.createElement(tagName);
iframeDocument.body.appendChild(targetElement);
// Grab styling (CSSStyleDeclaration is live, and all values become "" after element removal)
var styling = iframe.contentWindow.getComputedStyle(targetElement);
var clonedStyling = {};
for(var i = 0, len = styling.length; i < len; i++){
var property = styling[i];
clonedStyling[i] = property;
clonedStyling[property] = styling[property];
}
// Remove iframe
document.body.removeChild(iframe);
// Return cloned styling
return clonedStyling;
};
var getUniqueUserStyling = function(element){
var allStyling = window.getComputedStyle(element);
var defaultStyling = getDefaultStyling(element.tagName);
var userStyling = {};
for(var i = 0, len = allStyling.length; i < len; i++){
var property = allStyling[i];
var value = allStyling[property];
var defaultValue = defaultStyling[property];
if(value != defaultValue){
userStyling[property] = value;
}
}
return userStyling;
};
if(!tagName) tagName = "dummy-tag-name";
// Create dummy iframe
var iframe = document.createElement("iframe");
document.body.appendChild(iframe);
// Create element within the iframe's document
var iframeDocument = iframe.contentDocument;
var targetElement = iframeDocument.createElement(tagName);
iframeDocument.body.appendChild(targetElement);
// Grab styling (CSSStyleDeclaration is live, and all values become "" after element removal)
var styling = iframe.contentWindow.getComputedStyle(targetElement);
var clonedStyling = {};
for(var i = 0, len = styling.length; i < len; i++){
var property = styling[i];
clonedStyling[i] = property;
clonedStyling[property] = styling[property];
}
// Remove iframe
document.body.removeChild(iframe);
// Return cloned styling
return clonedStyling;
};
var getUniqueUserStyling = function(element){
var allStyling = window.getComputedStyle(element);
var defaultStyling = getDefaultStyling(element.tagName);
var userStyling = {};
for(var i = 0, len = allStyling.length; i < len; i++){
var property = allStyling[i];
var value = allStyling[property];
var defaultValue = defaultStyling[property];
if(value != defaultValue){
userStyling[property] = value;
}
}
return userStyling;
};
2017年2月17日 星期五
(js)jq.transition
http://ricostacruz.com/jquery.transit/
https://www.npmjs.com/package/jquery.transition
https://github.com/louisremi/jquery.transition.js/
https://www.npmjs.com/package/jquery.transition
https://github.com/louisremi/jquery.transition.js/
2017年2月13日 星期一
(js)promise小問題修正版
////////////////////////////////////////////////////////////////////////////////
/**
* 2017/2/14
*
* fix from https://github.com/ygm125/promise
*/
////////////////////////////////////////////////////////////////////////////////
(function(exports) {
if (typeof window === 'object') {
// is window
exports._Promise = Promise;
try {
new Promise();
return;
} catch (e) {
exports.Promise = Promise;
}
} else if (typeof module === 'object' && module.exports) {
// is node.js
module.exports = Promise;
} else {
return;
}
////////////////////////////////////////////////////////////////////////////
var PENDING = undefined; // 事件仍在處理狀態
var FULFILLED = 1; // 事件已處理完成
var REJECTED = 2; // 事件已處理完,但拋出 reject
/**
* @param {string} name 測試用,命名以方便與 then() 生成的 promise做區分
*/
function Promise(_resolver, name, parent) {
// debugger;
if (typeof _resolver !== 'function') {
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
}
if (!(this instanceof Promise)) {
// 當作函式用的話
return new Promise(_resolver, name);
}
/* ---------------------------------- */
// for test 方便辨別 promise 身份
this._parent = (parent instanceof Promise ? parent : undefined); // 紀錄上一個 promise
this.guid = Promise.prototype.guid++; // for test
this._name = (name ? (name + '(' + this.guid + ')') : this.guid); // for test
/* ---------------------------------- */
var promise = this;
promise._value;
promise._reason;
promise._status = PENDING;
/* ---------------------------------- */
promise._resolves = []; // then([0])的工作都放這
promise._rejects = []; // then([1])的工作都放這
/* ---------------------------------- */
try {
// 處理 promise 程序拋出 error
_resolver(resolve, reject);
} catch (error) {
reject(error);
}
/* ================================== */
function resolve(value) {
promise._status = FULFILLED;
reportFinshJob.call(promise, value);
}
/* ---------------------------------- */
function reject(reason) {
promise._status = REJECTED;
reportFinshJob.call(promise, reason);
}
};
/* ====================================================================== */
Promise.prototype.guid = 0; // for test
////////////////////////////////////////////////////////////////////////////
/**
* very important
*/
Promise.prototype.then = function(onFulfilled, onRejected) {
// debugger;
var promise = this;
// 每次返回一个promise,保证是可thenable的
return new Promise(function(resolve, reject) {
// debugger;
if (promise._status === PENDING) {
promise._resolves.push(callback);
promise._rejects.push(errback);
} else if (promise._status === FULFILLED) { // 状态改变后的then操作,立刻执行
callback(promise._value);
} else if (promise._status === REJECTED) {
errback(promise._reason);
}
/* ============================================ */
function callback(value) {
var ret;
try {
/**
* 修改此處
*
* 處理 then.onFulfilled() 萬一出錯
*/
ret = (typeof onFulfilled === 'function' && onFulfilled(value));
} catch (error) {
reject(error);
}
ret = ret || value;
if (isThenable(ret)) {
ret.then(function(value) {
resolve(value);
}, function(reason) {
reject(reason);
});
} else {
resolve(ret);
}
}
/* ---------------------------------------- */
function errback(reason) {
var _reason;
try {
_reason = (typeof onRejected === 'function' && onRejected(reason));
} catch (error) {
_reason = error;
} finally {
_reason = _reason || reason;
reject(_reason);
}
}
}, 'then', promise);
};
/* ====================================================================== */
Promise.prototype.catch = function(onRejected) {
return this.then(undefined, onRejected)
};
/* ====================================================================== */
Promise.prototype.delay = function(ms, val) {
return this.then(function(ori) {
return Promise.delay(ms, val || ori);
})
};
/* ====================================================================== */
Promise.delay = function(ms, val) {
return Promise(function(resolve, reject) {
setTimeout(function() {
resolve(val);
}, ms);
})
};
/* ====================================================================== */
Promise.resolve = function(arg) {
return Promise(function(resolve, reject) {
resolve(arg)
}, 'resolve');
};
/* ====================================================================== */
Promise.reject = function(arg) {
return Promise(function(resolve, reject) {
reject(arg)
}, 'reject');
};
/* ====================================================================== */
Promise.all = function(promises) {
if (!isArray(promises)) {
throw new TypeError('You must pass an array to all.');
}
return Promise(function(resolve, reject) {
var i = 0,
result = [],
len = promises.length,
count = len
function resolver(index) {
return function(value) {
resolveAll(index, value);
};
}
function rejecter(reason) {
reject(reason);
}
function resolveAll(index, value) {
result[index] = value;
if (--count == 0) {
resolve(result)
}
}
for (; i < len; i++) {
promises[i].then(resolver(i), rejecter);
}
}, 'all');
};
/* ====================================================================== */
Promise.race = function(promises) {
if (!isArray(promises)) {
throw new TypeError('You must pass an array to race.');
}
return Promise(function(resolve, reject) {
var i = 0,
len = promises.length;
function resolver(value) {
resolve(value);
}
function rejecter(reason) {
reject(reason);
}
for (; i < len; i++) {
promises[i].then(resolver, rejecter);
}
}, 'race');
};
////////////////////////////////////////////////////////////////////////////
function isArray(obj) {
return Object.prototype.toString.call(obj) === "[object Array]";
};
/* ====================================================================== */
/**
* 若對象含有.then()
*/
function isThenable(obj) {
return (obj && typeof obj['then'] == 'function');
};
/* ====================================================================== */
/**
* promise.resolve() || promise.reject() 後要做的事
*/
function reportFinshJob(value) {
// debugger;
var promise = this;
publish.call(promise, value);
};
/* ====================================================================== */
/**
* 執行(._resolves)or(_rejects)
*/
function publish(val) {
var promise = this,
fn,
st = promise._status === FULFILLED;
// 任務隊列
var queue = promise[st ? '_resolves' : '_rejects'];
while (fn = queue.shift()) {
// 裡面是 callback || errback 包住下一個 promise
val = fn.call(promise, val) || val;
}
promise[st ? '_value' : '_reason'] = val;
promise._resolves = [];
promise._rejects = [];
}
})(this || {});
/**
* 2017/2/14
*
* fix from https://github.com/ygm125/promise
*/
////////////////////////////////////////////////////////////////////////////////
(function(exports) {
if (typeof window === 'object') {
// is window
exports._Promise = Promise;
try {
new Promise();
return;
} catch (e) {
exports.Promise = Promise;
}
} else if (typeof module === 'object' && module.exports) {
// is node.js
module.exports = Promise;
} else {
return;
}
////////////////////////////////////////////////////////////////////////////
var PENDING = undefined; // 事件仍在處理狀態
var FULFILLED = 1; // 事件已處理完成
var REJECTED = 2; // 事件已處理完,但拋出 reject
/**
* @param {string} name 測試用,命名以方便與 then() 生成的 promise做區分
*/
function Promise(_resolver, name, parent) {
// debugger;
if (typeof _resolver !== 'function') {
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
}
if (!(this instanceof Promise)) {
// 當作函式用的話
return new Promise(_resolver, name);
}
/* ---------------------------------- */
// for test 方便辨別 promise 身份
this._parent = (parent instanceof Promise ? parent : undefined); // 紀錄上一個 promise
this.guid = Promise.prototype.guid++; // for test
this._name = (name ? (name + '(' + this.guid + ')') : this.guid); // for test
/* ---------------------------------- */
var promise = this;
promise._value;
promise._reason;
promise._status = PENDING;
/* ---------------------------------- */
promise._resolves = []; // then([0])的工作都放這
promise._rejects = []; // then([1])的工作都放這
/* ---------------------------------- */
try {
// 處理 promise 程序拋出 error
_resolver(resolve, reject);
} catch (error) {
reject(error);
}
/* ================================== */
function resolve(value) {
promise._status = FULFILLED;
reportFinshJob.call(promise, value);
}
/* ---------------------------------- */
function reject(reason) {
promise._status = REJECTED;
reportFinshJob.call(promise, reason);
}
};
/* ====================================================================== */
Promise.prototype.guid = 0; // for test
////////////////////////////////////////////////////////////////////////////
/**
* very important
*/
Promise.prototype.then = function(onFulfilled, onRejected) {
// debugger;
var promise = this;
// 每次返回一个promise,保证是可thenable的
return new Promise(function(resolve, reject) {
// debugger;
if (promise._status === PENDING) {
promise._resolves.push(callback);
promise._rejects.push(errback);
} else if (promise._status === FULFILLED) { // 状态改变后的then操作,立刻执行
callback(promise._value);
} else if (promise._status === REJECTED) {
errback(promise._reason);
}
/* ============================================ */
function callback(value) {
var ret;
try {
/**
* 修改此處
*
* 處理 then.onFulfilled() 萬一出錯
*/
ret = (typeof onFulfilled === 'function' && onFulfilled(value));
} catch (error) {
reject(error);
}
ret = ret || value;
if (isThenable(ret)) {
ret.then(function(value) {
resolve(value);
}, function(reason) {
reject(reason);
});
} else {
resolve(ret);
}
}
/* ---------------------------------------- */
function errback(reason) {
var _reason;
try {
_reason = (typeof onRejected === 'function' && onRejected(reason));
} catch (error) {
_reason = error;
} finally {
_reason = _reason || reason;
reject(_reason);
}
}
}, 'then', promise);
};
/* ====================================================================== */
Promise.prototype.catch = function(onRejected) {
return this.then(undefined, onRejected)
};
/* ====================================================================== */
Promise.prototype.delay = function(ms, val) {
return this.then(function(ori) {
return Promise.delay(ms, val || ori);
})
};
/* ====================================================================== */
Promise.delay = function(ms, val) {
return Promise(function(resolve, reject) {
setTimeout(function() {
resolve(val);
}, ms);
})
};
/* ====================================================================== */
Promise.resolve = function(arg) {
return Promise(function(resolve, reject) {
resolve(arg)
}, 'resolve');
};
/* ====================================================================== */
Promise.reject = function(arg) {
return Promise(function(resolve, reject) {
reject(arg)
}, 'reject');
};
/* ====================================================================== */
Promise.all = function(promises) {
if (!isArray(promises)) {
throw new TypeError('You must pass an array to all.');
}
return Promise(function(resolve, reject) {
var i = 0,
result = [],
len = promises.length,
count = len
function resolver(index) {
return function(value) {
resolveAll(index, value);
};
}
function rejecter(reason) {
reject(reason);
}
function resolveAll(index, value) {
result[index] = value;
if (--count == 0) {
resolve(result)
}
}
for (; i < len; i++) {
promises[i].then(resolver(i), rejecter);
}
}, 'all');
};
/* ====================================================================== */
Promise.race = function(promises) {
if (!isArray(promises)) {
throw new TypeError('You must pass an array to race.');
}
return Promise(function(resolve, reject) {
var i = 0,
len = promises.length;
function resolver(value) {
resolve(value);
}
function rejecter(reason) {
reject(reason);
}
for (; i < len; i++) {
promises[i].then(resolver, rejecter);
}
}, 'race');
};
////////////////////////////////////////////////////////////////////////////
function isArray(obj) {
return Object.prototype.toString.call(obj) === "[object Array]";
};
/* ====================================================================== */
/**
* 若對象含有.then()
*/
function isThenable(obj) {
return (obj && typeof obj['then'] == 'function');
};
/* ====================================================================== */
/**
* promise.resolve() || promise.reject() 後要做的事
*/
function reportFinshJob(value) {
// debugger;
var promise = this;
publish.call(promise, value);
};
/* ====================================================================== */
/**
* 執行(._resolves)or(_rejects)
*/
function publish(val) {
var promise = this,
fn,
st = promise._status === FULFILLED;
// 任務隊列
var queue = promise[st ? '_resolves' : '_rejects'];
while (fn = queue.shift()) {
// 裡面是 callback || errback 包住下一個 promise
val = fn.call(promise, val) || val;
}
promise[st ? '_value' : '_reason'] = val;
promise._resolves = [];
promise._rejects = [];
}
})(this || {});
(js)jquery.Deferred() 序列的用法
看三小賤人,不要臉的賤畜生
/**
* 取得非同步工作
*/
function getAsyncTask(def) {
if (typeof getAsyncTask.index === 'undefined') {
getAsyncTask.index = 0;
}
return function() {
// debugger
console.log('mission(%d) begin', getAsyncTask.index);
setTimeout(function() {
// debugger;
console.log('mission(%d) finish', getAsyncTask.index++);
// important,通知工作結束
def.resolve();
}, (1000 + Math.random() * 2000));
};
}
////////////////////////////////////////////////////////////////////////
function doIt_1() {
// 對列
job_1().then(job_2).then(job_3).then(job_4);
/* ============================================================== */
function job_1() {
var def = $.Deferred();
var fun = getAsyncTask(def);
fun();
return def.promise();
}
/* ============================================================== */
function job_2() {
var def = $.Deferred();
var fun = getAsyncTask(def);
fun();
return def.promise();
}
/* ============================================================== */
function job_3() {
var def = $.Deferred();
var fun = getAsyncTask(def);
fun();
return def.promise();
}
/* ============================================================== */
function job_4() {
var def = $.Deferred();
var fun = getAsyncTask(def);
fun();
return def.promise();
}
/* ============================================================== */
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Promise.series用法
function job1() {
return new Promise(function (res, rej) {
console.log('p_1 start');
setTimeout(function () {
console.log('p_1 end');
res();
}, 2000);
});
}
function job2() {
return new Promise(function (res, rej) {
console.log('p_2 start');
setTimeout(function () {
console.log('p_2 end');
res();
}, 2000);
});
}
function job3() {
return new Promise(function (res, rej) {
console.log('p_3 start');
setTimeout(function () {
console.log('p_3 end');
res();
}, 2000);
});
}
/* ================================================ */
job1().then(function () {
return job2();
}).then(function () {
return job3();
});
(js)jquery.defferd用法
var mainObj;
function job_1() {
mainObj = runAsync_1();
// deferred.then()
mainObj.then(function(data) {
alert(data);
});
}
function job_2() {
mainObj = runAsync_2();
// deferred.promise().then()
mainObj.then(function(data) {
alert(data);
});
}
function job_3() {
mainObj = runAsync_2();
// 平行處理多個 deferred
$.when(mainObj).then(function(data) {
alert(data);
});
}
/* ================================================================== */
/**
* 返回 deferred
*/
function runAsync_1() {
var def = $.Deferred();
//做一些異步操作
setTimeout(function() {
console.log('執行完成');
def.resolve('隨便什麼數據');
}, 2000);
return def;
};
/**
* 返回 deferred.promise()
*/
function runAsync_2() {
var def = $.Deferred();
//做一些異步操作
setTimeout(function() {
console.log('執行完成');
def.resolve('隨便什麼數據');
}, 2000);
return def.promise();
};
function job_1() {
mainObj = runAsync_1();
// deferred.then()
mainObj.then(function(data) {
alert(data);
});
}
function job_2() {
mainObj = runAsync_2();
// deferred.promise().then()
mainObj.then(function(data) {
alert(data);
});
}
function job_3() {
mainObj = runAsync_2();
// 平行處理多個 deferred
$.when(mainObj).then(function(data) {
alert(data);
});
}
/* ================================================================== */
/**
* 返回 deferred
*/
function runAsync_1() {
var def = $.Deferred();
//做一些異步操作
setTimeout(function() {
console.log('執行完成');
def.resolve('隨便什麼數據');
}, 2000);
return def;
};
/**
* 返回 deferred.promise()
*/
function runAsync_2() {
var def = $.Deferred();
//做一些異步操作
setTimeout(function() {
console.log('執行完成');
def.resolve('隨便什麼數據');
}, 2000);
return def.promise();
};
2017年2月10日 星期五
(js)Array.prototype.indexOf()
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(searchElement, fromIndex) {
var k;
// 1. Let o be the result of calling ToObject passing
// the this value as the argument.
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
// 2. Let lenValue be the result of calling the Get
// internal method of o with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = o.length >>> 0;
// 4. If len is 0, return -1.
if (len === 0) {
return -1;
}
// 5. If argument fromIndex was passed let n be
// ToInteger(fromIndex); else let n be 0.
var n = fromIndex | 0;
// 6. If n >= len, return -1.
if (n >= len) {
return -1;
}
// 7. If n >= 0, then Let k be n.
// 8. Else, n<0, Let k be len - abs(n).
// If k is less than 0, then let k be 0.
k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
// 9. Repeat, while k < len
while (k < len) {
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the
// HasProperty internal method of o with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
// i. Let elementK be the result of calling the Get
// internal method of o with the argument ToString(k).
// ii. Let same be the result of applying the
// Strict Equality Comparison Algorithm to
// searchElement and elementK.
// iii. If same is true, return k.
if (k in o && o[k] === searchElement) {
return k;
}
k++;
}
return -1;
};
}
Array.prototype.indexOf = function(searchElement, fromIndex) {
var k;
// 1. Let o be the result of calling ToObject passing
// the this value as the argument.
if (this == null) {
throw new TypeError('"this" is null or not defined');
}
var o = Object(this);
// 2. Let lenValue be the result of calling the Get
// internal method of o with the argument "length".
// 3. Let len be ToUint32(lenValue).
var len = o.length >>> 0;
// 4. If len is 0, return -1.
if (len === 0) {
return -1;
}
// 5. If argument fromIndex was passed let n be
// ToInteger(fromIndex); else let n be 0.
var n = fromIndex | 0;
// 6. If n >= len, return -1.
if (n >= len) {
return -1;
}
// 7. If n >= 0, then Let k be n.
// 8. Else, n<0, Let k be len - abs(n).
// If k is less than 0, then let k be 0.
k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
// 9. Repeat, while k < len
while (k < len) {
// a. Let Pk be ToString(k).
// This is implicit for LHS operands of the in operator
// b. Let kPresent be the result of calling the
// HasProperty internal method of o with argument Pk.
// This step can be combined with c
// c. If kPresent is true, then
// i. Let elementK be the result of calling the Get
// internal method of o with the argument ToString(k).
// ii. Let same be the result of applying the
// Strict Equality Comparison Algorithm to
// searchElement and elementK.
// iii. If same is true, return k.
if (k in o && o[k] === searchElement) {
return k;
}
k++;
}
return -1;
};
}
(js)取得css屬性(包含style)
css = getComputedStyle(dom, null) || dom.currentStyle;
// 取得預設 css 值,即使已經有設定樣式
var defaultCss = getDefaultComputedStyle(dom, null);
// 取得預設 css 值,即使已經有設定樣式
var defaultCss = getDefaultComputedStyle(dom, null);
2017年2月9日 星期四
(js)Object.create
function create(prototype){
var Temp = function () {};
if (arguments.length > 1) {
throw Error('Second argument not supported');
}
if (prototype !== Object(prototype) && prototype !== null) {
throw TypeError('Argument must be an object or null');
}
if (prototype === null) {
throw Error('null [[Prototype]] not supported');
}
Temp.prototype = prototype;
var result = new Temp();
// 清除
Temp.prototype = null;
return result;
}
var Temp = function () {};
if (arguments.length > 1) {
throw Error('Second argument not supported');
}
if (prototype !== Object(prototype) && prototype !== null) {
throw TypeError('Argument must be an object or null');
}
if (prototype === null) {
throw Error('null [[Prototype]] not supported');
}
Temp.prototype = prototype;
var result = new Temp();
// 清除
Temp.prototype = null;
return result;
}
2017年2月3日 星期五
(css)因應不同尺寸下css的各種設定
方法一>>
<link rel="stylesheet" href="" media="only screen and (min-width:600px) and (max-width:979px)">
方法二>>
@media (min-width: 768px) and (max-width: 979px) {
}
<link rel="stylesheet" href="" media="only screen and (min-width:600px) and (max-width:979px)">
方法二>>
@media (min-width: 768px) and (max-width: 979px) {
}
訂閱:
文章 (Atom)