先決條件: | 基本的計(jì)算機(jī)素養(yǎng),對(duì)HTML和CSS的基本了解,熟悉JavaScript基礎(chǔ)知識(shí)(請(qǐng)參見第一步和構(gòu)建塊 / a>)和OOJS基礎(chǔ)知識(shí)(請(qǐng)參見對(duì)象簡(jiǎn)介)。 |
---|---|
目的: | 要了解如何使用存儲(chǔ)在JSON中的數(shù)據(jù),并創(chuàng)建自己的JSON對(duì)象。 |
JSON 是一種數(shù)據(jù)格式,遵循JavaScript對(duì)象語法,該語法由 a class ="external"> Douglas Crockford 。 即使它是基于JavaScript語法,它可以獨(dú)立于JavaScript使用,并且許多編程環(huán)境具有讀取(解析)和生成JSON的能力。
JSON可以作為對(duì)象或字符串存在 - 前者用于從JSON讀取數(shù)據(jù),后者用于在網(wǎng)絡(luò)上發(fā)送JSON。 這不是一個(gè)大問題 - JavaScript提供了一個(gè)全局 JSON 對(duì)象 有可用于在兩者之間轉(zhuǎn)換的方法。
JSON對(duì)象可以存儲(chǔ)在自己的文件中,基本上只是一個(gè)擴(kuò)展名為 .json
和 mozilla.org/zh-CN/docs/Glossary/MIME_type\"> MIME類型的 application / json
。
我們?cè)谏厦嬉呀?jīng)暗示,JSON對(duì)象基本上是一個(gè)JavaScript對(duì)象,這是最正確的。 您可以在JSON中包含與標(biāo)準(zhǔn)JavaScript對(duì)象(字符串,數(shù)字,數(shù)組,布爾值和其他對(duì)象字面值)中相同的基本數(shù)據(jù)類型。 這允許您構(gòu)造數(shù)據(jù)層次結(jié)構(gòu),如下所示:
{ ? "squadName" : "Super hero squad", ? "homeTown" : "Metro City", ? "formed" : 2016, ? "secretBase" : "Super tower", "active" : true, ? "members" : [ ??? { ????? "name" : "Molecule Man", ????? "age" : 29, ????? "secretIdentity" : "Dan Jukes", ????? "powers" : [ ??????? "Radiation resistance", ??????? "Turning tiny", ??????? "Radiation blast" ????? ] ??? }, ??? { ????? "name" : "Madame Uppercut", ????? "age" : 39, ????? "secretIdentity" : "Jane Wilson", ????? "powers" : [ ??????? "Million tonne punch", ??????? "Damage resistance", ??????? "Superhuman reflexes" ????? ] ??? }, ??? { ????? "name" : "Eternal Flame", ????? "age" : 1000000, ????? "secretIdentity" : "Unknown", ????? "powers" : [ ??????? "Immortality", ??????? "Heat Immunity", ??????? "Inferno", ??????? "Teleportation", ??????? "Interdimensional travel" ????? ] ??? } ? ] }
如果我們將這個(gè)對(duì)象加載到JavaScript程序中,保存在一個(gè)叫做 superHeroes
的變量中,我們就可以使用我們?cè)?a href="</span"> "/ webstart / Objects / Basics"> JavaScript對(duì)象基礎(chǔ)文章。 例如:
superHeroes.hometown superHeroes["active"]
要在層次結(jié)構(gòu)中進(jìn)一步訪問數(shù)據(jù),您只需將所需的屬性名稱和數(shù)組索引鏈接在一起。 例如,要訪問成員列表中列出的第二個(gè)英雄的第三超級(jí)大國(guó),您可以這樣做:
superHeroes["members"][1]["powers"][2]
superHeroes
.members
property, so we use ["members"]
.members
contains an array populated by objects. We want to access the second object inside the array, so we use [1]
.powers
property, so we use ["powers"]
.powers
property is an array containing the selected hero's superpowers. We want the third one, so we use [2]
.注意:我們已在上面的 /json/JSONTest.html\">JSONText.html 示例(請(qǐng)參閱 /json/JSONTest.html\">源代碼)。 嘗試加載,然后通過瀏覽器的JavaScript控制臺(tái)訪問變量中的數(shù)據(jù)。
上面我們說"我們已經(jīng)暗示JSON對(duì)象基本上是一個(gè)JavaScript對(duì)象,這是正確的" - 我們說"大多數(shù)正確"的原因是因?yàn)閿?shù)組也可以是一個(gè)有效的JSON對(duì)象,例如:
[ { "name" : "Molecule Man", "age" : 29, "secretIdentity" : "Dan Jukes", "powers" : [ "Radiation resistance", "Turning tiny", "Radiation blast" ] }, { ??? "name" : "Madame Uppercut", ??? "age" : 39, ??? "secretIdentity" : "Jane Wilson", ??? "powers" : [ ????? "Million tonne punch", ????? "Damage resistance", ????? "Superhuman reflexes" ??? ] ? } ]
上面是完全有效的JSON。 你只需要從數(shù)組索引開始訪問數(shù)組項(xiàng),例如 [0] ["powers"] [0]
。
因此,讓我們通過一個(gè)例子來說明如何在網(wǎng)站上使用一些JSON數(shù)據(jù)。
首先,制作我們的英雄的本地副本。 html 和 style.css a>文件。 后者包含一些簡(jiǎn)單的CSS來為我們的頁面設(shè)計(jì)樣式,而前者包含一些非常簡(jiǎn)單的body HTML:
<header> </header> <section> </section>
加上 < script>
元素,以包含我們將在此處撰寫的JavaScript代碼 行使。 目前它只包含兩行,它們引用了 < header>
和 < section>
元素并將其存儲(chǔ)在變量中:
var header = document.querySelector('header'); var section = document.querySelector('section');
我們已將我們的JSON數(shù)據(jù)提供給我們的GitHub,網(wǎng)址為: https:/ /mdn.github.io/learning-area/javascript/oojs/json/superheroes.json 。
我們將把它加載到我們的頁面,并使用一些漂亮的DOM操作來顯示它,像這樣:
要將我們的JSON加載到我們的網(wǎng)頁中,我們將使用名為 XMLHttpRequest
的API(通常稱為 XHR )。 這是一個(gè)非常有用的JavaScript對(duì)象,它允許我們通過JavaScript(例如圖像,文本,JSON,甚至HTML片段)來從服務(wù)器檢索資源,這意味著我們可以更新內(nèi)容的小部分,而不必重新加載整個(gè) 頁。 這導(dǎo)致更響應(yīng)的網(wǎng)頁,并聽起來令人興奮,但不幸的是超出了本文的范圍,教更多的細(xì)節(jié)。
var requestURL = 'https://mdn.github.io/learning-area/javascript/oojs/json/superheroes.json';
XMLHttpRequest
constructor, using the new
keyword. Add the following below your last line: var request = new XMLHttpRequest();
open()
method. Add the following line: request.open('GET', requestURL);
這至少需要兩個(gè)參數(shù) - 還有其他可選參數(shù)可用。 對(duì)于這個(gè)簡(jiǎn)單的例子,我們只需要兩個(gè)強(qiáng)制的:
GET
is fine, as we are just retrieving some simple data.responseType
to JSON, so the server will know we want a JSON object returned, and sending the request with the send()
method: request.responseType = 'json'; request.send();
request.onload = function() { var superHeroes = request.response; populateHeader(superHeroes); showHeroes(superHeroes); }
這里我們存儲(chǔ)對(duì)我們的請(qǐng)求的響應(yīng)(可在 響應(yīng)
> 屬性)在一個(gè)名為 superHeroes
的變量中; 這個(gè)變量現(xiàn)在將包含我們的JSON! 然后,我們將該JSON傳遞給兩個(gè)函數(shù)調(diào)用 - 第一個(gè)將用正確的數(shù)據(jù)填充< header>
,而第二個(gè)將為團(tuán)隊(duì)中的每個(gè)英雄創(chuàng)建一個(gè)信息卡, 將其插入到< section>
中。
我們將代碼包裝在事件處理程序中,當(dāng)load事件觸發(fā)請(qǐng)求對(duì)象時(shí)運(yùn)行(參見 XMLHttpRequestEventTarget / onload"> onload
) - 這是因?yàn)閘oad事件在響應(yīng)成功返回時(shí)觸發(fā); 這樣做保證 request.response
一定會(huì)可用,當(dāng)我們?cè)噲D做一些事情。
現(xiàn)在我們已經(jīng)檢索了我們的JSON數(shù)據(jù),讓我們通過寫我們上面提到的兩個(gè)函數(shù)來使用它。 首先,在上面的代碼下面添加以下函數(shù)定義:
function populateHeader(jsonObj) { var myH1 = document.createElement('h1'); myH1.textContent = jsonObj['squadName']; header.appendChild(myH1); var myPara = document.createElement('p'); myPara.textContent = 'Hometown: ' + jsonObj['homeTown'] + ' // Formed: ' + jsonObj['formed']; header.appendChild(myPara); }
我們調(diào)用了參數(shù) jsonObj
,這就是我們需要調(diào)用它里面的JSON對(duì)象。 在這里,我們首先使用創(chuàng)建
> createElement() ,將其< h1>
元素 > textContent
等于 squadName
屬性 JSON,然后使用 appendChild()將其附加到標(biāo)題
。 然后,我們對(duì)一個(gè)段落進(jìn)行非常類似的操作:創(chuàng)建它,設(shè)置其文本內(nèi)容并將其附加到標(biāo)題。 唯一的區(qū)別是其文本設(shè)置為包含JSON的 homeTown
和形成
屬性的連接字符串。
接下來,在代碼的底部添加以下函數(shù),創(chuàng)建并顯示超級(jí)英雄卡:
function showHeroes(jsonObj) { var heroes = jsonObj['members']; for(i = 0; i < heroes.length; i++) { var myArticle = document.createElement('article'); var myH2 = document.createElement('h2'); var myPara1 = document.createElement('p'); var myPara2 = document.createElement('p'); var myPara3 = document.createElement('p'); var myList = document.createElement('ul'); myH2.textContent = heroes[i].name; myPara1.textContent = 'Secret identity: ' + heroes[i].secretIdentity; myPara2.textContent = 'Age: ' + heroes[i].age; myPara3.textContent = 'Superpowers:'; var superPowers = heroes[i].powers; for(j = 0; j < superPowers.length; j++) { var listItem = document.createElement('li'); listItem.textContent = superPowers[j]; myList.appendChild(listItem); } myArticle.appendChild(myH2); myArticle.appendChild(myPara1); myArticle.appendChild(myPara2); myArticle.appendChild(myPara3); myArticle.appendChild(myList); section.appendChild(myArticle); } }
首先,我們將JSON的 members
屬性存儲(chǔ)在一個(gè)新變量中。 此數(shù)組包含多個(gè)對(duì)象,其中包含每個(gè)英雄的信息。
接下來,我們使用 for循環(huán)循環(huán)訪問數(shù)組中的每個(gè)對(duì)象。 對(duì)于每一個(gè),我們:
<article>
, an <h2>
, three <p>
s, and a <ul>
.name
.secretIdentity
, age
, and a line saying "Superpowers:" to introduce the information in the list.powers
property in another new variable called superPowers
— this contains an array that lists the current hero's superpowers.for
loop to loop through the current hero's superpowers — for each one we create a <li>
element, put the superpower inside it, then put the listItem
inside the <ul>
element (myList
) using appendChild()
.<h2>
, <p>
s, and <ul>
inside the <article>
(myArticle
), then append the <article>
inside the <section>
. The order in which things are appended is important, as this is the order they will be displayed inside the HTML.注意:如果您無法使示例工作,請(qǐng)嘗試參考我們的 master / javascript / oojs / json / heroes-finished.html"> heroes-finished.html 源代碼(參見 -area / javascript / oojs / json / heroes-finished.html">運(yùn)行實(shí)時(shí))。
注意:如果您在使用我們用于訪問JSON的點(diǎn)/括號(hào)符號(hào)時(shí)遇到問題,可以使用 github.io/learning-area/javascript/oojs/json/superheroes.json\">superheroes.json 文件在另一個(gè)選項(xiàng)卡或文本編輯器中打開,并在查看我們的JavaScript時(shí)參考它。 您還應(yīng)參閱我們的 JavaScript對(duì)象基礎(chǔ)知識(shí)文章,了解點(diǎn)和括號(hào)符號(hào)的更多信息。
上面的例子在訪問JSON方面很簡(jiǎn)單,因?yàn)槲覀冊(cè)O(shè)置XHR以JSON格式返回響應(yīng),使用:
request.responseType = 'json';
但有時(shí)我們不那么幸運(yùn) - 有時(shí)我們會(huì)收到一些格式化為文本字符串的JSON數(shù)據(jù),我們需要將它轉(zhuǎn)換為一個(gè)對(duì)象。 當(dāng)我們想要發(fā)送JSON數(shù)據(jù)作為某種消息時(shí),我們經(jīng)常需要將其轉(zhuǎn)換為字符串,以使其正常工作。 幸運(yùn)的是,這兩個(gè)問題在Web開發(fā)中非常常見,內(nèi)置的 JSON / a>對(duì)象被添加到瀏覽器很久以前,包含以下兩種方法:
parse()
: Accepts a JSON object in text string form as a parameter, and returns the corresponding object.stringify()
: Accepts a JSON object as a parameter, and returns the equivalent text string form.您可以在我們的 > heroes-finished-json-parse.html example(see the json / heroes-finished-json-parse.html">源代碼) - 這與我們之前構(gòu)建的示例完全相同,只是我們?cè)O(shè)置XHR將JSON作為文本返回,然后使用 parse()
將其轉(zhuǎn)換為實(shí)際的JSON對(duì)象。 代碼的關(guān)鍵代碼片段在這里:
request.open('GET', requestURL); request.responseType = 'text'; // now we're getting a string! request.send(); request.onload = function() { var superHeroesText = request.response; // get the string from the response var superHeroes = JSON.parse(superHeroesText); // convert it to an object populateHeader(superHeroes); showHeroes(superHeroes); }
正如你可能猜到的, stringify()
工作方式相反。 嘗試在瀏覽器的JavaScript控制臺(tái)中輸入以下行,以便在操作中查看它:
var myJSON = { "name" : "Chris", "age" : "38" }; myJSON var myString = JSON.stringify(myJSON); myString
這里我們創(chuàng)建一個(gè)JSON對(duì)象,然后檢查它包含什么,然后使用 stringify()
將返回值保存在一個(gè)新的變量,然后再次檢查它轉(zhuǎn)換為字符串。
在本文中,我們?yōu)槟峁┝嗽诔绦蛑惺褂肑SON的簡(jiǎn)單指南,包括如何創(chuàng)建和解析JSON,以及如何訪問其中鎖定的數(shù)據(jù)。 在下一篇文章中,我們將開始討論面向?qū)ο蟮腏avaScript。
更多建議: