Search K
Appearance
Appearance
以下哪个方法可以把 JS 数据类型转成 JSON 字符串类型?
JSON.stringify()JSON.parse()JSON.stringify() 方法用于将 JavaScript 对象转换为 JSON 字符串。JSON.parse() 则用于将 JSON 字符串解析为 JavaScript 对象。以下哪个方法,会延迟一段时间后,再执行函数体,并执行一次就停止?
setTimeout(函数体,毫秒值)setInterval(函数体,毫秒值)setTimeout 方法用于在指定的毫秒数后执行一次函数体。setInterval 方法会每隔指定的毫秒数执行一次函数体,不停地重复执行,直到被取消。setTimeout。下面代码 result 结果是多少?
let obj = {
status: 240,
};
const result = obj.status >= 200 && obj.status < 300;result 变量的值是根据 obj.status 的范围判断的,因为 obj.status 的值是 240,它同时满足 obj.status >= 200 和 obj.status < 300 这两个条件,因此 result 的值是 true。下面代码运行结果是多少?
let result = 'http://www.baidu.com';
result += '?a=10';
result += '&b=20';'http://www.baidu.com''?a=10''&b=20''http://www.baidu.com?a=10&b=20'result 为 'http://www.baidu.com',然后使用 += 运算符追加 '?a=10' 和 '&b=20',最终得到的字符串是 'http://www.baidu.com?a=10&b=20'。哪个事件能实时检测到输入框值的变化?
input 事件change 事件input 事件能够实时检测到输入框值的变化,无论是用户通过键盘输入、粘贴、剪切等方式修改输入框的值,都会触发 input 事件。change 事件在用户完成输入并移出输入框时触发,不会像 input 事件那样实时反映输入框的变化。学习目标
XMLHttpRequest(XHR)对象用于与服务器交互。通过 XMLHttpRequest 可以在不刷新页面的情况下请求特定 URL,获取数据。这允许网页在不影响用户操作的情况下,更新页面的局部内容。XMLHttpRequest 在 AJAX 编程中被大量使用。XMLHttpRequest 可以用于获取任何类型的数据,而不仅仅是 XML。它甚至支持 HTTP 以外的协议(包括 file:// 和 FTP),尽管可能受到更多出于安全等原因的限制。AJAX 是浏览器与服务器通信的技术,采用 XMLHttpRequest 对象相关代码
axios 是对 XHR 相关代码进行了封装,让我们只关心传递的接口参数
学习 XHR 也是了解 axios 内部与服务器交互过程的真正原理

const xhr = new XMLHttpRequest();
xhr.open('请求方法', '请求 url 网址');
xhr.addEventListener('loadend', () => {
// 响应结果
console.log(xhr.response);
});
xhr.send();目标:使用 XMLHttpRequest 对象与服务器通信
loadend 事件,接收响应结果<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>20 获取省份列表数据 XMLHttpRequest</title>
</head>
<body style="padding: 3em;">
<p class="province-list"></p>
<script>
// - 1. 创建 XMLHttpRequest 对象
// - 2. 配置请求方法和请求 url 地址
// - 3. 监听 loadend 事件,接收响应结果
// - 4. 发起请求
// 1. 创建 XMLHttpRequest 对象
const xhr = new XMLHttpRequest()
// 2. 配置请求方法和请求 url 地址
xhr.open('get', 'http://hmajax.itheima.net/api/province')
// 3. 监听 loadend 事件,接收响应结果
xhr.addEventListener('loadend', function () {
console.log(xhr.response)
console.log(JSON.parse(xhr.response).list)
console.log(JSON.parse(xhr.response).list.join(' '))
document.querySelector('.province-list').innerHTML = JSON.parse(xhr.response).list.join(' ')
})
// 4. 发起请求
xhr.send()
</script>
</body>
</html>AJAX 原理是什么?
XMLHttpRequest为什么学习 XHR?
XHR 使用步骤?
open 方法,设置 url 和请求方法loadend 事件,接收结果send 方法,发起请求http://xxxx.com/xxx/xxx?参数名1=值1&参数名2=值2url 后面携带查询参数字符串,没有 axios 帮助我们把 params 参数拼接到 url 字符串后面了<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>21 获取甘肃省下属的城市列表</title>
</head>
<body>
<p class="province-city"></p>
<script>
// 目标:使用 XHR 携带查询参数,展示甘肃省下属的城市列表
// api: http://hmajax.itheima.net/api/city
// 1. 创建 XHR 对象
const xhr = new XMLHttpRequest()
// 2. 配置请求方法和请求 url 地址
xhr.open('get', 'http://hmajax.itheima.net/api/city?pname=甘肃省')
// 3. 监听 loadend 事件,接收响应结果
xhr.addEventListener('loadend', () => {
console.log(xhr.response)
console.log(JSON.parse(xhr.response).list)
document.querySelector('.province-city').innerHTML = JSON.parse(xhr.response).list.join(' ')
})
// 4. 发起请求
xhr.send()
</script>
</body>
</html>XHR 如何携带查询参数?
url? 后面按照指定格式拼接参数名和值xhr.open('get', `http://hmajax.itheima.net/api/area?pname=${pname}&cname=${cname}}`);JS 对象如何转成查询参数格式字符串?
URLSearchParams 把参数对象转成 参数名=值&参数名=值 格式的字符串const paramsObj = new URLSearchParams({ pname, cname });
const queryString = paramsObj.toString();
console.log(queryString);
xhr.open('get', `http://hmajax.itheima.net/api/area?${queryString}`);<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>22 地区查询</title>
<link rel="stylesheet" href="./css/bootstrap.min.css">
</head>
<body class="p-3">
<div class="container">
<h2>04 查询地区列表</h2>
<form class="form-group row" id="editForm">
<div class="mb-3 col">
<label for="province" class="form-label">省份</label>
<select class="form-select" id="province" name="province">
<option value="北京" selected>北京</option>
</select>
</div>
<div class="mb-3 col">
<label for="city" class="form-label">城市</label>
<select class="form-select" id="city" name="city">
<option value="北京市" selected>北京市</option>
</select>
</div>
</form>
<button class="btn btn-primary sel-btn mb-3" type="button">查询</button>
<div class="mt-3 result">
<p>地区列表</p>
<ul class="list-group">
<li class="list-group-item">东城区</li>
</ul>
</div>
</div>
<script>
// 1. 获取省份列表数据添加到省份下拉菜单中
// 2. 为省份下拉菜单绑定 onchange 事件,当省份发生改变时,获取对应的城市列表数据添加到城市下拉菜单中
// 3. 为查询按钮绑定点击事件,当点击查询按钮时,获取当前选中的省份和城市,发送请求获取对应的地区列表数据,展示到页面中
// 1. 获取省份列表数据添加到省份下拉菜单中
const xhr = new XMLHttpRequest();
xhr.open('get', 'http://hmajax.itheima.net/api/province');
xhr.addEventListener('loadend', () => {
console.log(JSON.parse(xhr.responseText).list.join(' '));
document.querySelector('#province').innerHTML = JSON.parse(xhr.responseText)
.list.map((item) => `<option value="${item}">${item}</option>`)
.join('');
});
xhr.send();
// 2. 为省份下拉菜单绑定 onchange 事件,当省份发生改变时,获取对应的城市列表数据添加到城市下拉菜单中
document.querySelector('#province').addEventListener('change', () => {
const xhr = new XMLHttpRequest();
xhr.open('get', `http://hmajax.itheima.net/api/city?pname=${this.value}`);
xhr.addEventListener('loadend', () => {
console.log(JSON.parse(xhr.responseText).list.join(' '));
document.querySelector('#city').innerHTML = JSON.parse(xhr.responseText)
.list.map((item) => `<option value="${item}">${item}</option>`)
.join('');
});
xhr.send();
});
// 3. 为查询按钮绑定点击事件,当点击查询按钮时,获取当前选中的省份和城市,发送请求获取对应的地区列表数据,展示到页面中
document.querySelector('.sel-btn').addEventListener('click', () => {
// 收集省份和城市名字
const pname = document.querySelector('#province').value;
const cname = document.querySelector('#city').value;
// const xhr = new XMLHttpRequest();
// xhr.open('get', `http://hmajax.itheima.net/api/area?pname=${pname}&cname=${cname}}`);
// xhr.addEventListener('loadend', () => {
// console.log(JSON.parse(xhr.responseText).list.join(' '));
// document.querySelector('.list-group').innerHTML = `${JSON.parse(xhr.responseText)
// .list.map((item) => `<li class="list-group-item">${item}</li>`)
// .join('')}`;
// });
// xhr.send();
const xhr = new XMLHttpRequest();
// xhr.open('get', `http://hmajax.itheima.net/api/area?pname=${pname}&cname=${cname}`)
// 组织查询参数字符串
const paramsObj = new URLSearchParams({ pname, cname });
const queryString = paramsObj.toString();
console.log(queryString);
xhr.open('get', `http://hmajax.itheima.net/api/area?${queryString}`);
xhr.addEventListener('loadend', () => {
console.log(JSON.parse(xhr.responseText).list.join(' '));
document.querySelector('.list-group').innerHTML = `${JSON.parse(xhr.responseText)
.list.map((item) => `<li class="list-group-item">${item}</li>`)
.join('')}`;
});
xhr.send();
});
</script>
</body>
</html><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>23 注册账号 (xhr 数据提交 )</title>
<link rel="stylesheet" href="./css/bootstrap.min.css">
</head>
<body class="p-3 mb-2 d-flex justify-content-center align-items-center vh-100">
<div class="container p-5 shadow" style="width: 500px; background-color: #f5f5f5; border-radius: 10px;">
<div class="toast position-fixed top-0 start-50 translate-middle-x" role="alert" aria-live="assertive"
aria-atomic="true" data-bs-delay="2000">
<div class="toast-body">
操作成功
</div>
</div>
<h2>05 注册账号</h2>
<form class="form-group mt-5">
<div class="mb-3">
<label for="exampleInputUsername" class="form-label">Username</label>
<input type="text" class="form-control" id="username" name="username" placeholder="鸡你太美cxk"
aria-describedby="usernameHelp">
<div id="usernameHelp" class="form-text">中英文和数字组成,最少 8 位。</div>
</div>
<div class="mb-3">
<label for="exampleInputPassword1" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" placeholder="987654321"
aria-describedby="passwordHelp">
<div id="passwordHelp" class="form-text">最少 6 位。</div>
</div>
</form>
<button type="submit" class="btn btn-primary mb-3">注册账号</button>
</div>
<script src="./js/bootstrap.min.js"></script>
<script>
const submitBtn = document.querySelector('button[type=submit]');
submitBtn.addEventListener('click', () => {
var username = document.querySelector('#username').value;
var password = document.querySelector('#password').value;
console.log(username, password);
var xhr = new XMLHttpRequest();
// axios.post("http://hmajax.itheima.net/api/register", { username, password });
xhr.open('POST', 'http://hmajax.itheima.net/api/register');
xhr.addEventListener('loadend', () => {
console.log(xhr.responseText);
console.log(JSON.parse(xhr.responseText).message);
const toastDom = document.querySelector('.toast');
const toast = new bootstrap.Toast(toastDom);
// 设置 toast 的内容
toastDom.querySelector('.toast-body').textContent = JSON.parse(xhr.responseText).message;
toastDom.querySelector('.toast-body').style.backgroundColor = 'var(--bs-primary)';
toastDom.querySelector('.toast-body').classList.add('p-3', 'rounded-3');
// 显示提示框
toast.show();
});
xhr.setRequestHeader('Content-Type', 'application/json');
// const userObj = { username, password }
// const userStr = JSON.stringify(userObj)
// xhr.send(userStr)
xhr.send(JSON.stringify({ username, password }));
});
</script>
</body>
</html>XHR 如何提交请求体数据?
send 中携带请求体数据,要按照后端要求的内容类型携带xhr.send(JSON.stringify({ username, password }));什么是 Promise?
Promise 是一个代理,它代表一个在创建 promise 时不一定已知的值。它允许你将处理程序与异步操作的最终成功值或失败原因关联起来。这使得异步方法可以像同步方法一样返回值:异步方法不会立即返回最终值,而是返回一个 promise,以便在将来的某个时间点提供该值。Promise 的好处是什么?
逻辑更清晰(成功或失败会关联后续的处理函数)
了解 axios 函数内部运作的机制

能解决回调函数地狱问题(后面会讲到),今天先来看下它的基础使用
// 1. 创建 Promise 对象
const p = new Promise((resolve, reject) => {
// 2. 执行异步任务 - 并传递结果
// 成功调用:resolve(值) 触发 then() 执行
// 失败调用:reject(值) 触发 catch() 执行
});
// 3. 接收结果
p.then((result) => {
// 成功
}).catch((error) => {
// 失败
});<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>24 认识 Promise 状态</title>
</head>
<body>
<script>
// 目标:认识 Promise 状态
// 1. 创建 Promise 对象(pending-待定状态)
// 2. 执行异步代码
// 3. 获取结果
// 1. 创建 Promise 对象(pending-待定状态)
const promise = new Promise((resolve, reject) => {
// Promise 对象创建时,这里的代码都会执行了
// 2. 执行异步代码
setTimeout(() => {
// resolve() => 'fulfilled 状态 - 已兑现' => then()
// resolve('成功的结果');
resolve('模拟 AJAX 请求 - 成功结果');
// reject() => 'rejected 状态 - 已拒绝' => catch()
// reject('模拟 AJAX 请求 - 失败结果')
reject(new Error('模拟 AJAX 请求 - 失败结果'));
}, 1000);
});
console.log(promise);
// 3. 获取结果
promise
.then((value) => {
console.log('成功的结果:', value);
})
.catch((reason) => {
console.log('失败的结果:', reason);
});
</script>
</body>
</html>什么是 Promise ?
为什么学习 Promise ?
axios 内部运作的原理Promise 使用步骤?
new Promise 对象执行异步任务。resolve 关联 then 的回调函数传递成功结果。reject 关联 catch 的回调函数传递失败结果。// 1. 创建 Promise 对象(pending-待定状态)
const promise = new Promise((resolve, reject) => {
// 2. 执行异步代码
setTimeout(() => {
resolve('模拟 AJAX 请求 - 成功结果');
reject(new Error('模拟 AJAX 请求 - 失败结果'));
}, 1000);
});
console.log(promise);
// 3. 获取结果
promise
.then((value) => {
console.log('成功的结果:', value);
})
.catch((reason) => {
console.log('失败的结果:', reason);
});为什么要了解 Promise 的三种状态?
Promise 有哪三种状态?
每个 Promise 对象必定处于以下三种状态之一
状态的英文字符串,可以理解为 Promise 对象内的字符串标识符,用于判断什么时候调用哪一个处理函数
一个待定的 Promise 最终状态可以是已兑现并返回一个值,或者是已拒绝并返回一个原因(错误)。当其中任意一种情况发生时,通过 Promise 的 then 方法串联的处理程序将被调用。如果绑定相应处理程序时 Promise 已经兑现或拒绝,这处理程序将被立即调用,因此在异步操作完成和绑定处理程序之间不存在竞态条件。
Promise 的状态改变有什么用:调用对应函数,改变 Promise 对象状态后,内部触发对应回调函数传参并执行

注意:每个 Promise 对象一旦被兑现/拒绝,那就是已敲定了,状态无法再被改变
创建 Promise 对象
执行 XHR 异步代码,获取省份列表数据
关联成功或失败回调函数,做后续的处理
错误情况:用地址错了 404 演示
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>25 使用 Promise 和 XHR 获取省份列表</title>
</head>
<body style="padding: 3em;">
<p class="province-list"></p>
<script>
/**
* 目标:使用 Promise 管理 XHR 请求省份列表
* 1. 创建 Promise 对象
* 2. 执行 XHR 异步代码,获取省份列表
* 3. 关联成功或失败函数,做后续处理
*/
// 1. 创建 Promise 对象
const promise = new Promise((resolve, reject) => {
// 2. 执行 XHR 异步代码,获取省份列表
const xhr = new XMLHttpRequest()
xhr.open('get', 'http://hmajax.itheima.net/api/province')
xhr.addEventListener('loadend', () => {
// xhr 如何判断响应成功还是失败的?
// 2xx 开头的都是成功响应状态码
// if (xhr.status >= 200 && xhr.status < 300) {
if (/^2\d{2}$/.test(xhr.status)) {
// 成功
resolve(JSON.parse(xhr.response))
} else {
// 失败
reject(new Error(xhr.response))
}
})
xhr.send()
})
// 3. 关联成功或失败函数,做后续处理
promise
.then((res) => {
console.log('成功的结果:', res.list)
document.querySelector('.province-list').innerHTML = res.list.join(' ')
})
.catch((err) => {
console.log('失败的结果:', err)
document.querySelector('.province-list').innerHTML = err.message;
})
</script>
</body>
</html>基于 Promise 和 XHR 封装 myAxios 函数
核心语法
function myAxios(config) {
return new Promise((resolve, reject) => {
// XHR 请求
// 调用成功/失败的处理程序
});
}
myAxios({
url: '目标资源地址',
})
.then((result) => {})
.catch((error) => {});步骤:
myAxios 函数,接收配置对象,返回 Promise 对象XHR 请求,默认请求方法为 GETmyAxios 函数,获取省份列表展示<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>26 简易 axios 函数 获取省份列表</title>
</head>
<body style="padding: 3em;">
<p class="province-list"></p>
<script>
/**
* 目标:封装_简易 axios 函数_获取省份列表
* 1. 定义 myAxios 函数,接收配置对象,返回 Promise 对象
* 2. 发起 XHR 请求,默认请求方法为 GET
* 3. 调用成功/失败的处理程序
* 4. 使用 myAxios 函数,获取省份列表展示
*/
// 1. 定义 myAxios 函数,接收配置对象,返回 Promise 对象
function myAxios(config) {
// 返回 Promise 对象
return new Promise((resolve, reject) => {
// 2. 发起 XHR 请求,默认请求方法为 GET
const xhr = new XMLHttpRequest()
// 判断是否传入请求方法
// if (config.method) {
// xhr.open(config.method, config.url)
// } else {
// xhr.open('get', config.url)
// }
xhr.open(config.method || 'get', config.url)
// 判断是否传入请求头
// if (config.headers) {
// for (let key in config.headers) {
// xhr.setRequestHeader(key, config.headers[key])
// }
// }
// 3. 调用成功/失败的处理程序
xhr.addEventListener('loadend', () => {
// if (xhr.status >= 200 && xhr.status < 300) {
if (/^2\d{2}$/.test(xhr.status)) {
// 成功
resolve(JSON.parse(xhr.response))
} else {
// 失败
reject(new Error(xhr.response))
}
})
xhr.send()
})
}
// 4. 使用 myAxios 函数,获取省份列表展示
myAxios({
url: 'http://hmajax.itheima.net/api/province'
}).then((res) => {
console.log(res)
document.querySelector('.province-list').innerHTML = res.list.join(' ')
}).catch((err) => {
console.log(err)
document.querySelector('.province-list').innerHTML = err.message
})
</script>
</body>
</html>修改 myAxios 函数支持传递查询参数,获取陕西省的城市列表。
params 选项,携带查询参数myAxios 函数,获取城市列表<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>27 简易 axios 函数 获取陕西省的城市列表</title>
</head>
<body style="padding: 3em;">
<p class="province-city"></p>
<script>
/**
* 1. 判断有 `params` 选项,携带查询参数
* 2. 使用 `myAxios` 函数,获取城市列表展示
*/
function myAxios(config) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
// 判断有 `params` 选项,携带查询参数
if (config.params) {
var params = ''
// 遍历 `params` 对象,拼接查询参数字符串
for (var key in config.params) {
params += `${key}=${config.params[key]}&`
}
params = params.slice(0, -1) // 去掉最后一个 `&`
config.url += '?' + params
}
console.log(config.url)
xhr.open(config.method || 'get', config.url)
xhr.addEventListener('loadend', () => {
if (/^2\d{2}$/.test(xhr.status)) {
console.log(JSON.parse(xhr.response))
resolve(JSON.parse(xhr.response))
} else {
reject(new Error(xhr.response))
}
})
xhr.send()
})
}
// 使用 `myAxios` 函数,获取城市列表展示
myAxios({
url: 'http://hmajax.itheima.net/api/city',
params: {
pname: '陕西省'
}
}).then((res) => {
document.querySelector('.province-city').innerHTML = res.list.join(' ')
}).catch((err) => {
console.log(err.message)
document.querySelector('.province-city').innerHTML = err.message
})
</script>
</body>
</html><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>28 简易 axios 函数 获取地区列表</title>
<link rel="stylesheet" href="./css/bootstrap.min.css">
</head>
<body class="p-3">
<div class="container">
<h2>04 查询地区列表</h2>
<form class="form-group row" id="editForm">
<div class="mb-3 col">
<label for="province" class="form-label">省份</label>
<select class="form-select" id="province" name="province">
<option value="北京" selected>北京</option>
</select>
</div>
<div class="mb-3 col">
<label for="city" class="form-label">城市</label>
<select class="form-select" id="city" name="city">
<option value="北京市" selected>北京市</option>
</select>
</div>
</form>
<button class="btn btn-primary sel-btn mb-3" type="button">查询</button>
<div class="mt-3 result">
<p>地区列表</p>
<ul class="list-group">
<li class="list-group-item">东城区</li>
</ul>
</div>
</div>
<script>
/**
* 目标:封装_简易 axios 函数_获取地区列表
* 1. 判断有 params 选项,携带查询参数
* 2. 使用 URLSearchParams 转换,并携带到 url 上
* 3. 使用 myAxios 函数,获取地区列表
*/
function myAxios(config) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
if (config.params) {
// var params = ''
// for (var key in config.params) {
// params += `${key}=${config.params[key]}&`
// }
// params = params.slice(0, -1)
// 使用 URLSearchParams 转换,并携带到 url 上
const paramsObj = new URLSearchParams(config.params);
const params = paramsObj.toString();
config.url += '?' + params;
}
xhr.open(config.method || 'get', config.url);
xhr.addEventListener('loadend', () => {
if (/^2\d{2}$/.test(xhr.status)) {
resolve(JSON.parse(xhr.response));
} else {
reject(new Error(xhr.response));
}
});
xhr.send();
});
}
const province = document.querySelector('#province');
const city = document.querySelector('#city');
// 获取省份列表数据添加到省份下拉菜单中
myAxios({
url: 'http://hmajax.itheima.net/api/province',
})
.then((res) => {
province.innerHTML = res.list.map((item) => `<option value="${item}">${item}</option>`).join('');
})
.catch((err) => {
console.log(err.message);
});
// 为省份下拉菜单绑定 onchange 事件,当省份发生改变时,获取对应的城市列表数据添加到城市下拉菜单中
province.addEventListener('change', () => {
myAxios({
url: `http://hmajax.itheima.net/api/city`,
params: {
pname: province.value,
},
})
.then((res) => {
city.innerHTML = res.list.map((item) => `<option value="${item}">${item}</option>`).join('');
})
.catch((err) => {
console.log(err.message);
});
});
// 为查询按钮绑定点击事件,当点击查询按钮时,获取当前选中的省份和城市,发送请求获取对应的地区列表数据,展示到页面中
document.querySelector('.sel-btn').addEventListener('click', () => {
myAxios({
url: `http://hmajax.itheima.net/api/area`,
params: {
pname: province.value,
cname: city.value,
},
})
.then((res) => {
document.querySelector('.list-group').innerHTML = res.list
.map((item) => `<li class="list-group-item">${item}</li>`)
.join('');
})
.catch((err) => {
console.log(err.message);
});
});
</script>
</body>
</html><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>29 简易 axios 函数 注册账号</title>
<link rel="stylesheet" href="./css/bootstrap.min.css">
</head>
<body class="p-3 mb-2 d-flex justify-content-center align-items-center vh-100">
<div class="container p-5 shadow" style="width: 500px; background-color: #f5f5f5; border-radius: 10px;">
<div class="toast position-fixed top-0 start-50 translate-middle-x" role="alert" aria-live="assertive"
aria-atomic="true" data-bs-delay="2000">
<div class="toast-body">
操作成功
</div>
</div>
<h2>05 注册账号</h2>
<form class="form-group mt-5">
<div class="mb-3">
<label for="exampleInputUsername" class="form-label">Username</label>
<input type="text" class="form-control" id="username" name="username" placeholder="鸡你太美cxk"
aria-describedby="usernameHelp">
<div id="usernameHelp" class="form-text">中英文和数字组成,最少 8 位。</div>
</div>
<div class="mb-3">
<label for="exampleInputPassword1" class="form-label">Password</label>
<input type="password" class="form-control" id="password" name="password" placeholder="987654321"
aria-describedby="passwordHelp">
<div id="passwordHelp" class="form-text">最少 6 位。</div>
</div>
</form>
<button type="submit" class="btn btn-primary mb-3">注册账号</button>
</div>
<script src="./js/bootstrap.min.js"></script>
<script>
/**
* 目标:封装_简易 axios 函数_注册用户
* 1. 判断有 data 选项,携带请求体
* 2. 转换数据类型,在 send 中发送
* 3. 使用 myAxios 函数,完成注册用户
*/
function myAxios(config) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
if (config.params) {
const paramsObj = new URLSearchParams(config.params);
const params = paramsObj.toString();
config.url += '?' + params;
}
xhr.open(config.method || 'get', config.url);
xhr.addEventListener('loadend', () => {
if (/^2\d{2}$/.test(xhr.status)) {
resolve(JSON.parse(xhr.response));
} else {
reject(new Error(xhr.response));
}
});
// 判断有 data 选项,携带请求体
if (config.data) {
// 转换数据类型,在 send 中发送
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(config.data));
} else {
xhr.send();
}
});
}
const submitBtn = document.querySelector('button[type=submit]');
submitBtn.addEventListener('click', () => {
const username = document.querySelector('#username').value;
const password = document.querySelector('#password').value;
console.log(username, password);
const toastDom = document.querySelector('.toast');
const toast = new bootstrap.Toast(toastDom);
toastDom.querySelector('.toast-body').style.backgroundColor = 'var(--bs-primary)';
toastDom.querySelector('.toast-body').classList.add('p-3', 'rounded-3');
myAxios({
method: 'post',
url: 'http://hmajax.itheima.net/api/register',
data: {
username,
password,
},
})
.then((res) => {
console.log(res);
toastDom.querySelector('.toast-body').textContent = res.message;
toast.show();
})
.catch((err) => {
console.log(err.message);
toastDom.querySelector('.toast-body').textContent = JSON.parse(err.message).message;
toast.show();
});
});
</script>
</body>
</html>Promise 对象有哪 3 种状态?
pendingfulfilledrejectedPromise 状态有什么用?
AJAX 如何判断是否请求响应成功了?
200 并且小于 300 的范围是成功的// if (xhr.status >= 200 && xhr.status < 300) {
if (/^2\d{2}$/.test(xhr.status)) {
// 成功
resolve(JSON.parse(xhr.response));
} else {
// 失败
reject(new Error(xhr.response));
}自己封装的 myAxios 如何设置默认请求方法 GET?
config.method 判断有值就用,无值用 GET 方法// 判断是否传入请求方法
// if (config.method) {
// xhr.open(config.method, config.url)
// } else {
// xhr.open('get', config.url)
// }
xhr.open(config.method || 'get', config.url);外面传入查询参数对象,myAxios 函数内如何转查询参数字符串?
URLSearchParams 对象转换if (config.params) {
// var params = ''
// for (var key in config.params) {
// params += `${key}=${config.params[key]}&`
// }
// params = params.slice(0, -1)
// 使用 URLSearchParams 转换,并携带到 url 上
const paramsObj = new URLSearchParams(config.params);
const params = paramsObj.toString();
config.url += '?' + params;
}外面传入 data 选项,myAxios 函数内如何携带请求体参数?
JSON 字符串并设置请求头并在 send 方法中携带// 判断有 data 选项,携带请求体
if (config.data) {
// 转换数据类型,在 send 中发送
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(config.data));
} else {
xhr.send();
}根据关键字,展示匹配的城市列表

