JavaScript實(shí)現(xiàn)復(fù)制粘貼剪切功能三種方法
方式一:原生方式實(shí)現(xiàn)復(fù)制粘貼剪切(不推薦)
使用瀏覽器自帶的document.execCommand('copy')實(shí)現(xiàn)復(fù)制,document.execCommand('paste')實(shí)現(xiàn)粘貼,document.execCommand('cut')實(shí)現(xiàn)剪切,這三個(gè)方法的返回值是布爾類型,用來(lái)判斷當(dāng)前瀏覽器中能夠使用這些方法,true表示方法能用,false表示方法不能用,目前因?yàn)?code>document.execCommand('paste')涉及到安全問(wèn)題,考慮到安全原因, document.execCommand(‘paste’)操作已經(jīng)被禁止了。
補(bǔ)充說(shuō)明下,目前官方已經(jīng)不推薦使用原生方式進(jìn)行復(fù)制粘貼操作了,這幾種方法隨時(shí)可能會(huì)被刪掉
代碼如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Document</title>
</head>
<body>
<input type="text" id="input" value="123" />
<button onclick="copy1()">復(fù)制(復(fù)制可編輯的標(biāo)簽中的內(nèi)容)</button>
<button onclick="copy2('這是復(fù)制的內(nèi)容')">復(fù)制(將可編輯的標(biāo)簽隱藏)</button>
<button onclick="cut()">剪切</button>
<button onclick="paste()">粘貼</button>
<input type="text" id="output">
<script>
// 復(fù)制可編輯標(biāo)簽中的value值得內(nèi)容
function copy1() {
const inputEle = document.querySelector("#input");
inputEle.select(); // 鼠標(biāo)選擇的內(nèi)容
document.execCommand("copy"); // 復(fù)制
}
/**
* 如果想使用 execCommand 方法,又不想頁(yè)面中出現(xiàn)可編輯區(qū)域,可以用下述辦法取巧
* @content 是要復(fù)制的內(nèi)容
*/
function copy2(content) {
const dom = document.createElement("input");
dom.value = content;
document.body.appendChild(dom);
dom.select();
document.execCommand("copy");
document.body.removeChild(dom);
}
// 剪切功能
function cut(){
console.log("cut");
document.execCommand("cut")
}
// 粘貼功能:注意,只會(huì)在光標(biāo)所在位置進(jìn)行粘貼
// function paste(){
// const pasteText = document.querySelector("#output")
// pasteText.focus() // 讓光標(biāo)聚焦到output標(biāo)識(shí)的輸入框上
// document.execCommand("paste"); // 截至目前該方法涉及到安全問(wèn)題已失效
// }
</script>
</body>
</html>
使用execCommand命令存在以下缺陷:
(1)不夠靈活。只能操作input, textarea或具有contenteditable屬性的元素
(2)execCommand是同步操作,如果復(fù)制/粘貼大量數(shù)據(jù),頁(yè)面會(huì)出現(xiàn)卡頓。
(3)有些瀏覽器還會(huì)跳出提示框,要求用戶許可,這時(shí)在用戶做出選擇前,頁(yè)面會(huì)失去響應(yīng)。
(4)它只能將選中的內(nèi)容復(fù)制到剪貼板,無(wú)法向剪貼板任意寫(xiě)入內(nèi)容
方式二:瀏覽器自帶clipboard API實(shí)現(xiàn)復(fù)制粘貼(推薦)
簡(jiǎn)介
ClipboardAPI是下一代的剪貼板操作方法,比傳統(tǒng)的document.execCommand()方法更加強(qiáng)大、更合理。
特點(diǎn)
(1)它的所有操作都是異步進(jìn)行的,返回promise對(duì)象,不糊造成頁(yè)面卡頓,
(2)它可以將任何內(nèi)容(例如圖片)放入到剪貼板。
(3)安全。通過(guò)navigator.clipboard屬性返回Clipboard對(duì)象,所有操作都通過(guò)這個(gè)對(duì)象進(jìn)行,如果navigator.clipboard屬性返回undefined,就說(shuō)明當(dāng)前瀏覽器不支持這個(gè)API。
1)有時(shí)候用戶可能會(huì)把敏感數(shù)據(jù)(比如密碼)放在剪貼板允許腳本任意讀取會(huì)產(chǎn)生風(fēng)險(xiǎn),而通過(guò)Clipboard對(duì)象進(jìn)行判斷,則很好的避免了這個(gè)風(fēng)險(xiǎn)。
2)此外,有些瀏覽器規(guī)定(例如Chrome),只有HTTPS協(xié)議(或者開(kāi)發(fā)環(huán)境、本地環(huán)境下)的頁(yè)面才能使用這個(gè)API,由于從 Chrome 76 開(kāi)始,Clipboard API 將不再被允許在非加密環(huán)境下(即純 HTTP)使用。這是因?yàn)樵?HTTP 環(huán)境下,網(wǎng)絡(luò)傳輸是明文的,容易被竊聽(tīng)和篡改,因此會(huì)引入安全風(fēng)險(xiǎn)。
3)其次,復(fù)制權(quán)限是用戶默認(rèn)賦予的,而粘貼權(quán)限是需要用戶手動(dòng)同意的,例如,在寫(xiě)入剪貼板時(shí)腳本可以自動(dòng)完成,但是讀取剪貼板時(shí),瀏覽器會(huì)彈出一個(gè)對(duì)話框咨詢用戶是否同意讀取。

