【JavaScript框架封裝】公共框架的封裝
版權宣告:本文為博主原創文章,未經博主允許不得轉載。更多學習資料請訪問我愛科技論壇:www.52tech.tech https://blog.csdn.net/m0_37981569/article/details/81056006
/* * @Author: 我愛科技論壇 * @Time: 20180706 * @Desc: 實現一個類似於JQuery功能的框架
// 公共框架
// 種子模組:名稱空間、物件擴充套件、陣列化、型別的判定、domReady機制,無衝突處理
(function (xframe) {
// 需要參與鏈式訪問的(必須使用prototype的方式來給物件擴充方法)
xframe.extend({
each: function (fn) {
var i = 0,
len = this.length;
for (; i < len; i++) {
// call第一個引數傳遞的實際上就是this的執行,後面的引數就是目標函式fn需要傳遞的引數(可省略)
// this[i] 裡面的取值方式類似於json取值,每一個引數儲存了選擇器獲取的所有的nodeList元素集合中的一個元素
fn.call(this[i]);
}
return this;
}
});
// 不需要參與鏈式訪問的
/*公共部分*/
xframe.extend(xframe, {});
/*字串處理模組*/
xframe.extend(xframe, {
/*
* 下面的這幾個都會用到正規表示式,會在後面補充
* camelCase函式的功能就是將形如background-color轉化為駝峰表示法:backgroundColor
* */
camelCase: function (str) {
// all: -c, letter: c
return str.replace(/-(w)/g, function (all, letter) {
// 把所有的字母都轉換為大寫的狀態
return letter.toUpperCase();
});
},
/**
* 去掉左邊的空格 str = ` ()`
* @param str
* @returns {*}
*/
ltrim: function (str) {
/*
^ :表示以XX開頭
s: 表示空格
*: 表示匹配零個或者多個
g: 表示匹配全部,如果沒有的話預設只會匹配一個
(^s*): 表示以空格開頭的一個或者多個字元
str.replace(, ``): 替換……
----------------------------------------------------[其他用法歸納]-------------------------------------
^, $: 匹配字串開始,結束的位置 eg:
g, i:匹配所有,不區分大小寫的字串; eg: /a/g, /a/i
*, +, ?: 匹配任意次數, 匹配前面的字元一次或者多次, 0次或者1次
[] : 匹配一個字符集合; eg: [a-z]所有小寫字母的集合, [0-9]所有數字的集合
eg: [a-zA-Z]所有大小寫字母的集合
脫字元^: 匹配任何不在該集合中的字元,與上面的用法正好相反
{}: 指定重複前面的一個字元多少遍 eg:{N} 重複n遍
eg:{n, m}重複n-m遍
eg: {n, }至少重複n遍
eg:{,m}至多重複m遍
// 【熟記:同類記憶法】
s: 表示空格:包括空格、換行、回車、tab,等價於[
f]
S: 匹配非空格字元,等價於[^
f]
d: 表示十進位制數字,等價於[0-9]
D: 匹配一個非數字字元, 等價於[^0-9]
w(小寫): 表示字母或者數字,等價於[a-zA-Z0-9]
W: 非字母且非數字,與w相反,等價於:[^a-zA-Z0-9]*
* */
return str.replace(/(^s*)/g, ``);
},
/* 去掉右邊的空格, str = `() `
* @param str
*/
rtrim: function (str) {
return str.replace(/(s*$)/g, ``);
},
/**
* 用於去掉兩邊的空格(去掉所有的空格) str =` () `
* @param str
* @returns {*}
*/
trimOld: function (str) {
return str.replace(/(s*$)/g, ``);
},
/**
* 【使用模板來實現一個簡單的資料繫結】
* 實現簡單的資料繫結: @(name), @(sex)
* data: var user = {name : `xiugang`, role, `鑽石會員`}
* str: = `歡迎@(name), 等級:@(role)光臨本站!`;
* @param str 原始的資料格式
* @param data 需要繫結的資料物件,是一個json格式的資料, json = {name : `xiuxiu`, age : 18}
* @returns {*}
*/
formateString: function (str, data) {
// 使用後面的值去替換掉前面的值
// 細節分析:((w+))使用括號匹配的值在JavaScript中實際上就是一個$1, 把這個引數傳給match
// (w+) 第二個括號實際上匹配到的就是一個$2, 把這個引數傳給key
// match: @(name), @(age), @(sex)
// key: name, age, sex
return str.replace(/@((w+))/g, function (match, key) {
// 先判斷有沒有匹配到相應的字串
// 找到@()開始的字串, 使用資料域中的資料去替換
// 如果json資料data裡面麼有找到相應的data[key]資料,返回的實際上就是一個空的字串
return typeof data[key] === `undefined` ? `` : data[key];
});
},
/**
* @param str
* @returns {*}
*/
trimLeft: function (str) {
return str.replace(/^s*/g, ``);
},
/**
* @param str
* @returns {*}
*/
trimRight: function (str) {
return str.replace(/s*$/g, ``);
},
/**
* 去掉所有的空格(兩邊的空格), 可以針對任意格式的字串
* 先去掉左邊的空格,然後去掉右邊的空格
* @param str
* @returns {*}
*/
trim: function (str) {
// var regx = `/^s*s*$/g`;
// return str.replace(regx, ``);
// | 表示或的意思, 也就是滿足| 左邊的也成立, 滿足 | 右面的也成立
// (^s*) 表示的就是以0個空格或者多個空格開頭
// (s*$) 的意思就是, 以0個空格或者多個空格結尾
// /…/g 是正規表示式的屬性, 表示全文匹配, 而不是找到一個就停止
return str.replace(/(^s*)|(s*$)/g, "");
//return this.trimRight(this.trimLeft(str));
},
/**
* 傳送一個ajax請求
* @param url 請求的URL地址資訊
* @param fn, 請求成功的回撥函式
*/
ajax: function (url, fn) {
// 建立一個XMLHTTPRequest物件
var xhr = createXHR();
// 每當 readyState 改變時,就會觸發 onreadystatechange 事件。
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
// 接受到響應之後,第一步檢查status屬性,為200則表明成功,此時responseText已經準備就緒;
// 為304表明請求資源未被修改,可以直接使用瀏覽器中的快取版本。
if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
fn(xhr.responseText);
} else {
alert(`錯誤的檔案!`);
}
}
};
// 定義請求引數, 對於指定的url傳送一個get請求
xhr.open(`get`, url, true);
// 傳送請求
// 第三個引數:指示請求使用應該非同步地執行。
// 如果這個引數是 false,請求是同步的,後續對 send() 的呼叫將阻塞,直到響應完全接收。
// 如果這個引數是 true 或省略,請求是非同步的,且通常需要一個 onreadystatechange 事件控制程式碼。
xhr.send();
/**
* 建立一個XHR
*/
function createXHR() {
//本函式來自於《JavaScript高階程式設計 第3版》第21章
if (typeof XMLHttpRequest != "undefined") {
return new XMLHttpRequest();
} else if (typeof ActiveXObject != "undefined") {
// arguments.callee用於指向他的回撥函式
if (typeof arguments.callee.activeXString != "string") {
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0",
"MSXML2.XMLHttp"
],
i, len;
for (i = 0, len = versions.length; i < len; i++) {
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (ex) {
//skip
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
} else {
throw new Error("No XHR object available.");
}
}
},
/**
* json轉換為字串
* @param json
* @returns {string}
*/
json2String: function (json) {
return JSON.stringify(json);
},
/**
* 字串轉換為json
* @param str
* @returns {any}
*/
string2Json: function (str) {
return eval(str);
}
});
/*陣列相關*/
xframe.extend(xframe, {
/**
* 將一個陣列清空,並返回陣列的引用
* 只需要把陣列的元素置空為0即可
* @return {xframe}
*/
clear: function () {
this.length = 0;
return this;
},
/**
* 返回陣列的第0個元素
* @return {*}
*/
first: function () {
return this[0];
},
/**
* 返回陣列的最後一個元素
* @return {*}
*/
last: function () {
return this[this.length - 1];
},
/**
* 計算一個陣列的大小尺寸
* @return {number|*}
*/
size: function () {
return this.length;
},
cacl: function (arr, callback) {
var ret;
for (var i = 0; i < arr.length; i++) {
// 專門用於處理每一項的計算機過程
ret = callback(arr[i], ret);
}
return ret;
},
/**
* 對陣列裡面的所有元素求和
* @return {*}
*/
sum: function () {
// 1. 正常寫法
var ret;
for (var i = 0; i < this.length; i++) {
ret = ret + this[i];
}
return ret;
},
max: function () {
},
min: function () {
},
avg: function () {
},
intersect: function () {
},
union: function () {
},
diff: function () {
},
unique: function () {
},
forEach: function () {
},
map: function () {
},
filter: function () {
},
every: function () {
},
some: function () {
},
reduce: function () {
},
reduceRight: function () {
},
indexOf: function () {
},
lastIndexOf: function () {
},
enhanceUnique: function () {
},
without: function () {
},
flatten: function () {
},
random: function () {
},
removeAt: function () {
},
contains: function () {
}
});
/*Math*/
xframe.extend(xframe, {
random: function () {
}
});
/*資料型別檢驗*/
xframe.extend(xframe, {
// 鴨子型別(duck typing)如果它走起路來像鴨子,叫起來也是鴨子,那麼它就是鴨子。
// 只關注物件的行為,不關注物件本身面向介面編型 ,而不是面向實現程式設計,是設計模式中最重要的思想。
// 【理解】:一個物件有效的語義,不是由整合自特定的類或實現特定的介面, 而是由當前方法和屬性的集合決定的!!!
isNumber: function (val) {
// 如果這個數字是有限的話, 而且是數字型別
return (typeof val === `number` && isFinite(val)) && (Object.prototype.toString.call(val) === `[object Number]`);
},
/***
* 判斷一個變數是不是Boolean型別
* @param val
* @returns {boolean}
*/
isBoolean: function (val) {
return (typeof val === `boolean`) && (Object.prototype.toString.call(val) === `[object Boolean]`);
},
/**
* 判斷一個變數是不是字串型別
* @param val
* @returns {boolean}
*/
isString: function (val) {
return (typeof val === `string`) && (Object.prototype.toString.call(val) === `[object String]`);
},
/**
* 判斷一個變數是不是undefined
* @param val
* @returns {boolean}
*/
isUndefined: function (val) {
// oid 0 is a correct and standard way to produce undefined.
return (val === void 0) || (typeof val === `undefined`) && (Object.prototype.toString.call(val) === `[object Undefined]`);
},
/**
* 判斷一個變數是不是為空
* @param val
* @returns {boolean}
*/
isNull: function (val) {
return (val === null) && (Object.prototype.toString.call(val) === `[object Null]`);
},
/**
* 檢測
* @param obj
* @returns {*}
*/
isNaN: function (val) {
// 只要這個數字通過判斷是不是和他自身相同或者使用typef的方式去檢測
return val !== val;
},
/**
* 判斷一個變數是不是一個物件型別
* @param val
* @returns {boolean}
*/
isObject: function (val) {
if (val !== null && val !== undefined) {
if ((typeof val === `object`) && (Object.prototype.toString.call(val))) {
return true;
}
}
return false;
},
/**
* 判斷一個物件是不是陣列物件
* @param val
* @returns {boolean|void|string}
*/
isArray: function (val) {
// 判斷上不是一個陣列的先判斷這個陣列物件是不是為空, 因為如果val為空的話,就是val.constructor這個屬性實際上是沒有的,error
if (val !== null || typeof val !== "undefined") {
// 注意在使用constructor判斷資料型別的時候比較的實際上是他的原型物件的constructor屬性, 這個屬性指向的實際上是這個變數的原型物件
return (val.constructor === Array) && (Object.prototype.toString.call(val));
}
return false;
}
});
/*陣列化:arguments, document.forms, document.getElementsByName, document.getElementsByTagName()*/
xframe.extend(xframe, {
/**
* 把一個偽陣列轉換為一個新的陣列
* 實現思路: 取出偽陣列中的每一個元素, 然後把取出來的這些元素重新放入到一個新的陣列裡面去!!!
* @param start
* @param end
* @returns {Array}
*/
toArray: function (start, end) {
var result = [];
var start = start || 0,
// 這裡的this指向呼叫的物件,使用了call之後, 改變了this的指向, 指向傳進來的物件(外邊必須要修改this的指向)
// 如果外邊不修改this的指向,這裡的this預設指向的是xframe這個框架物件
end = end || this.length;
for (var i = start; i < end; i++) {
result.push(this[i]);
}
return result;
},
/**
* 方法二: 直接把一個偽陣列轉換為JavaScript中的一個陣列物件
* @param obj
* @returns {T[]}
*/
slice: function (obj) {
return Array.prototype.slice.apply(obj);
}
});
/*domReady的實現*/
xframe.extend(xframe, {
//arguments 的主要用途是儲存函式引數, 但這個物件還有一個名叫 callee 的屬性,該屬性是一個指標,指向擁有這個 arguments 物件的函式
/**
* 實現一個domReady方法:所有元素都載入完畢之後一個回撥函式
* @param domElement
* @param fn
*/
onDOMReady: function (fn) {
if (document.addEventListener) {
// W3C組織: 如果傳過來的是一個DOM元素的話,就直接對這個DOM元素新增監聽, 否則,就對整個document新增事件監聽
document.addEventListener(`DOMContentLoaded`, fn, false);
} else {
// IE瀏覽器
IEContentLoaded(fn);
}
/**
* 微軟的IE瀏覽器的處理方法
* @param fn
* @constructor
*/
function IEContentLoaded(fn) {
// 定義需要的全域性變數
var done = false, document = window.document;
// 這個函式只會在所有的DOM節點樹建立完畢的時候才會繼續向下執行
var init = (function () {
if (!done) {
console.log(`done……`);
// 如果DOM樹建立完畢的話
done = true;
fn();
}
})();
/*
使用這個立即函式來呼叫IE瀏覽器的內建函式實現domReady的功能
*/
(function () {
try {
// DOM樹在未建立完畢之後呼叫 doScroll的話,會丟擲錯誤
document.documentElement.doScroll(`left`);
} catch (err) {
// 延遲1秒之後再次執行這個函式, 形成一個函式遞迴呼叫的功能【回撥函式】
// clllee是一個函式指標,指向的是擁有這個arguments物件的函式, 從而實現再次呼叫這個函式
setTimeout(arguments.callee, 1);
return;
}
// 如果沒有錯誤的話,表示DOM樹已經完全建立完畢, 此時開始執行使用者的回撥函式
init();
})();
// 監聽document的載入狀態(DOM載入的過程中會不斷回撥這個函式)
document.onreadystatechange = function () {
console.log(`onreadystatechange……`);
if (document.readyState === `complete`) {
console.log(`complete……`);
// 如果載入完成的話
document.onreadystatechange = null;
init();
}
}
}
}
});
})(xframe);
相關文章
- 【JavaScript框架封裝】實現一個類似於JQuery的動畫框架的封裝JavaScript框架封裝jQuery動畫
- 【JavaScript框架封裝】實現一個類似於JQuery的CSS樣式框架的封裝JavaScript框架封裝jQueryCSS
- 封裝框架的實踐封裝框架
- Flutter 基於Bloc框架的封裝FlutterBloC框架封裝
- Flutter 網路請求框架封裝Flutter框架封裝
- 039.CI4框架CodeIgniter,封裝Model模型繫結資料庫的封裝框架封裝模型資料庫
- 【JavaScript框架封裝】使用Prototype給Array,String,Function物件的方法擴充JavaScript框架封裝Function物件
- 封裝定時任務框架的正確方式封裝框架
- 關於網路框架設計封裝的扯淡框架封裝
- JavaScript 模組封裝JavaScript封裝
- 使用APICloud AVM框架封裝通訊錄元件APICloud框架封裝元件
- 使用APICloud AVM框架封裝app日曆元件APICloud框架封裝APP元件
- 【JavaScript框架封裝】JavaScript中的文字字串的轉義和反轉義的實現JavaScript框架封裝字串
- 基於gin框架封裝的web專案骨架goskeleton框架封裝WebGo
- 封裝一個在react上更易用的redux框架封裝ReactRedux框架
- web自動化框架—BasePage 類的簡單封裝Web框架封裝
- 【封裝小技巧】is 系列方法的封裝封裝
- 【封裝那些事】 缺失封裝封裝
- Dapper的封裝、二次封裝、官方擴充套件包封裝,以及ADO.NET原生封裝APP封裝套件
- Retrofit + Kotlin + MVVM 的網路請求框架的封裝嘗試KotlinMVVM框架封裝
- Disruptor 高效能併發框架二次封裝框架封裝
- python自動化測試框架,封裝方法方式Python框架封裝
- Flutter 熱門網路請求框架Dio的簡單封裝Flutter框架封裝
- 封裝封裝
- 基於spring boot框架進行二次封裝,微型框架編寫思路Spring Boot框架封裝
- 基於javascript的拖拽類封裝^o^JavaScript封裝
- 【vue系列】封裝公共彈窗元件的正確方式Vue封裝元件
- JavaScript物件導向之一(封裝)JavaScript物件封裝
- 封裝、許可權修飾符、封裝的案例封裝
- 【封裝小技巧】列表處理函式的封裝封裝函式
- Flutter 封裝:富文字 RichText 極簡封裝Flutter封裝
- 封裝介面封裝
- ajax 封裝封裝
- axios封裝iOS封裝
- 封裝axios封裝iOS
- AVPlayer封裝封裝
- 09 #### 封裝封裝
- java 封裝Java封裝