「DOM 編程」表單操作

表單操作

表單為頁面的主要組成部分,其中包含許多的表單控件。用戶通過控件提供數(shù)據(jù)并提交給服務(wù)器,服務(wù)器則做出相應(yīng)的處理。而編寫一個正常工作的表單需要三個部分:

  1. 構(gòu)建表單
  2. 服務(wù)器處理(提供接受數(shù)據(jù)接口)
  3. 配置表單

構(gòu)建表單

form_sample_form.png
<form>
  <p><label>姓名:<input></label></p>
  <p><label>電話:<input type="tel"></label></p>
  <p><label>郵箱:<input type="email"></label></p>
  <fieldset>
    <legend> 披薩大小 </legend>
    <label><input type="radio" name="size"> 小 </label>
    <label><input type="radio" name="size"> 中 </label>
    <label><input type="radio" name="size"> 大 </label>
  </fieldset>
  <fieldset>
    <legend> 披薩配料 </legend>
    <label><input type="checkbox"> 熏肉 </input></label>
    <label><input type="checkbox"> 奶酪 </input></label>
    <label><input type="checkbox"> 洋蔥 </input></label>
    <label><input type="checkbox"> 蘑菇 </input></label>
  </fieldset>
  <p><label>配送時間:<input type="time" min="11:00" max="2100" step="900"></label></p>
  <p><button>提交訂單</button></p>
</form>

服務(wù)器處理