(4)有一點(diǎn)需要特別注意,腳本讀取的是當(dāng)前頁(yè)面的剪切板(注意我說(shuō)的是瀏覽器中的剪貼板,而不是電腦操作系統(tǒng)自帶的剪貼板),這帶來(lái)一個(gè)問(wèn)題,如果想把相關(guān)的代碼粘貼到開(kāi)發(fā)者工具中直接運(yùn)行,可能會(huì)報(bào)錯(cuò),因?yàn)檫@時(shí)的當(dāng)前頁(yè)面是開(kāi)發(fā)者工具的窗口,而不是網(wǎng)頁(yè)頁(yè)面。
例如:你把下面的代碼粘貼到開(kāi)發(fā)者工具運(yùn)行就會(huì)報(bào)錯(cuò)。
(async () => {
const text = await navigator.clipboard.readText();
console.log(text);
})();
因?yàn)樵诖a運(yùn)行的時(shí)候,開(kāi)發(fā)者工具窗口是當(dāng)前頁(yè),這個(gè)頁(yè)面不存在ClipboardAPI依賴的DOM接口。
解決辦法是將相關(guān)代碼放到setTimeout()里面延遲運(yùn)行,在調(diào)用函數(shù)之前快速點(diǎn)擊瀏覽器的頁(yè)面窗口,將其變成當(dāng)前頁(yè)。
setTimeout(async () => {
const text = await navigator.clipboard.readText();
console.log(text);
}, 2000);
clipboard對(duì)象及相關(guān)API
clipboard對(duì)象提供了四個(gè)方法用來(lái)讀寫(xiě)剪貼板,他們都是異步方法,返回promise對(duì)象。
Clipboard.readText()
Clipboard.readText()方法用來(lái)復(fù)制剪貼板(也就是粘貼功能)里面的文本數(shù)據(jù)。
該方法返回的是Promise對(duì)象,那么我這里提供兩種使用形式
- 形式一:pormise回調(diào)實(shí)現(xiàn)
// 普通方法
function paste() {
navigator.clipboard // 創(chuàng)建clipboard對(duì)象
.readText() // 調(diào)用readText()方法
.then((clipText) => {
// 成功回調(diào)
console.log(clipText); // clipText是從剪貼板讀取到的內(nèi)容(也就是要粘貼的內(nèi)容)
})
.catch((err) => console.log("粘貼失?。?,err)); // 失敗回調(diào)
}
- 形式二:async函數(shù)
// async 函數(shù)
async function paste(){
try{
// 創(chuàng)建clipboard對(duì)象并調(diào)用readText()方法讀取剪貼板上的內(nèi)容進(jìn)行返回
const text = await navigator.clipboard.readText()
console.log("要粘貼的內(nèi)容為:",text); // 具體粘貼到哪你自己決定
}catch(err){
// catch捕獲處理報(bào)錯(cuò)
console.log("粘貼失??!",err);
}
}
注意,如果用戶不允許使用這個(gè)API進(jìn)行粘貼操作,那么腳本就會(huì)報(bào)錯(cuò),那么我們就可以用catch()方法進(jìn)行處理報(bào)錯(cuò)。
Clipboard.read()
Clipboard.read()方法用于復(fù)制剪貼板(也就是粘貼功能)里面的數(shù)據(jù),可以是文本數(shù)據(jù),也可以是二進(jìn)制數(shù)據(jù)(比如圖片)。該方法需要用戶明確給予許可。
該方法返回一個(gè) Promise 對(duì)象。一旦該對(duì)象的狀態(tài)變?yōu)?resolved,就可以獲得一個(gè)數(shù)組,每個(gè)數(shù)組成員都是 ClipboardItem 對(duì)象的實(shí)例。
下面我們簡(jiǎn)單介紹下代碼中用到的幾個(gè)對(duì)象屬性和方法
遍歷通過(guò)Clipboard.read()方法成功回調(diào)得到的數(shù)組對(duì)象,由此得到一個(gè)個(gè)的ClipboardItem 對(duì)象,表示一個(gè)單獨(dú)的剪貼項(xiàng),每個(gè)剪貼項(xiàng)都擁有ClipboardItem.types屬性和ClipboardItem.getType()方法。
1、ClipboardItem.types屬性返回一個(gè)數(shù)組,里面的成員是該剪貼項(xiàng)可用的 MIME 類型,比如某個(gè)剪貼項(xiàng)可以用 HTML 格式粘貼,也可以用純文本格式粘貼,那么它就有兩個(gè) MIME 類型(text/html和text/plain)。
2、ClipboardItem.getType(type)方法用于讀取剪貼項(xiàng)的數(shù)據(jù),返回一個(gè) Promise 對(duì)象。該方法接受剪貼項(xiàng)的 MIME 類型作為參數(shù),返回該類型的數(shù)據(jù),該參數(shù)是必需的,否則會(huì)報(bào)錯(cuò)。
代碼示例如下:
- 形式一:promise回調(diào)實(shí)現(xiàn)
// 粘貼任何類型的數(shù)據(jù)
function paste() {
navigator.clipboard
.read() // 調(diào)用read()方法從剪貼板讀取數(shù)據(jù)進(jìn)行粘貼操作
.then((clipboardItems) => {
console.log(clipboardItems,"clipboardItems =========");
// clipboardItems是一個(gè)數(shù)組
for (const clipboardItem of clipboardItems) {
console.log(clipboardItem, "clipboardItem ========="); // clipboardItem是一個(gè)實(shí)例對(duì)象
for (const type of clipboardItem.types) { // clipboardItem.types返回一個(gè)數(shù)組,存儲(chǔ)的是每一段剪貼板的mine數(shù)據(jù)類型
clipboardItem
.getType(type) // 讀取接收到的mine類型作為參數(shù),返回該類型的數(shù)據(jù)
.then((res) => console.log(res))
.catch((err) => console.log(err));
}
}
})
.catch((err) => {
console.log(err.name,err.message)
});
}
- 形式二:async函數(shù)+await實(shí)現(xiàn)
async function paste(){
try {
const clipboardItems = await navigator.clipboard.read()
for(const clipboardItem of clipboardItems){
for(const type of clipboardItem.types){
const result = await clipboardItem.getType(type)
console.log(result);
}
}
} catch (err) {
console.log(err.name,err.message);
}
}
顯然使用第二種方式實(shí)現(xiàn)代碼更簡(jiǎn)單。
Clipboard.writeText()
Clipboard.writeText()方法用于將文本內(nèi)容寫(xiě)入剪貼板(也就是復(fù)制功能),該方法同樣返回一個(gè)Promise對(duì)象。
代碼示例如下:
下面代碼功能是:通過(guò)點(diǎn)擊頁(yè)面,將數(shù)據(jù)復(fù)制到剪貼板。
document.body.addEventListener('click',async (e) => {
await navigator.clipboard.writeText('Yo') // 參數(shù)是要寫(xiě)入的文本
}
)
當(dāng)然你可以通過(guò)點(diǎn)擊一個(gè)按鈕,一個(gè)標(biāo)簽等來(lái)觸發(fā)該復(fù)制操作。
Clipboard.write()
Clipboard.write()方法用于將任意數(shù)據(jù)寫(xiě)入剪貼板,可以是文本數(shù)據(jù),也可以是二進(jìn)制數(shù)據(jù)。
該方法接受一個(gè) ClipboardItem 實(shí)例作為參數(shù),表示寫(xiě)入剪貼板的數(shù)據(jù)。
- 代碼示例復(fù)制一個(gè)圖片類型
async function copy1() {
try {
// 圖片地址
const imgURL = "https://dummyimage.com/300.png";
// 獲取圖片
const data = await fetch(imgURL);
// 將圖片轉(zhuǎn)為blob類型
const blob = await data.blob();
// 將數(shù)據(jù)寫(xiě)入(復(fù)制)到剪貼板
await navigator.clipboard.write([
// 創(chuàng)建Clipboard實(shí)例對(duì)象,對(duì)象的鍵名是數(shù)據(jù)的 MIME 類型,鍵值就是數(shù)據(jù)本身
new ClipboardItem({
[blob.type]: blob,
}),
]);
console.log("Image copied.");
} catch (err) {
console.error(err.name, err.message);
}
}
ClipboardItem()是瀏覽器原生提供的構(gòu)造函數(shù),用來(lái)生成ClipboardItem實(shí)例,它接收一個(gè)對(duì)象作為參數(shù),該對(duì)象的鍵名是數(shù)據(jù)的 MIME 類型,鍵值就是數(shù)據(jù)本身。
注意,Chrome 瀏覽器目前只支持寫(xiě)入 PNG 格式的圖片。
此外,write()方法還可以將用一個(gè)剪貼項(xiàng)的多種格式的值寫(xiě)入到剪貼板,一種是文本數(shù)據(jù),一種是二進(jìn)制數(shù)據(jù),供不同的場(chǎng)合粘貼使用。
function copy() {
const image = await fetch('kitten.png'); // 獲取圖片類型的數(shù)據(jù)
const blob = await image.blob(); // 將圖片轉(zhuǎn)為blob對(duì)象
const text = new Blob(['Cute sleeping kitten'], {type: 'text/plain'}); // 獲取文字類型的數(shù)據(jù)并轉(zhuǎn)為blob實(shí)例對(duì)象
const item = new ClipboardItem({
'text/plain': text,
[blob.type]: image
});
await navigator.clipboard.write([item]);
}
就是剪貼板中的剪貼項(xiàng)有兩種類型的數(shù)據(jù),在你要圖片時(shí),我就將剪貼板中的數(shù)據(jù)用圖片的形式給你粘貼使用,要用文字時(shí),就粘貼文字給你。
方式三:clipboard.js插件庫(kù)實(shí)現(xiàn)復(fù)制剪切(推薦)
它是一個(gè)不需要Flash,就能實(shí)現(xiàn)文本復(fù)制或者剪切到剪切板的輕量級(jí)插件(注意沒(méi)有粘貼哦)
官網(wǎng):clipboard.js
安裝引入
# node安裝 npm install clipboard --save
<!-- html文件中可以使用CDN引入 --> <script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js"></script>
// js文件中可以通過(guò)ES6語(yǔ)法的import或者commonjs進(jìn)行引入或者使用其他引入方式
這個(gè)庫(kù)同時(shí)依賴于Selection和execCommand api。所有瀏覽器都支持第一個(gè),而以下瀏覽器支持第二個(gè)。chrome42+,Edge12+,F(xiàn)irefox41+,IE9+,Opera2+,Safari0+
基本使用
總共有兩步,第一步在指定的html標(biāo)簽中使用指定屬性進(jìn)行綁定,第二部創(chuàng)建Clipboard實(shí)例對(duì)象調(diào)用相關(guān)的event事件,操作如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!-- 引入clipboard.js -->
<script src="https://cdn.bootcdn.net/ajax/libs/clipboard.js/2.0.11/clipboard.js"></script>
<title>Document</title>
</head>
<body>
<div>
<!-- Target -->
<input type="text" id="foo" value="要復(fù)制的內(nèi)容" />
<!-- Trigger -->
<button class="btn" data-clipboard-target="#foo" data-clipboard-action="copy">復(fù)制</button>
<!--
有兩個(gè)屬性值:
data-clipboard-target:取值是一個(gè)選擇器對(duì)象,用來(lái)綁定要復(fù)制的標(biāo)簽,復(fù)制其內(nèi)容
data-clipboard-action:用來(lái)決定是復(fù)制還是粘貼,有兩個(gè)取值:copy和cut
-->
</div>
<script>
// 創(chuàng)建一個(gè)實(shí)例對(duì)象,參數(shù)是一個(gè)選擇器,綁定的是觸發(fā)復(fù)制/剪切事件的標(biāo)簽
var clipboard = new ClipboardJS(".btn");
// 成功回調(diào)
clipboard.on("success", function (e) {
console.info("Action:", e.action); // 操作:copy或者cut
console.info("Text:", e.text); // 復(fù)制/剪切的內(nèi)容
console.info("Trigger:", e.trigger); // 觸發(fā)對(duì)象
e.clearSelection();
});
// 失敗回調(diào)
clipboard.on("error", function (e) {
console.error("Action:", e.action); // 操作:copy或者cut
console.error("Trigger:", e.trigger); // 觸發(fā)對(duì)象
});
</script>
</body>
</html>
可以通過(guò)ClipboardJS.isSupported()方法判斷瀏覽器是否可以使用這個(gè)庫(kù)
進(jìn)階使用
new ClipboardJS("選擇器",{...})方法,第二個(gè)參數(shù)是一個(gè)對(duì)象,你可以往里面?zhèn)魅牖卣{(diào)函數(shù),如下
(1)通過(guò)函數(shù)返回要綁定的節(jié)點(diǎn)target
new ClipboardJS('.btn', {
target: function(trigger) {
return trigger.nextElementSibling;
}
});
(2)通過(guò)函數(shù)設(shè)置要復(fù)制的文本內(nèi)容text
new ClipboardJS('.btn', {
text: function(trigger) {
return trigger.getAttribute('aria-label');
}
});
(3)在Bootstrap Modals 中或與任何其他更改焦點(diǎn)的庫(kù)一起使用時(shí),將焦點(diǎn)元素設(shè)置為 container 值
new ClipboardJS('.btn', {
container: document.getElementById('modal')
});
(4)銷毀復(fù)制粘貼的實(shí)例對(duì)象(如果在單頁(yè)應(yīng)用中使用時(shí),要更精確地管理DOM的生命周期,可以使用以下方法清除創(chuàng)建的事件對(duì)象)
var clipboard = new ClipboardJS('.btn');
clipboard.destroy();
可以看到這個(gè)插件庫(kù)基本的功能是復(fù)制和剪切,沒(méi)有涉及到粘貼操作,所以,通常會(huì)和瀏覽器自帶clipboardAPI配合使用實(shí)現(xiàn)復(fù)制粘貼操作。
補(bǔ)充:復(fù)制粘貼操作攔截
主要用到了copy和paste事件
copy
例如:復(fù)制操作時(shí),將用戶放入到剪貼板中的文本轉(zhuǎn)為大寫(xiě)
const source = document.querySelector('.source');
source.addEventListener('copy', (event) => {
const selection = document.getSelection();
event.clipboardData.setData('text/plain', selection.toString().toUpperCase());
event.preventDefault();
});
上面示例中,事件對(duì)象的clipboardData屬性包含了剪貼板數(shù)據(jù)。它是一個(gè)對(duì)象,有以下屬性和方法。
Event.clipboardData.setData(type, data):修改剪貼板數(shù)據(jù),需要指定數(shù)據(jù)類型。Event.clipboardData.getData(type):獲取剪貼板數(shù)據(jù),需要指定數(shù)據(jù)類型Event.clipboardData.clearData([type]):清除剪貼板數(shù)據(jù),可以指定數(shù)據(jù)類型。如果不指定類型,將清除所有類型的數(shù)據(jù)。Event.clipboardData.items:一個(gè)類似數(shù)組的對(duì)象,包含了所有剪貼項(xiàng),不過(guò)通常只有一個(gè)剪貼項(xiàng)。
例如:攔截用戶的復(fù)制操作,將指定內(nèi)容放入剪貼板
onst clipboardItems = [];
document.addEventListener('copy', async (e) => {
e.preventDefault(); // 先使用該方法組織默認(rèn)事件,然后由腳本接管復(fù)制操作
try {
let clipboardItems = [];
for (const item of e.clipboardData.items) {
if (!item.type.startsWith('image/')) {
continue;
}
clipboardItems.push(
new ClipboardItem({
[item.type]: item,
})
);
await navigator.clipboard.write(clipboardItems);
console.log('Image copied.');
}
} catch (err) {
console.error(err.name, err.message);
}
});
paste
用戶使用剪貼板數(shù)據(jù),進(jìn)行粘貼操作時(shí),會(huì)觸發(fā)paste事件
document.addEventListener('paste', async (e) => {
e.preventDefault();
const text = await navigator.clipboard.readText();
console.log('Pasted text: ', text);
});總結(jié)
到此這篇關(guān)于JavaScript實(shí)現(xiàn)復(fù)制粘貼剪切功能的文章就介紹到這了,更多相關(guān)JS復(fù)制粘貼剪切功能內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaScript獲取網(wǎng)頁(yè)中第一個(gè)鏈接ID的方法
這篇文章主要介紹了JavaScript獲取網(wǎng)頁(yè)中第一個(gè)鏈接ID的方法,涉及javascript中document.links方法的使用,需要的朋友可以參考下2015-04-04
js刪除對(duì)象中的某一個(gè)字段的方法實(shí)現(xiàn)
這篇文章主要介紹了js刪除對(duì)象中的某一個(gè)字段的方法實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01
使用JavaScript實(shí)現(xiàn)獲取頁(yè)面滾動(dòng)位置
這篇文章主要為大家詳細(xì)介紹了在JavaScript中如何獲取水平和垂直的滾動(dòng)位置,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以參考一下2024-12-12
js模擬jquery的slide和fadeIn和fadeOut功能
以前用過(guò)jquery的slideUp,slideDown,等許多很不錯(cuò)的方法,感覺(jué)很容易就能實(shí)現(xiàn)頁(yè)面元素的動(dòng)畫(huà)效果!2010-07-07
固定背景實(shí)現(xiàn)的背景滾動(dòng)特效示例分享
固定背景滾動(dòng)特效,使用background-attachment: fixed和導(dǎo)航菜單,頁(yè)面會(huì)非常平滑的滾動(dòng),感興趣的朋友可以參考下哈希望對(duì)你有所幫助2013-05-05
如何根據(jù)url?批量下載二維碼實(shí)現(xiàn)詳解
這篇文章主要為大家介紹了如何根據(jù)url批量下載二維碼實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
深入理解JavaScript系列(26):設(shè)計(jì)模式之構(gòu)造函數(shù)模式詳解
這篇文章主要介紹了深入理解JavaScript系列(26):設(shè)計(jì)模式之構(gòu)造函數(shù)模式詳解,本文講解了基本用法、構(gòu)造函數(shù)與原型、只能用new嗎?、強(qiáng)制使用new、原始包裝函數(shù)等內(nèi)容,需要的朋友可以參考下2015-03-03
JavaScript設(shè)計(jì)模式之建造者模式實(shí)例教程
這篇文章主要介紹了JavaScript設(shè)計(jì)模式之建造者模式,結(jié)合實(shí)例形式分析了設(shè)計(jì)模式中建造者模式的概念、功能及JavaScript實(shí)現(xiàn)與使用建造者模式的相關(guān)操作技巧,需要的朋友可以參考下2018-07-07