/**
* @description: 获取天气预报
* @param {string } cityCode
*
* api: http://hmajax.itheima.net/api/weather (GET)
*/
function getWeather(cityCode) {
myAxios({
url: 'http://hmajax.itheima.net/api/weather',
params: {
city: cityCode,
},
}).then((res) => {
console.log(res.data);
// 打印出对象的属性名
console.log(Object.keys(res.data));
const {
date,
dateLunar,
area,
temperature,
weather,
weatherImg,
windPower,
windDirection,
psPm25Level,
psPm25,
todayWeather,
dayForecast,
} = res.data;
function setElement(selector, value, isImage = false) {
const element = document.querySelector(selector);
if (isImage) {
element.src = value;
} else {
element.innerHTML = value;
}
}
setElement('span.dateShort', date);
setElement('span.dateLunar', dateLunar);
setElement('span.area', area);
setElement('span.temperature', temperature);
setElement('span.psPm25', psPm25);
setElement('span.psPm25Level', psPm25Level);
setElement('img.weatherImg', weatherImg, true);
setElement('span.weather', weather);
setElement('span.windDirection', windDirection);
setElement('span.windPower', windPower);
const {
humidity,
sunriseTime,
sunsetTime,
temDay,
temNight,
ultraviolet,
weather: todayWeatherWeather,
} = todayWeather;
setElement('.range span.weather', todayWeatherWeather);
setElement('span.temNight', temNight);
setElement('span.temDay', temDay);
setElement('span.ultraviolet', ultraviolet);
setElement('span.humidity', humidity);
setElement('span.sunriseTime', sunriseTime);
setElement('span.sunsetTime', sunsetTime);
// 1.3 未来七天天气预报
document.querySelector('.week-wrap').innerHTML = dayForecast
.map(
({ dateFormat, date, weatherImg, weather, temNight, temDay, windDirection, windPower }) => `
<li class="item">
<div class="date-box">
<span class="dateFormat">${dateFormat}</span>
<span class="date">${date}</span>
</div>
<img src="${weatherImg}" alt="" class="weatherImg">
<span class="weather">${weather}</span>
<div class="temp">
<span class="temNight">${temNight}</span>-
<span class="temDay">${temDay}</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">${windDirection}</span>
<span class="windPower">${windPower}</span>
</div>
</li>
`,
)
.join('');
});
}// 页面加载后默认展示北京市的天气信息
// 北京市的城市 code 为 110100
getWeather('110100');
/**
* 目标 2:搜索城市列表
* 2.1 绑定 input 事件,获取关键字
* 2.2 获取展示城市列表数据
*/
document.querySelector('.search-city').addEventListener('input', (e) => {
console.log(e.target.value);
myAxios({
url: 'http://hmajax.itheima.net/api/weather/city',
params: {
city: e.target.value,
},
})
.then((res) => {
console.log(res);
// 渲染城市列表
document.querySelector('.search-list').innerHTML = res.data
.map((item) => `<li class="city-item" data-code="${item.code}">${item.name}</li>`)
.join('');
})
.catch((err) => {
// console.dir 可以打印详细信息:对象的属性名
console.dir(err.message);
});
});
/**
* 目标 3:切换城市天气
* 3.1 绑定城市点击事件,获取城市 code 值
* 3.2 调用获取并展示天气的函数
*/
document.querySelector('.search-list').addEventListener('click', (e) => {
console.log(e.target);
if (e.target.classList.contains('city-item')) {
// const cityCode = e.target.dataset.code;
const cityCode = e.target.getAttribute('data-code');
console.log(cityCode);
getWeather(cityCode);
}
});监听输入框实时改变的事件是什么?
input 事件了解 AJAX 原理之 XMLHttpRequest(XHR)相关语法
// 创建 XMLHttpRequest 对象
const xhr = new XMLHttpRequest();
// 组织查询参数字符串
const paramsObj = new URLSearchParams({ pname, cname });
const queryString = paramsObj.toString();
// 配置请求方法和请求 url 地址
xhr.open('get', `http://hmajax.itheima.net/api/area?${queryString}`);
// 设置 HTTP 请求头(可选)
xhr.setRequestHeader('Content-Type', 'application/json');
// 处理状态变化事件
// - onreadystatechange:事件处理属性,指定在 readyState 属性改变时触发的函数
// - readyState:表示 XMLHttpRequest 的状态,有 5 个值(0-4),分别对应不同的状态
// - status:表示 HTTP 请求的状态码,例如 200 表示成功
// - responseText 和 responseXML:包含响应的文本或 XML 数据
xhr.addEventListener('loadend', () => {
// 响应结果
console.log(xhr.response);
});
// 发送 HTTP 请求
xhr.send();
// 对于 POST 请求,可以在 send 方法中传递请求体参数
// xhr.send('param1=value1¶m2=value2');
// xhr.send(JSON.stringify({ username, password }));了解 Promise 的作用和三种状态
Promise 是 JavaScript 中用于处理异步操作的对象。它提供了更优雅和可读性更高的方式来处理异步代码,避免了回调地狱(callback hell)。
Promise 的作用:
then 和 catch 方法来组织和处理异步代码,使代码更具可读性和可维护性。Promise 的三种状态:
Pending 变为 Fulfilled。Pending 变为 Rejected。Promise 的基本用法:
const promise = new Promise((resolve, reject) => {
// 异步操作,成功时调用 resolve,失败时调用 reject
setTimeout(() => {
resolve('成功结果');
// 或者
// reject(new Error("失败原因"));
}, 1000);
});
promise
.then((res) => {
// 处理成功的情况
console.log(res);
})
.catch((err) => {
// 处理失败的情况
console.error(err);
});在上面的例子中,then 方法用于注册在 Promise 对象状态变为 Fulfilled 时执行的函数,catch 方法用于注册在状态变为 Rejected 时执行的函数。
了解 axios 内部运作的过程
Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 Node.js。它允许在浏览器中发送异步 HTTP 请求,并提供了更方便的 API。
Axios 内部运作的主要过程:
创建 Axios 实例: 在使用 Axios 之前,通常需要创建一个 Axios 实例,以便配置一些全局参数,例如基础 URL、请求头等。
const axiosInstance = axios.create({
baseURL: 'https://api.example.com',
headers: {
'Content-Type': 'application/json',
},
});发送请求: 使用创建的 Axios 实例可以发送各种类型的 HTTP 请求,例如 GET、POST、PUT、DELETE 等。
axiosInstance
.get('/data')
.then((response) => {
// 处理成功的响应
console.log(response.data);
})
.catch((error) => {
// 处理失败的响应
console.error(error);
});封装请求: Axios 封装了底层的 XMLHTTPRequest 或者 Node.js 中的 http 模块,以处理底层的网络通信。它隐藏了大部分底层实现,使开发者能够更专注于业务逻辑。
Promise 封装: Axios 使用 Promise 对象来处理异步操作。每个 Axios 请求返回一个 Promise 对象,允许通过 then 和 catch 方法处理成功和失败的响应。
axiosInstance.interceptors.request.use(
(config) => {
// 在请求被发送之前做些什么
return config;
},
(error) => {
// 对请求错误做些什么
return Promise.reject(error);
},
);
axiosInstance.interceptors.response.use(
(response) => {
// 对响应数据做些什么
return response;
},
(error) => {
// 对响应错误做些什么
return Promise.reject(error);
},
);拦截器(Interceptors): Axios 提供了拦截器,允许在请求或响应被 then 或 catch 处理之前拦截它们。这使得可以在请求发送之前或响应处理之后执行一些额外的逻辑。
axiosInstance.interceptors.request.use(
(config) => {
// 在请求被发送之前做些什么
return config;
},
(error) => {
// 对请求错误做些什么
return Promise.reject(error);
},
);
axiosInstance.interceptors.response.use(
(response) => {
// 对响应数据做些什么
return response;
},
(error) => {
// 对响应错误做些什么
return Promise.reject(error);
},
);完成案例 - 天气预报
<!DOCTYPE html>
<html lang="zh-CN">
<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">
<link rel="stylesheet" href="./css/reset.css">
<link rel="stylesheet" href="./css/index.css">
<title>案例_天气预报</title>
</head>
<body>
<div class="container">
<!-- 顶部 -->
<div class="top-box">
<div class="title">
<span class="dateShort">10 月 28 日</span>
<span class="calendar">农历
<span class="dateLunar">十月初四</span>
</span>
</div>
<div class="search-box">
<div class="location">
<img src="./imgs/定位.png" alt="">
<span class="area">城市名</span>
</div>
<!-- 搜索框 + 搜索列表 -->
<div class="search">
<input type="text" class="search-city" placeholder="搜索城市">
<ul class="search-list">
<li class="city-item">北京市</li>
</ul>
</div>
</div>
</div>
<!-- 当前天气 -->
<div class="weather-box">
<div class="tem-box">
<span class="temp">
<span class="temperature">12</span>
<span>°</span>
</span>
</div>
<div class="climate-box">
<div class="air">
<span class="psPm25">55</span>
<span class="psPm25Level">良</span>
</div>
<ul class="weather-list">
<li>
<img src="./imgs/小雨-line.png" class="weatherImg" alt="">
<span class="weather">多云</span>
</li>
<li class="windDirection">东南风</li>
<li class="windPower">2 级</li>
</ul>
</div>
</div>
<div class="today-weather">
<div class="range-box">
<span>今天:</span>
<span class="range">
<span class="weather">晴</span>
<span class="temNight">9</span>
<span>-</span>
<span class="temDay">14</span>
<span>℃</span>
</span>
</div>
<ul class="sun-list">
<li>
<span>紫外线</span>
<span class="ultraviolet">强</span>
</li>
<li>
<span>湿度</span>
<span class="humidity">53</span>%
</li>
<li>
<span>日出</span>
<span class="sunriseTime">06:38</span>
</li>
<li>
<span>日落</span>
<span class="sunsetTime">17:18</span>
</li>
</ul>
</div>
<!-- 周天气预报 -->
<div class="week-weather-box">
<div class="title">7 日内天气预报</div>
<ul class="week-wrap">
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temNight">12</span>-
<span class="temDay">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
</ul>
</div>
</div>
<!-- 自己封装 myAxios 函数 -->
<script src="./js/my-axios.js"></script>
<!-- 搜索框 + 下拉菜单出现逻辑 -->
<script src="./js/search.js"></script>
<!-- 获取城市天气信息 -->
<script src="./js/getWeather.js"></script>
<!-- 核心 js -->
<script src="./js/index.js"></script>
</body>
</html>function myAxios(config) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
if (config.params) {
const paramsObj = new URLSearchParams(config.params);
const queryString = paramsObj.toString();
config.url += `?${queryString}`;
}
xhr.open(config.method || 'GET', config.url);
xhr.addEventListener('loadend', () => {
if (/^2\d{2}$/.test(xhr.status)) {
resolve(JSON.parse(xhr.response));
} else {
reject(new Error(xhr.response));
}
});
if (config.data) {
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(JSON.stringify(config.data));
} else {
xhr.send();
}
});
}/**
* @description: 获取天气预报
* @param {string } cityCode
*
* api: http://hmajax.itheima.net/api/weather (GET)
*/
function getWeather(cityCode) {
myAxios({
url: 'http://hmajax.itheima.net/api/weather',
params: {
city: cityCode,
},
}).then((res) => {
console.log(res.data);
// 打印出对象的属性名
console.log(Object.keys(res.data));
const {
date,
dateLunar,
area,
temperature,
weather,
weatherImg,
windPower,
windDirection,
psPm25Level,
psPm25,
todayWeather,
dayForecast,
} = res.data;
function setElement(selector, value, isImage = false) {
const element = document.querySelector(selector);
if (isImage) {
element.src = value;
} else {
element.innerHTML = value;
}
}
setElement('span.dateShort', date);
setElement('span.dateLunar', dateLunar);
setElement('span.area', area);
setElement('span.temperature', temperature);
setElement('span.psPm25', psPm25);
setElement('span.psPm25Level', psPm25Level);
setElement('img.weatherImg', weatherImg, true);
setElement('span.weather', weather);
setElement('span.windDirection', windDirection);
setElement('span.windPower', windPower);
const {
humidity,
sunriseTime,
sunsetTime,
temDay,
temNight,
ultraviolet,
weather: todayWeatherWeather,
} = todayWeather;
setElement('.range span.weather', todayWeatherWeather);
setElement('span.temNight', temNight);
setElement('span.temDay', temDay);
setElement('span.ultraviolet', ultraviolet);
setElement('span.humidity', humidity);
setElement('span.sunriseTime', sunriseTime);
setElement('span.sunsetTime', sunsetTime);
// 1.3 未来七天天气预报
document.querySelector('.week-wrap').innerHTML = dayForecast
.map(
({ dateFormat, date, weatherImg, weather, temNight, temDay, windDirection, windPower }) => `
<li class="item">
<div class="date-box">
<span class="dateFormat">${dateFormat}</span>
<span class="date">${date}</span>
</div>
<img src="${weatherImg}" alt="" class="weatherImg">
<span class="weather">${weather}</span>
<div class="temp">
<span class="temNight">${temNight}</span>-
<span class="temDay">${temDay}</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">${windDirection}</span>
<span class="windPower">${windPower}</span>
</div>
</li>
`,
)
.join('');
});
}// 页面加载后默认展示北京市的天气信息
// 北京市的城市 code 为 110100
getWeather('110100');
/**
* 目标 2:搜索城市列表
* 2.1 绑定 input 事件,获取关键字
* 2.2 获取展示城市列表数据
*/
document.querySelector('.search-city').addEventListener('input', (e) => {
// console.log(e.target.value);
myAxios({
url: 'http://hmajax.itheima.net/api/weather/city',
params: {
city: e.target.value,
},
})
.then((res) => {
console.log(`${e.target.value}: ${JSON.stringify(res.data)}`);
// 渲染城市列表
document.querySelector('.search-list').innerHTML = res.data
.map((item) => `<li class="city-item" data-code="${item.code}">${item.name}</li>`)
.join('');
})
.catch((err) => {
// console.dir 可以打印详细信息:对象的属性名
console.dir(err.message);
});
});
/**
* 目标 3:切换城市天气
* 3.1 绑定城市点击事件,获取城市 code 值
* 3.2 调用获取并展示天气的函数
*/
document.querySelector('.search-list').addEventListener('click', (e) => {
console.log(e.target);
if (e.target.classList.contains('city-item')) {
// const cityCode = e.target.dataset.code;
const cityCode = e.target.getAttribute('data-code');
console.log(cityCode);
getWeather(cityCode);
}
});在线答题:Day03_AJAX 原理
以下哪个方法可以把 JSON 字符串转 JS 数据类型( )?
Object.keys()JSON.stringify()JSON.parse()Object.values()JSON.parse()。这个方法用于将 JSON 字符串转换为相应的 JavaScript 对象。Object.keys():返回一个给定对象的所有可枚举属性的字符串数组。JSON.stringify():将 JavaScript 对象转换为 JSON 字符串。Object.values():返回一个给定对象的所有可枚举属性值的数组。以下哪个事件是在输入框失去焦点并内容改变是触发( )?
changeinputclickonchangechange。change 事件在用户对表单元素进行更改并提交更改时触发。在输入框中,它通常在输入框失去焦点后触发,但是具体的行为可能因浏览器而异。这个事件不同于 input 事件,input 事件在输入框的值发生任何变化时都会触发,不需要等到失去焦点。input 事件是在输入框的值发生变化时即时触发。click 事件是在用户点击元素时触发,与输入框的值变化和焦点失去无关。onchange 不是一个事件,而是一个事件处理属性的命名方式,通常用于绑定 change 事件的处理函数。以下哪个是 AJAX 原理( )?
XMLHttpRequestxmlhttprequestaxiosmyAxiosXMLHttpRequest。AJAX(Asynchronous JavaScript and XML)是一种用于在不重新加载整个页面的情况下与服务器交换数据的技术。XMLHttpRequest 对象是实现这种技术的关键。它允许浏览器通过 JavaScript 发送 HTTP 请求,并处理服务器的响应。xmlhttprequest:这是一个不正确的写法,正确的是 XMLHttpRequest。axios:axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 Node.js。它是对 XMLHttpRequest 的封装,使得使用更加方便。myAxios:这个选项是一个自定义的名称,与 AJAX 的原理直接无关。原生 AJAX 如何携带查询参数( )?
send 里发送setRequestHeader 携带url 上自己按照格式拼接new 的时候携带正确的选项是 C. 在 url 上自己按照格式拼接。在原生的 AJAX 中,你可以将查询参数直接附加到请求的 URL 上。
var xhr = new XMLHttpRequest();
var url = 'example.com/api/data?param1=value1¶m2=value2';
xhr.open('GET', url, true);
xhr.send();A. 在 send 里发送:这是不准确的,send 方法通常用于发送请求体(对于 POST 请求等),而不是查询参数。
B. 使用 setRequestHeader 携带:setRequestHeader 用于设置 HTTP 请求头,而不是用来携带查询参数。
D. 在 new 的时候携带:在 new XMLHttpRequest() 的时候并没有直接提供携带查询参数的接口,你需要手动将参数拼接到请求的 URL 上。
原生 AJAX 如何携带请求体参数()?
new 的时候传递url 上携带send 方法中携带setRequestHeader 里携带正确的选项是 C. 在 send 方法中携带。对于包含请求体的 HTTP 请求(如 POST 请求),你可以在 send 方法中传递请求体参数。
var xhr = new XMLHttpRequest();
const url = 'example.com/api/data';
const params = new URLSearchParams({
param1: 'value1',
param2: 'value2',
});
xhr.open('POST', url);
// 设置请求头(如果有需要)
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onreadystatechange = () => {
if (xhr.readyState == 4 && xhr.status == 200) {
// 请求成功的处理逻辑
console.log(xhr.responseText);
}
};
// 在 send 方法中携带请求体参数
xhr.send(params);A. 在 new 的时候传递:在 new XMLHttpRequest() 的时候通常用于配置一些基本的请求参数,但并不是用来携带请求体参数的地方。
B. 在 url 上携带:通常用于 GET 请求的查询参数,而不是请求体参数。
D. 在 setRequestHeader 里携带:setRequestHeader 用于设置请求头,而不是用来携带请求体参数。
什么是 Promise?
正确的选项是 D. 管理异步任务,在将来接收成功/失败状态及其结果值。Promise 是 JavaScript 中用于处理异步操作的对象。它代表了一个异步操作的最终完成或失败,以及其结果值。
Promise 对象有三种状态:
通过 then 方法,你可以在 Promise 对象的状态发生变化时注册对应的处理函数,分别处理成功和失败的情况。
var promise = new Promise(function (resolve, reject) {
// 异步操作,成功时调用 resolve,失败时调用 reject
setTimeout(() => {
resolve('成功结果');
// 或者
// reject("失败原因");
}, 1000);
});
promise
.then((result) => {
// 处理成功的情况
console.log(result);
})
.catch((error) => {
// 处理失败的情况
console.error(error);
});这样,Promise 提供了一种更优雅和可读性更高的方式来处理异步代码。
以下哪个不是 Promise 的三种状态?
fulfilledsettledresolvependingresolve。在 Promise 的状态中,fulfilled 表示已成功,rejected 表示已失败,而 pending 表示进行中。settled 这个术语通常用来描述 Promise 已经处于终态(fulfilled 或 rejected)的状态,因此也是 Promise 的一种状态。fulfilled: 已成功状态。settled: 已终态,即已成功或已失败状态。resolve: 不是状态,而是 Promise 的方法,用于将 Promise 从 pending 状态变为 fulfilled 状态。pending: 进行中的状态。以下哪个不是 axios 内部运作机制( )?
PromiseXHRclickAJAXclick。click 不是 axios 内部运作机制的一部分。Promise: axios 使用 Promise 来处理异步操作。它支持 Promise 的链式调用,使得代码更加清晰和可读。XHR(XMLHttpRequest): XMLHttpRequest 是在浏览器中实现 AJAX 的底层技术,而 axios 利用它来发起 HTTP 请求。click: 不是 axios 的内部运作机制,而是一个事件。在前端开发中,click 通常用于处理用户点击事件。AJAX: 虽然 axios 使用了类似 AJAX 的技术,但 AJAX 本身也不是 axios 的内部运作机制,而是表示 "Asynchronous JavaScript and XML",是一种用于在不重新加载整个页面的情况下与服务器交换数据的技术。以下哪个会触发原生 XHR 请求和响应成功状态?
200399190411200。HTTP 状态码 200 OK 表示服务器成功处理了请求。411: HTTP 状态码 411 Length Required 表示服务器拒绝在没有定义 Content-Length 头的情况下接受请求。这并不是成功状态,而是一个客户端错误状态。以下哪个是监听 AJAX 响应完成事件?
onloadloadloadendonreadyloadend。loadend 事件在 AJAX 请求完成(无论成功或失败)时触发。onload: 这是一个事件处理属性,用于指定在 AJAX 请求成功完成时执行的函数。load: 这是一个事件,但通常用于监听资源(如图片)的加载完成。在 XMLHttpRequest 上使用 onload 属性而不是 load 事件。onready: 这不是标准的事件,没有与之对应的 AJAX 事件。正常的事件处理属性为 onload、onerror 等。目标:完成如下英雄百科的效果
要求:
接口文档:https://apifox.com/apidoc/shared-1b0dd84f-faa8-435d-b355-5a8a329e34a8/api-82668103
<!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" />
<link rel="stylesheet" href="./css/bootstrap.min.css" />
<link rel="stylesheet" href="./css/index.css" />
<title>英雄百科</title>
</head>
<body>
<div class="main">
<img class="cover"
src="https://img.crawler.qq.com/lolwebschool/0/JAutoCMS_LOLWeb_f6416138ae858f73e2ca40a11587e17f/0"
referrerpolicy="no-referrer" />
<div class="hero-container">
<input type="text" class="search" placeholder="检索" />
<ul class="list">
<li>
<img src="http://game.gtimg.cn/images/lol/act/img/champion/Annie.png" alt="" referrerpolicy="no-referrer" />
<p>安妮</p>
</li>
</ul>
</div>
</div>
<div id="infoModal" class="modal" tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title">黑暗之女安妮</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="info">
<img src="http://game.gtimg.cn/images/lol/act/img/champion/Annie.png" class="icon img-thumbnail" alt="..."
referrerpolicy="no-referrer" />
<div class="progress-box">
<div class="progress">
<div class="attack progress-bar bg-success" style="width: 25%">攻击:</div>
</div>
<div class="progress">
<div class="defense progress-bar bg-info" role="progressbar" style="width: 50%">防御:</div>
</div>
<div class="progress">
<div class="magic progress-bar bg-warning" role="progressbar" style="width: 75%">魔法:</div>
</div>
<div class="progress">
<div class="difficulty progress-bar bg-danger" role="progressbar" style="width: 100%">难度:</div>
</div>
</div>
</div>
<p>
拥有危险夺命的能力,却长着一幅小大人儿的可爱模样,这就是掌握深不可测占火魔法的女孩——安妮。安妮生活在诺克萨斯北边的山脚下,但即便是在这种地方,她也依然是魔法师中的异类。她与火焰的紧密关系与生俱来——最初那些火焰是伴随着喜怒无常的冲动情绪出现的,后来她学会了如何掌握这些“好玩的小把戏”。其中,安妮最喜欢的就是她召唤亲爱的泰迪熊提伯斯——那头狂野的守护火兽。如今安妮已经迷失在了永恒的天真里,她在黑暗森林中游荡,寻觅着能陪自己玩耍的人。
</p>
</div>
</div>
</div>
</div>
</body>
<script src="./js/axios.min.js"></script>
<script src="./js/bootstrap.min.js"></script>
<!-- 展示所有英雄列表数据 -->
<script src="./js/showHeroList.js"></script>
<!-- 搜索英雄 -->
<script src="./js/searchHero.js"></script>
<!-- 点击英雄查看英雄详情 -->
<script src="./js/showHeroInfo.js"></script>
<script>
</script>
</html>/**
* 展示所有英雄列表数据
* api: https://hmajax.itheima.net/api/lol/search - GET
*/
const infoModal = document.querySelector('#infoModal');
const modal = new bootstrap.Modal(infoModal);
async function showHeroList() {
try {
const res = await axios.get('https://hmajax.itheima.net/api/lol/search');
console.log(res.data.data);
const heroList = res.data.data
.map((item) => {
return `
<li>
<img class="icon img-thumbnail" data-id='${item.heroId}' src="${item.icon}" alt="" referrerpolicy="no-referrer">
<p>${item.title}</p>
</li>
`;
})
.join('');
document.querySelector('.list').innerHTML = heroList;
} catch (err) {
console.dir(err);
console.log(err.response);
}
}
// 页面加载时展示所有英雄列表数据
showHeroList();/**
* 搜索英雄
* api: https://hmajax.itheima.net/api/lol/search - GET
* @param { String } q 搜索关键字
*/
async function searchHero(string) {
try {
const res = await axios.get(`https://hmajax.itheima.net/api/lol/search?q=${string}`);
console.log(res.data.data);
const heroList = res.data.data
.map((item) => {
return `
<li>
<img class="icon img-thumbnail" data-id='${item.heroId}' src="${item.icon}" alt="" referrerpolicy="no-referrer">
<p>${item.title}</p>
</li>
`;
})
.join('');
document.querySelector('.list').innerHTML = heroList;
} catch (err) {
console.dir(err);
console.log(err.response);
}
}
const searchInput = document.querySelector('input.search');
// 搜索框输入时实时搜索英雄
// searchInput.addEventListener('input', (e) => {
// onkeyup 事件会在键盘按键被松开时发生
searchInput.onkeyup = async (e) => {
if (e.keyCode !== 13) return; // 没有按回车键就不执行
const string = e.target.value.trim(); // 去除两端空格
console.log(string);
if (string) {
searchHero(string);
} else {
console.log('输入为空,请输入搜索关键字!!!');
}
};/**
* 点击英雄查看英雄详情
* api: https://hmajax.itheima.net/api/lol/info - GET
* @param { String } id 英雄 id
*/
async function showHeroInfo(id) {
try {
const res = await axios.get(`https://hmajax.itheima.net/api/lol/info?id=${id}`);
const hero = res.data.data.hero;
console.log(hero);
// console.log(JSON.stringify(hero));
const modalContent = document.querySelector('.modal-content');
modalContent.querySelector('.modal-title').innerHTML = hero.name + hero.title;
modalContent.querySelector('.icon').src = hero.icon;
modalContent.querySelector('.attack').style.width = `${(hero.attack / 10) * 100}%`;
modalContent.querySelector('.defense').style.width = `${(hero.defense / 10) * 100}%`;
modalContent.querySelector('.magic').style.width = `${(hero.magic / 10) * 100}%`;
modalContent.querySelector('.difficulty').style.width = `${(hero.difficulty / 10) * 100}%`;
modalContent.querySelector('p').innerHTML = hero.shortBio;
modal.show();
} catch (err) {
console.dir(err);
console.log(err.response);
}
}
document.querySelector('.list').addEventListener('click', async (e) => {
const heroId = e.target.getAttribute('data-id');
console.log(heroId);
if (heroId) {
showHeroInfo(heroId);
}
});<!DOCTYPE html>
<html lang="zh-CN">
<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">
<link rel="stylesheet" href="./css/reset.css">
<link rel="stylesheet" href="./css/index.css">
<title>案例_天气预报</title>
</head>
<body>
<div class="container">
<!-- 顶部 -->
<div class="top-box">
<div class="title">
<span class="dateShort">10 月 28 日</span>
<span class="calendar">农历
<span class="dateLunar">十月初四</span>
</span>
</div>
<div class="search-box">
<div class="location">
<img src="./imgs/定位.png" alt="">
<span class="area">城市名</span>
</div>
<!-- 搜索框 + 搜索列表 -->
<div class="search">
<input type="text" class="search-city" placeholder="搜索城市">
<ul class="search-list">
<li class="city-item">北京市</li>
</ul>
</div>
</div>
</div>
<!-- 当前天气 -->
<div class="weather-box">
<div class="tem-box">
<span class="temp">
<span class="temperature">12</span>
<span>°</span>
</span>
</div>
<div class="climate-box">
<div class="air">
<span class="psPm25">55</span>
<span class="psPm25Level">良</span>
</div>
<ul class="weather-list">
<li>
<img src="./imgs/小雨-line.png" class="weatherImg" alt="">
<span class="weather">多云</span>
</li>
<li class="windDirection">东南风</li>
<li class="windPower">2 级</li>
</ul>
</div>
</div>
<div class="today-weather">
<div class="range-box">
<span>今天:</span>
<span class="range">
<span class="weather">晴</span>
<span class="temNight">9</span>
<span>-</span>
<span class="temDay">14</span>
<span>℃</span>
</span>
</div>
<ul class="sun-list">
<li>
<span>紫外线</span>
<span class="ultraviolet">强</span>
</li>
<li>
<span>湿度</span>
<span class="humidity">53</span>%
</li>
<li>
<span>日出</span>
<span class="sunriseTime">06:38</span>
</li>
<li>
<span>日落</span>
<span class="sunsetTime">17:18</span>
</li>
</ul>
</div>
<!-- 周天气预报 -->
<div class="week-weather-box">
<div class="title">7 日内天气预报</div>
<ul class="week-wrap">
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temNight">12</span>-
<span class="temDay">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
</ul>
</div>
</div>
<!-- 自己封装 myAxios 函数 -->
<script src="./js/my-axios.js"></script>
<!-- 搜索框 + 下拉菜单出现逻辑 -->
<script src="./js/search.js"></script>
<!-- 核心 js -->
<script src="./js/index.js"></script>
</body>
</html>/**
* 目标 1:默认显示 - 北京市天气
* 1.1 获取北京市天气数据
* 1.2 数据展示到页面
*/
// 获取并渲染城市天气函数
function getWeather(cityCode) {
// 1.1 获取北京市天气数据
myAxios({
url: 'http://hmajax.itheima.net/api/waether',
params: {
city: cityCode,
},
}).then((result) => {
console.log(result);
const wObj = result.data;
// 1.2 数据展示到页面
// 阳历和农历日期
const dateStr = `<span class="dateShort">${wObj.date}</span>
<span class="calendar">农历
<span class="dateLunar">${wObj.dateLunar}</span>
</span>`;
document.querySelector('.title').innerHTML = dateStr;
// 城市名字
document.querySelector('.area').innerHTML = wObj.area;
// 当天气温
const 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 = nowWStr;
// 当天天气
const twObj = wObj.todayWeather;
const 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 = todayWStr;
// 7 日天气预报数据展示
const dayForecast = wObj.dayForecast;
const 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('');
// console.log(dayForecastStr)
document.querySelector('.week-wrap').innerHTML = dayForecastStr;
});
}
// 默认进入网页 - 就要获取天气数据(北京市城市编码:'110100')
getWeather('1101001');
/**
* 目标 2:搜索城市列表
* 2.1 绑定 input 事件,获取关键字
* 2.2 获取展示城市列表数据
*/
// 2.1 绑定 input 事件,获取关键字
document.querySelector('.search-city').addEventListener('input', (e) => {
console.log(e.target.value);
// 2.2 获取展示城市列表数据
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('');
console.log(liStr);
document.querySelector('.search-list').innerHTML = liStr;
});
});
/**
* 目标 3:切换城市天气
* 3.1 绑定城市点击事件,获取城市 code 值
* 3.2 调用获取并展示天气的函数
*/
// 3.1 绑定城市点击事件,获取城市 code 值
document.querySelector('.city-item').addEventListener('click', (e) => {
if (e.target.classList.contains('city-item')) {
// 只有点击城市 li 才会走这里
const cityCode = e.target.dataset.code;
console.log(cityCode);
// 3.2 调用获取并展示天气的函数
getWeather(cityCode);
}
});打开控制台提示 api url 报错:
hmajax.itheima.net/api/waether?city=1101001:1 Failed to load resource: the server responded with a status of 404 (Not Found)
my-axios.js:14 Uncaught (in promise) Error: <h1>404 Not Found</h1>
at XMLHttpRequest.<anonymous> (my-axios.js:14:16)查看 api 后发现代码里的 api 写为
myAxios({
url: 'http://hmajax.itheima.net/api/waether',
params: {应该为
myAxios({
url: 'http://hmajax.itheima.net/api/weather',
params: {再次打开控制台还是发现有错,但是这次是查询参数错误:
my-axios.js:22 GET http://hmajax.itheima.net/api/weather?city=1101001 400 (Bad Request)
my-axios.js:14 Uncaught (in promise) Error: {"code":400001,"message":"入参城市 code:1101001 错误","data":{}}
at XMLHttpRequest.<anonymous> (my-axios.js:14:16)查看 api 后发现北京市的城市 code 为 110100,代码里为 1101001
再次打开控制台,这次没有报错。但是搜索框中输入城市后选择城市,但是天气和城市名都没有变。查看代码:
// 3.1 绑定城市点击事件,获取城市 code 值
document.querySelector('.city-item').addEventListener('click', (e) => {
if (e.target.classList.contains('city-item')) {列表是动态创建的,而绑定的 JS 代码上来就执行完了,这个时候列表数据还未回来,标签没有,获取不到标签,所以绑定不上事件!但是呢,数据回来后,列表标签创建插入到页面上,实际是有标签在页面,但是事件绑定的代码没有在创建后执行
发现点击事件绑定有问题,动态创建的标签绑定事件要用 事件委托 + 判断。这里应该给搜索框绑定点击事件。
// 3.1 绑定城市点击事件,获取城市 code 值
document.querySelector('.search-list').addEventListener('click', (e) => {
if (e.target.classList.contains('city-item')) {<!DOCTYPE html>
<html lang="zh-CN">
<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">
<link rel="stylesheet" href="./css/reset.css">
<link rel="stylesheet" href="./css/index.css">
<title>案例_天气预报</title>
</head>
<body>
<div class="container">
<!-- 顶部 -->
<div class="top-box">
<div class="title">
<span class="dateShort">10 月 28 日</span>
<span class="calendar">农历
<span class="dateLunar">十月初四</span>
</span>
</div>
<div class="search-box">
<div class="location">
<img src="./imgs/定位.png" alt="">
<span class="area">城市名</span>
</div>
<!-- 搜索框 + 搜索列表 -->
<div class="search">
<input type="text" class="search-city" placeholder="搜索城市">
<ul class="search-list">
<li class="city-item">北京市</li>
</ul>
</div>
</div>
</div>
<!-- 当前天气 -->
<div class="weather-box">
<div class="tem-box">
<span class="temp">
<span class="temperature">12</span>
<span>°</span>
</span>
</div>
<div class="climate-box">
<div class="air">
<span class="psPm25">55</span>
<span class="psPm25Level">良</span>
</div>
<ul class="weather-list">
<li>
<img src="./imgs/小雨-line.png" class="weatherImg" alt="">
<span class="weather">多云</span>
</li>
<li class="windDirection">东南风</li>
<li class="windPower">2 级</li>
</ul>
</div>
</div>
<div class="today-weather">
<div class="range-box">
<span>今天:</span>
<span class="range">
<span class="weather">晴</span>
<span class="temNight">9</span>
<span>-</span>
<span class="temDay">14</span>
<span>℃</span>
</span>
</div>
<ul class="sun-list">
<li>
<span>紫外线</span>
<span class="ultraviolet">强</span>
</li>
<li>
<span>湿度</span>
<span class="humidity">53</span>%
</li>
<li>
<span>日出</span>
<span class="sunriseTime">06:38</span>
</li>
<li>
<span>日落</span>
<span class="sunsetTime">17:18</span>
</li>
</ul>
</div>
<!-- 周天气预报 -->
<div class="week-weather-box">
<div class="title">7 日内天气预报</div>
<ul class="week-wrap">
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temNight">12</span>-
<span class="temDay">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
<li class="item">
<div class="date-box">
<span class="dateFormat">今天</span>
<span class="date">10 月 28 日</span>
</div>
<img src="./imgs/多云.png" alt="" class="weatherImg">
<span class="weather">多云</span>
<div class="temp">
<span class="temDay">12</span>-
<span class="temNight">12</span>
<span>℃</span>
</div>
<div class="wind">
<span class="windDirection">东南风</span>
<span class="windPower"><3 级</span>
</div>
</li>
</ul>
</div>
</div>
<!-- 自己封装 myAxios 函数 -->
<script src="./js/my-axios.js"></script>
<!-- 搜索框 + 下拉菜单出现逻辑 -->
<script src="./js/search.js"></script>
<!-- 核心 js -->
<script src="./js/index.js"></script>
</body>
</html>/**
* 目标 1:默认显示 - 北京市天气
* 1.1 获取北京市天气数据
* 1.2 数据展示到页面
*/
// 获取并渲染城市天气函数
function getWeather(cityCode) {
// 1.1 获取北京市天气数据
myAxios({
url: 'http://hmajax.itheima.net/api/waether',
params: {
city: cityCode,
},
}).then((result) => {
console.log(result);
const wObj = result.data;
// 1.2 数据展示到页面
// 阳历和农历日期
const dateStr = `<span class="dateShort">${wObj.date}</span>
<span class="calendar">农历
<span class="dateLunar">${wObj.dateLunar}</span>
</span>`;
document.querySelector('.title').innerHTML = dateStr;
// 城市名字
document.querySelector('.area').innerHTML = wObj.area;
// 当天气温
const 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 = nowWStr;
// 当天天气
const twObj = wObj.todayWeather;
const 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 = todayWStr;
// 7 日天气预报数据展示
const dayForecast = wObj.dayForecast;
const 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('');
// console.log(dayForecastStr)
document.querySelector('.week-wrap').innerHTML = dayForecastStr;
});
}
// 默认进入网页 - 就要获取天气数据(北京市城市编码:'110100')
getWeather('1101001');
/**
* 目标 2:搜索城市列表
* 2.1 绑定 input 事件,获取关键字
* 2.2 获取展示城市列表数据
*/
// 2.1 绑定 input 事件,获取关键字
document.querySelector('.search-city').addEventListener('input', (e) => {
console.log(e.target.value);
// 2.2 获取展示城市列表数据
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('');
console.log(liStr);
document.querySelector('.search-list').innerHTML = liStr;
});
});
/**
* 目标 3:切换城市天气
* 3.1 绑定城市点击事件,获取城市 code 值
* 3.2 调用获取并展示天气的函数
*/
// 3.1 绑定城市点击事件,获取城市 code 值
document.querySelector('.city-item').addEventListener('click', (e) => {
if (e.target.classList.contains('city-item')) {
// 只有点击城市 li 才会走这里
const cityCode = e.target.dataset.code;
console.log(cityCode);
// 3.2 调用获取并展示天气的函数
getWeather(cityCode);
}
});/**
* 目标 1:默认显示 - 北京市天气
* 1.1 获取北京市天气数据
* 1.2 数据展示到页面
*/
// 获取并渲染城市天气函数
function getWeather(cityCode) {
// 1.1 获取北京市天气数据
myAxios({
url: 'http://hmajax.itheima.net/api/weather',
params: {
city: cityCode,
},
}).then((result) => {
console.log(result);
const wObj = result.data;
// 1.2 数据展示到页面
// 阳历和农历日期
const dateStr = `<span class="dateShort">${wObj.date}</span>
<span class="calendar">农历
<span class="dateLunar">${wObj.dateLunar}</span>
</span>`;
document.querySelector('.title').innerHTML = dateStr;
// 城市名字
document.querySelector('.area').innerHTML = wObj.area;
// 当天气温
const 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 = nowWStr;
// 当天天气
const twObj = wObj.todayWeather;
const 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 = todayWStr;
// 7 日天气预报数据展示
const dayForecast = wObj.dayForecast;
const 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('');
// console.log(dayForecastStr)
document.querySelector('.week-wrap').innerHTML = dayForecastStr;
});
}
// 默认进入网页 - 就要获取天气数据(北京市城市编码:'110100')
getWeather('110100');
/**
* 目标 2:搜索城市列表
* 2.1 绑定 input 事件,获取关键字
* 2.2 获取展示城市列表数据
*/
// 2.1 绑定 input 事件,获取关键字
document.querySelector('.search-city').addEventListener('input', (e) => {
console.log(e.target.value);
// 2.2 获取展示城市列表数据
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('');
console.log(liStr);
document.querySelector('.search-list').innerHTML = liStr;
});
});
/**
* 目标 3:切换城市天气
* 3.1 绑定城市点击事件,获取城市 code 值
* 3.2 调用获取并展示天气的函数
*/
// 3.1 绑定城市点击事件,获取城市 code 值
document.querySelector('.search-list').addEventListener('click', (e) => {
if (e.target.classList.contains('city-item')) {
// 只有点击城市 li 才会走这里
const cityCode = e.target.dataset.code;
console.log(cityCode);
// 3.2 调用获取并展示天气的函数
getWeather(cityCode);
}
});你是怎么理解 Promise ?