提供接口地址(例如,https://pizza.example.com/order,數(shù)據(jù)格式(application/x-www-form-urlencoded),還是接受的參數(shù)信息(custname、custtel、custemail、size、topping、delivery)。

數(shù)據(jù)命名需在表單控件中注明。

配置表單

form_data_receive.png
<form action="https://pizza.example.com/order" method="post" enctype="application/x-www-form-urlencoded">
  <p><label>姓名:<input name="custname"></label></p>
  <p><label>電話:<input type="tel" name="custtel"></label></p>
  <p><label>郵箱:<input type="email" name="custemail"></label></p>
  <fieldset>
    <legend> 披薩大小 </legend>
    <label><input type="radio" name="size" value="small"> 小 </label>
    <label><input type="radio" name="size" value="medium"> 中 </label>
    <label><input type="radio" name="size" value="large"> 大 </label>
  </fieldset>
  <fieldset>
    <legend> 披薩配料 </legend>
    <label><input type="checkbox"> 熏肉 </input></label>
    <label><input type="checkbox"> 奶酪 </input></label>
    <label><input type="checkbox"> 洋蔥 </input></label>
    <label><input type="checkbox"> 蘑菇 </input></label>
  </fieldset>
  <p><label>配送時間:<input type="time" min="11:00" max="2100" step="900"></label></p>
  <p><button>提交訂單</button></p>
</form>

用戶所有提交的信息需在提交服務(wù)器前對其進(jìn)行驗證從而提高用戶體驗。

NOTE:表單驗證 使用 require 來強(qiáng)制用戶填寫相應(yīng)的信息。

內(nèi)容

元素

form 元素

form 元素為構(gòu)建表單中最重要的元素。

<form novalidate name="pizza" target="abc" method="post" autocomplete="off" accept-charset="utf-8" action="http://pizza.example.com/order" enctype="application/x-www-form-urlencoded">

其對應(yīng)的信息則可以視為

字段
noValidate true
target abc
method post
acceptCharset utf-8
action http://pizza.example.com/order
enctype application/x-www-form-urlencoded
name pizza
autocomplete off

NOTE:前六項為表單提交相關(guān)的信息。

屬性
  • name 屬性:可以用于獲取表單節(jié)點元素。
var pizzaForm = document.forms.pizza;
  • autocomplete 屬性:有兩個值 onoff,在設(shè)置為 on 時,可以自動對輸入框進(jìn)行補(bǔ)全(之前提交過的輸入值,下圖左)。
form-auto-complete.png

NOTE:在已經(jīng)設(shè)置 autocomplete="off" 時依然出現(xiàn)提示框,大多數(shù)情況為瀏覽器設(shè)置的自動補(bǔ)全(可以強(qiáng)制關(guān)閉,需要時請搜索對應(yīng)的解決方案)。

  • elements 屬性:為一個動態(tài)節(jié)點集合(更具 DOM 的變化進(jìn)行變化),其用于歸結(jié)該表單的子孫表單控件(除圖標(biāo)按鈕外 <input type="image>"):

    • button
    • fieldset
    • input
    • keygen
    • object
    • output
    • select
    • textarea

此外還有歸屬于該表單的空間(依舊圖片按鍵除外)代碼如下所示。

<form id="a">
</form>
<label><input name="null" form="a"></label>
  • length 屬性:等價于 elements.length 來用于描述表單內(nèi)節(jié)點集合的個數(shù)。
選取表單空間元素
<form name="test">
  <input name="a">
  <input name="b">
</form>

選取 name="a" 的控件可以使用下面的方法:

testForm.elements[0];
testForm.elements['a'];

// 操作 Form 表單的屬性
testForm[0];
testForm['a'];
  • form[name] 通過名稱作為索引時有如下特點:

    • 返回 id 或者 name 為指定名稱的表單空間(圖標(biāo)按鍵除外)
    • 如果結(jié)果為空,則返回id 為指定名稱的 img 元素(入下面代碼所示)
    • 如果有多個同名元素,則返回的元素為動態(tài)節(jié)點集合
    • 一旦用指定名稱取過改元素,之后則不論該元素的 id 或者 name 如何變化,只有節(jié)點存在則均可使用原名稱來繼續(xù)獲取改節(jié)點。

無指定名稱索引范例

<form name="test">
  <img id="a" src="sample.png">
</form>
testForm['a']; // 取得的便是 id 為 a 的圖片元素

更新名稱,依然可以獲取節(jié)點范例

<form name="test">
  <input name="a">
</form>
// 第一步
testForm['a'];
// 或者
testForm.elements['a'];

// 第二步
testForm['a'].name = 'b';
form_element.png
form 接口

form 元素也提供了一些接口便于對其進(jìn)行操作 reset() submit() checkValidity()

可以重置(reset)的元素有下面的幾種:

  • input
  • keygen
  • output
  • select
  • textarea

當(dāng)觸發(fā)表單 reset 事件時可使用阻止該事件的默認(rèn)行為來取消重置。而且元素重置時將不會再次觸發(fā)元素上的 changeinput 事件。

form-reset.png
label 元素
<label for="textId" form="formId">
字段
htmlFor textId
control HTMLElement#textId
form HTMLFormElement#formId
  • htmlFor 屬性:用于關(guān)聯(lián)表單控件的激活行為(可使點擊 label 與點擊表單控件的行為一致),可關(guān)聯(lián)的元素有下列(hidden 除外):

    • button
    • input
    • keygen
    • meter
    • output
    • progress
    • select
    • textarea

自定義文件提交控件樣式

form_file_upload.png
  • control 屬性:如果指定了 for 屬性則指定該for 屬性對于 id 的可關(guān)聯(lián)元素。如果沒有指定 for 屬性則為第一個可關(guān)聯(lián)的子孫元素。
for_label.png

可關(guān)聯(lián)的元素 (只讀屬性不可在程序中直接賦值修改)

  • button
  • fieldset
  • input
  • keygen
  • label
  • object
  • output
  • select
  • textarea

form 屬性:修改關(guān)聯(lián)元素所歸屬的表單則可以修改元素的 form 屬性為帶關(guān)聯(lián)表單Id(元素中對于的for屬性也應(yīng)該做對應(yīng)的修改)。//這里有一點小問題,更改form屬性之后label并不能自動綁定到新表單對應(yīng)的元素上

label.setAttribute('form', 'newFormId');
input 元素
<input type="text">
  • type 屬性:可用于控制控件的外觀以及數(shù)據(jù)類型(默認(rèn)為 text),在不同的瀏覽器不同數(shù)據(jù)類型有不同的展示效果。

本地圖片預(yù)覽示例

所需技術(shù)點(HTMLInputElement屬性)

  • onchange
  • accept
  • multiple
  • files
<input type="file" accept="image/*" multiple>
file.addEventListener(
  'change', function(event){
      var files = Array.prototype.slice.call(
        event.target.files, 0
      );
      files.forEach(function(item){
        files2dataurl(item,function(url){
          var image = new Image();
          parent.appendChild(image);
          image.src = url;
        });
      });
  }
);
function file2dataurl(file, callback) {
    if (!window.FileReader) {
        throw 'Browser not support File API !';
    }
    var reader = new FileReader();
    reader.readAsDataURL(file);
    reader.onload = function(event) {
        callback(event.target.result);
    };
}

NOTE:accept 所支持的格式有 audio/* video/* image/* 以及不帶;的 MINE Type 類型和 . 開頭的文件名后綴的文件。多個文件類型可以使用,分隔。

select 元素
form_select.png

指定選項列表中選擇需要的選項。

主要的三個子標(biāo)簽 selectoptgroup(用于選項分組)、option

  • select 具有的屬性和方法如下:

    • name
    • value
    • multiple
    • options(動態(tài)節(jié)點集合)
    • selectedOptions(動態(tài)節(jié)點集合)
    • selectedIndex
    • add(element[, before])(無指定參照物則添加至最末端)
    • remove([index])
  • optgroup 所具有的屬性和方法:

    • disabled (分組選項不可選)
    • label(分組說明)
  • option 所具有的屬性和方法:

    • disabled
    • label(描述信息)
    • value(提交表單時的數(shù)據(jù)信息)
    • text(用戶看到的文字)
    • index
    • selected
    • defaultSelected
選項操作

創(chuàng)建選項

document.createElement('option')
// 或者
new Option([text[, value[, defaultSelected[, selected]]]])

添加選項

var option = new Option('sample');
opt.insertAdjacentElement(option, '參照元素');
// 或者
select.add(option, '參照元素')

刪除選項

opt.parentNode.removeChild(option);
// 或者使用它的索引將其刪除
select.remove(2);
級聯(lián)下列選擇器

所需知識點:

  • onchange
  • remove
  • add
<form name="course">
  <select name="chapter">
    <option>Select0</option>
  </select>
  <select name="section">
    <option>Select1</option>
  </select>
</form>
var chapters = {
  {text: 1, value: 1},
  {text: 2, value: 2}
};
var sections = {
  1: [{
    text:1.1, value: 1.1
  }, {
    text:1.2, value: 1.2
  }],
  2:[{
    text:2.1, value:2.1;
  }]
};

function fillSelect(select, list) {
  for(var i = select.length; i > 0; i--) {
    select.remove(i);
  }
  list.forEach(function(data){
    var option = new Option(data.text, data.value);
    select.add(option);
  })
}

fileSelect(chapterSelect, chapters);
chapterSelect.addEventListener(
  'change', function(event) {
    var value = event.target.value,
        list = sections[value] || [];
    fillSelect(sectionSelect, list);
  }
);
textarea 元素

textarea 具有的屬性和方法如下:

  • name
  • value (用戶輸入信息)
  • select() (全選當(dāng)前輸入的內(nèi)容)
  • selectionStart (選中的內(nèi)容的起始位置,無選中時返回當(dāng)前光標(biāo)所在位置)
  • selectionEnd (選中內(nèi)容結(jié)束位置,無選中時返回光標(biāo)位置)
  • selectionDirection (選取方向 forward backward
  • setSelectionRange(start, end[, direction]) (使用程序選中內(nèi)容)
  • setRangeText(replacement[, start, end, [mode]]) (設(shè)置內(nèi)容范圍)
selection

表示選擇區(qū)域,對于 input 元素同樣有效。

form_select_start_and_end.png

selectionDirection 主要是用于在使用 SHIFT 鍵與方向鍵組合選取時的選取方向。設(shè)置為 forward 時選取移動的方向為 selectionEnd 設(shè)置為 backward 時移動方向為 selectionStart

@輸入提示示例

form_textarea_at_symble.png

所需知識點:

  • oninput
  • selectionStart
  • setRangeText
textarea.addEventListener(
  'input', function(event) {
    var target = event.target,
        cursor = target.selectionStart;
    if(target.value.charAt(cursor-1) === '@') {
      doShowAtList(functi=on(name){
        var end = cursor + name.length;
        target.setRangeText(
          name, cursor, end, 'end'
        );
      });
    }
  }
);
其他元素
  • fieldset
  • button
  • keygen
  • output
  • progress
  • meter
form_supportability.jpg

驗證

可以被驗證的元素如下所示:】

  • button
  • input
  • select
  • textarea

以下情況不可以做驗證

  • input 元素在類型是 hidden, reset, button 時
  • button 元素在類型為 reset, button 時
  • input 與 textarea 當(dāng)屬性為 readonly 時
  • 當(dāng)元素為 datalist 的子孫節(jié)點時
  • 當(dāng)元素被禁用時 disabled 的狀態(tài)
屬性

驗證涉及到以下的以下屬性,在每一個可以驗證的元素上均可以調(diào)用對于的屬性或通過接口進(jìn)行操作:

  • willValidate (表明此元素在表單提交時是否會被驗證)
  • checkValidity() (用于驗證元素,返回 true 當(dāng)驗證通過,或者觸發(fā) invalid 事件)
  • validity (存儲驗證結(jié)果)
  • validationMessage (顯示驗證異常信息)
  • setCustomValidity(message) (自定義驗證錯誤信息)
form_validity.png

自定義異常范例

涉及到的知識點:

  • oninvalid
  • setCustomValidity
<form action="./api" method="post">
  <label>Name: <input name="username" required></label>
  <button>submit</button>
</form>
input.addEventListener(
  'invalid', function(event){
    var target = event.target;
    if (target.validity.valueMissing) {
      target.setCustomValidity('Name is missing');
    }
  }
)

禁止驗證范例

使用 formnovalidate 屬性來禁止表單提交的驗證。

<form action="./api" method="post" novalidate>
  <label>Mobile: <input name="mobile" type="number"></label>
  <button>submit</button>
</form>

提交

隱式提交

在操作過程中通過控件的操作來提交表單(敲擊回車來提交表單),其需要滿足以下的條件:

  • 表單有非禁用的提交按鍵
  • 沒有提交按鍵時,不超過一個類型為 text search url email password date time numberinput 元素
提交過程細(xì)節(jié)

提交過程分為兩個階段,第一個階段是更具表單 enctype 指定的值構(gòu)建要提交的數(shù)據(jù),第二個階段是使用指定的方法(method)發(fā)送數(shù)據(jù)到 action 指定的目標(biāo)。

構(gòu)建提交數(shù)據(jù),從可提交元素中提取數(shù)據(jù)組成指定數(shù)據(jù)結(jié)構(gòu)過程(可提交元素有 button input keygen object select textarea

編碼方式(enctype)所支持的形式:

  • application/x-www-form-urlencoded (默認(rèn),數(shù)據(jù)格式為 & 分隔的鍵值對)
  • multipart/form-data (IFC 2388 字節(jié)流形式,例如文件上傳所使用的數(shù)據(jù)編碼形式)
  • text/plain (回車換行符分隔的鍵值對)
form_submit_data_type.png
form_submit_data_2.png
form_submit_data_type1.png

特殊案例一

當(dāng)一個表單元素 name="isindex" 并且 type="text" 而且滿足如下要求時:

  • 編碼格式為 application/x-www-form-urlencoded
  • 作為表單的第一個元素

則提交時只發(fā)送 value 值,不包含 name。

<form action="./api" method="post">
  <input name="isindex">
  <input name="a">
  <button>submit</button>
</form>
form_special_case.png

特殊案例二

當(dāng) name="_charset_" 并且類型為 hidden 時,而且滿足如下要求時:

  • 沒有設(shè)置 value

則提交時 value 自動使用當(dāng)前提交的字符集填充。

form_speicla_calse2.png
submit 接口

form.submit() 可以通過調(diào)用接口submit()直接提交表單,在提交表單時均會觸發(fā)一個 onsubmit 表單提交事件,在這個事件中 women 可以做下面的事件:

  • 提交前的數(shù)據(jù)驗證
  • 阻止事件的默認(rèn)行為來取消表單的提交(例如當(dāng)驗證失敗時)
form.addEventListener(
  'submit', function(event) {
    var notValid = false;
    var elements = event.target.elements;

    // 自定義驗證

    if (notValid) {
      // 取消提交
      event.preventDefault();
    }
  }
)

無刷新表單提交范例

常用的方式是通過 AJAX 進(jìn)行實現(xiàn),這里我們使用 iframe 來做中介代理實現(xiàn)。

form_ifram_submit_data.png

所需知識點:

  • form
  • target
  • iframe
<iframe name="targetFrame" class="f-hidden" style="display:none" id="result">

<form action="./api" method="post" target="targetFrame">
  <input name="isindex">
  <input name="a">
  <button>submit</button>
</form>
var frame = document.getElementById('result');
frame.addEventListener(
  'load', function(event) {
    try {
      var result = JSON.parse(
        frame.contentWindow.document.body.textContent
      );

      // 還原登陸按鈕狀態(tài)
      disabledSubmit(false);

      // 識別登陸結(jié)果
      if (result.code === 200) {
        showMessage('j-suc', 'success');
        form.reset();
      }
    } catch(ex) {
      // 忽略操作
    }
  }
)

表單應(yīng)用

首先需要知道服務(wù)器端登陸接口的相關(guān)信息,如下所示:

描述 數(shù)據(jù)信息
請求地址 /api/login
請求參數(shù) telephone 手機(jī)號碼; password 密碼 MD5 加密
返回結(jié)果 code 請求狀態(tài); result 請求數(shù)據(jù)結(jié)果
form_app_code.png
var form = document.forms.loginForm;

var message = document.getElementById('message');

// 通用邏輯封裝
function showMessage(class, message) {
  if(!class) {
    message.innerHTML = "";
    message.classList.remove('j-suc');
    message.classList.remove('j-err');
  } else {
    message.innerHTML = message;
    message.classList.add(class);
  }
}

function invalidInput (node, message) {
  showMessage('j-err', message);
  node.classList.add('j-err');
  node.focus();
}

function clearInvalid(node){
  showMessage();
  node.classList.remove('j-err');
}

function disabledSubmit(disabled) {
  form.loginBtn.disabled = !!disabled;
  var method = !disabled ? 'remove' : 'add';
  form.loginBtn.classList[method]('j-disabled');
}

// 驗證手機(jī)號碼(系統(tǒng)自帶方法)
form.telephone.addEventListener(
  'invalid', function(event) {
    event.preventDefault();
    invalidInput(form.telephone, 'invalid mobile number');
  }
);

// 驗證密碼
form.addEventListener(
  'submit', function(event) {
    var input = form.password;
    var password = input.value;
    errorMessage = '';
    if (password.length < 6) {
      errorMessage = 'password less than 6 char';
    } else if (!/\d./test(password) || !/[a-z]/i.test(password)) {
      errorMessage = 'password must contains number and letter'
    }

    if (!!errorMessage) {
      event.preventDefault();
      invalidInput(input, errorMessage);
      return;
    }
    // 提交表單代碼
    // ...
  }
);

// 提交表單
form.addEventListener(
  'submit', function(event){
    input.value = md5(password);
    disabledSubmit(true);
  }
);

// 狀態(tài)恢復(fù)
form.addEventListener(
  'focus', function(event) {
    // 錯誤還原
    clearInvalid(event.target);
    // 還原登陸按鈕狀態(tài)
    disabledSubmit(false);
  }
)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,488評論 6 531
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 98,034評論 3 414
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,327評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,554評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 71,337評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,883評論 1 321
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,975評論 3 439
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,114評論 0 286
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,625評論 1 332
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,555評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,737評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,244評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 43,973評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,362評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,615評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,343評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 47,699評論 2 370

推薦閱讀更多精彩內(nèi)容

  • 1.表單元素 編寫表單的三個步驟:構(gòu)建表單,服務(wù)器端處理,配置表單 以披薩預(yù)定表單為例 構(gòu)建完表單,需要服務(wù)器端提...
    hyt222閱讀 537評論 0 0
  • HTML 5 HTML5概述 因特網(wǎng)上的信息是以網(wǎng)頁的形式展示給用戶的,因此網(wǎng)頁是網(wǎng)絡(luò)信息傳遞的載體。網(wǎng)頁文件是用...
    阿啊阿吖丁閱讀 3,983評論 0 0
  • ??JavaScript 最初的一個應(yīng)用,就是分擔(dān)服務(wù)器處理表單的責(zé)任,打破處處依賴服務(wù)器的局面。 ??盡管目前的...
    霜天曉閱讀 676評論 0 3
  • 每個人的家庭背景不一樣,親戚之間的關(guān)系也錯綜復(fù)雜,親昵無私的,友好的,冷漠的,背后一套 表面一套的,仇恨詆毀的,聽...
    大顱不大閱讀 255評論 0 0
  • 鏈表(linked list)是一種線性表,但是并不會在物理存儲上按照線性順序存儲數(shù)據(jù),而是在每一個節(jié)點里存到下一...
    云時之間閱讀 988評論 0 2