案例一:更換網站背景
JS核心代碼
<script>document.querySelector('.bg-ipt').addEventListener('change', e => {//選擇圖片上傳,設置body背景const fd = new FormData()fd.append('img', e.target.files[0])axios({url: 'http://hmajax.itheima.net/api/uploadimg',method: 'post',data: fd}).then(result => {const imgUrl = result.data.data.urldocument.body.style.backgroundImage = `url(${imgUrl})`//上傳成功保存圖片網址localStorage.setItem('bgImg', imgUrl)})})//網頁運行后直接獲取圖片url網址const bgUrl = localStorage.getItem('bgImg')//本地有背景圖地址才設置bgUrl && (document.body.style.backgroundImage = `url(${bgUrl})`)</script>
案例叮囑:
明確核心步驟:STEP1:選擇圖片上傳,設置body背景
? ? ? ? ? ? ? ? ? ? ? ? ?STEP2:上傳成功時,保存url網址
? ? ? ? ? ? ? ? ? ? ? ? ?STEP3:網頁運行后,獲取url網址使用
1.上傳圖片資源后對服務器返回的數據進行處理,將其設置為body背景,注意body部分的樣式修改不需要先獲取元素可以直接修改,順帶將圖片網址保存在本地存儲中
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 圖片上傳
1.獲取圖片文件對象
2.使用 FormData 攜帶圖片文件
3.提交表單數據到服務器,使用圖片 url 網址
2.?網頁運行后直接獲取圖片url網址,但是需要注意只有當本地有背景圖地址才設置
這里注意使用&&的邏輯中斷
?案例二:個人信息設置
模塊一:信息渲染
//一打開網頁就需要獲取用戶的數據
const creator = '在逃的嗎嘍'
axios({url: 'http://hmajax.itheima.net/api/settings',params: {creator}
}).then(result => {const userObj = result.data.data//回顯數據到標簽上Object.keys(userObj).forEach(key => {//需要對頭像和性別進行特殊處理if (key === 'avatar') {document.querySelector('.prew').src = userObj[key]} else if (key === 'gender') {const gRadioList = document.querySelectorAll('.gender')const gNum = userObj[key]gRadioList[gNum].checked = true} else {document.querySelector(`.${key}`).value = userObj[key]}})
})
關鍵:
回顯數據到標簽上我們可以總結經驗:使用forEach方法遍歷Object.keys()方法得到的數組
Object.keys(userObj).forEach(key => {document.querySelector(`.${key}`).value = userObj[key]
}
模塊二:頭像修改? ? ? ? ? ? ? ??借鑒案例一更換網站背景
document.querySelector('.upload').addEventListener('change', e => {const fd = new FormData()fd.append('avator', e.target.files[0])fd.append('creator', creator)axios({url: 'http://hmajax.itheima.net/api/avatar',method: 'put',data: fd}).then(result => {const imgUrl = result.data.data.avatardocument.querySelector('.prew').src = imgUrl})
})
模塊三:提交表單 + 結果提示
document.querySelector('.submit').addEventListener('click', () => {const userForm = document.querySelector('.user-form')const userObj = serialize(userForm, { hash: true, empty: true })userObj.creator = creator//性別數字字符串轉成數字類型 userObj.gender = +userObj.genderaxios({url: 'http://hmajax.itheima.net/api/settings',method: 'put',data: userObj}).then(result => {const toastDom = document.querySelector('.my-toast')const toast = new bootstrap.Toast(toastDom)toast.show()})
})
Bootstrap提示框
?案例三:Promise + XHR獲取省份列表
<script>// 1. 創建Promise對象const p = new Promise((resolve, reject) => {// 2. 執行XHR異步代碼,獲取省份列表const xhr = new XMLHttpRequest()xhr.open('GET', 'http://hmajax.itheima.net/api/province')xhr.addEventListener('loadend', () => {// 2xx開頭的都是成功響應狀態碼if (xhr.status >= 200 && xhr.status < 300) {resolve(JSON.parse(xhr.response))} else {reject(new Error(xhr.response))}})xhr.send()})// 3. 關聯成功或失敗函數,做后續處理p.then(result => {console.log(result)document.querySelector('.my-p').innerHTML = result.list.join('<br>')}).catch(error => {// 錯誤對象要用console.dir詳細打印console.dir(error)document.querySelector('.my-p').innerHTML = error.message})</script>
注意:
1. 因為2xx開頭的都是成功響應狀態碼,xhr由此判斷響應成功還是失敗
2. reject()里面的參數一般跟new Error()
3. 錯誤對象要用console.dir詳細打印,里面需要的報錯信息一般是error.message
案例四:天氣預報?
模塊一:渲染函數
function getWeather(cityCode) {myAxios({url: 'http://hmajax.itheima.net/api/weather',params: {city: cityCode}}).then(result => {//console.log(result)const wObj = result.dataconst dateStr = `<span class="dateShort">${wObj.date}</span><span class="calendar">農歷 <span class="dateLunar">${wObj.dateLunar}</span></span>`document.querySelector('.title').innerHTML = dateStrdocument.querySelector('.area').innerHTML = wObj.areaconst nowWStr = `<div class="tem-box"><span class="temp"><span class="temperature">${wObj.temperature}</span><span>°</span></span></div><div class="climate-box"><div class="air"><span class="psPm25">${wObj.psPm25}</span><span class="psPm25Level">${wObj.psPm25Level}</span></div><ul class="weather-list"><li><img src="${wObj.weatherImg}" class="weatherImg" alt=""><span class="weather">${wObj.weather}</span></li><li class="windDirection">${wObj.windDirection}</li><li class="windPower">${wObj.windPower}</li></ul></div>`document.querySelector('.weather-box').innerHTML = nowWStrconst twObj = wObj.todayWeatherconst todayWStr = `<div class="range-box"><span>今天:</span><span class="range"><span class="weather">${twObj.weather}</span><span class="temNight">${twObj.temNight}</span><span>-</span><span class="temDay">${twObj.temDay}</span><span>℃</span></span></div><ul class="sun-list"><li><span>紫外線</span><span class="ultraviolet">${twObj.ultraviolet}</span></li><li><span>濕度</span><span class="humidity">${twObj.humidity}</span>%</li><li><span>日出</span><span class="sunriseTime">${twObj.sunriseTime}</span></li><li><span>日落</span><span class="sunsetTime">${twObj.sunsetTime}</span></li></ul>`document.querySelector('.today-weather').innerHTML = todayWStrconst dayForecast = wObj.dayForecastconst dayForecastStr = dayForecast.map(item => {return `<li class="item"><div class="date-box"><span class="dateFormat">${item.dateFormat}</span><span class="date">${item.date}</span></div><img src="${item.weatherImg}" alt="" class="weatherImg"><span class="weather">${item.weather}</span><div class="temp"><span class="temNight">${item.temNight}</span>-<span class="temDay">${item.temDay}</span><span>℃</span></div><div class="wind"><span class="windDirection">${item.windDirection}</span><span class="windPower">${item.windPower}</span></div></li>`}).join('')document.querySelector('.week-wrap').innerHTML = dayForecastStr})
}//默認進入網頁就要獲取天氣數據
getWeather('110100')
模板字符串渲染各部分并修改標簽內容
渲染小li時需要用map()和join()方法處理數組并且轉化成字符串
模塊二:搜索城市列表
document.querySelector('.search-city').addEventListener('input', (e) => {myAxios({url: 'http://hmajax.itheima.net/api/weather/city',params: {city: e.target.value}}).then(result => {// console.log(result)const liStr = result.data.map(item => {return `<li class="city-item" data-code="${item.code}">${item.name}</li>`}).join('')document.querySelector('.search-list').innerHTML = liStr})
})
渲染小li時需要用map()和join()方法處理數組并且轉化成字符串
模塊三:切換城市天氣
document.querySelector('.search-list').addEventListener('click', (e) => {if (e.target.classList.contains('city-item')) {const cityCode = e.target.dataset.codegetWeather(cityCode)}
})
注意:這里的小li是動態創建的,因此需要事件委托給父級綁定點擊事件,通過給小li添加自定義屬性獲取渲染函數的參數
?案例五:商品分類案例
<script>// 1. 獲取所有一級分類數據axios({url: 'http://hmajax.itheima.net/api/category/top'}).then(result => {//console.log(result)// 2. 遍歷id,創建獲取二級分類請求const secPromiseList = result.data.data.map(item => {return axios({url: 'http://hmajax.itheima.net/api/category/sub',params: {id: item.id // 一級分類id}})})console.log(secPromiseList) // [二級分類請求Promise對象,二級分類請求Promise對象,...]// 3. 合并所有二級分類Promise對象const p = Promise.all(secPromiseList)p.then(result => {console.log(result)// 4. 等待同時成功后,渲染頁面const htmlStr = result.map(item => {const dataObj = item.data.data // 取出關鍵數據對象return `<div class="item"><h3>${dataObj.name}</h3><ul>${dataObj.children.map(item => {return `<li><a href="javascript:;"><img src="${item.picture}"><p>${item.name}</p></a></li>`}).join('')}</ul></div>`}).join('')console.log(htmlStr)document.querySelector('.sub-list').innerHTML = htmlStr})})
</script>
注意:
1.return的值可以是創建獲取二級分類請求
2.返回的模板字符串可以用兩次map()嵌套解決