first commit

This commit is contained in:
编码猿
2024-09-27 02:06:13 +08:00
commit 852d94fbb9
36760 changed files with 3274413 additions and 0 deletions

View File

@@ -0,0 +1,29 @@
class Ajax{
constructor() {
this.ajax = new XMLHttpRequest ()
}
/**
* * @param{*}params
* {
* 请求的网址 url:"",
*
* 请求的参数 data:{
* (对象) id:1,
* page:2
* },
*
* 请求头 header:{
* (对象) 'Content-Type':'application/json;charset=UTF-8'
* },
*
* 请求成功的回调 success:(res)=>{},
* (方法)
*
* 请求失败的回调 erro:(err)=>{不同地方的错误提示也不一样,可以不用但必须要有},
* }
*/
get(params){
ajax.open("GET","http://localhost")
}
post(){}
}

View File

@@ -0,0 +1,142 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>promise</title>
</head>
<body>
<!-- promise是es6的时候才更新出来的:promise本身是同步的,但调用promise的过程是异步的(then通过回调拿结果) -->
<!-- Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理且更强大。
它最早由社区提出并实现,ES6将其写进了语言标准,统一了用法,并原生提供了Promise对象。
JS执行——Promise: Pending状态(进行中)
Fulfilled状态(已成功)
Rejected状态(已失败)
一旦状态改变就不会再变 (两种状态改变:成功或失败)
Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolve和reject。
resolve:将Promise对象状态由“未完成”变为“成功”,即Pending -> Fulfilled,在异步操作成功时调用,并将异步操作的结果作为参数传递出去
reject:将Promise对象状态由“未完成”变为“失败”,即Pending -> Rejected,在异步操作失败时调用,并将异步操作的结果作为参数传递出去。
Promise实例生成后,可用then方法分别指定两种状态回调参数。then 方法可以接受两个回调函数作为参数:
在Promise新建后会立即执行,然后,then方法指定的回调函数将在当前脚本所有同步任务执行完后才会执行。
then在Promise对象状态改为Resolved时调用 (必选);Promise对象状态改为Rejected时调用 (可选)
拓展 async/await
async:异步——————————async 函数必定返回 Promise,我们把所有返回 Promise 的函数都可以认为是异步函数。
特点体现在以下四点: 内置执行器
更好的语义
更广的适用性
返回值是 Promise
await:等待——————————await命令后面一般是一个 Promise 对象,返回该对象的结果(利用await来等待一个Promise。)如果不是 Promise 对象,就直接返回对应的值。
另一种情况是,await命令后面是一个thenable对象(即定义then方法的对象),那么await会将其等同于 Promise 对象。
Promise优缺点:
优点 缺点
解决回调 无法监测进行状态
链式调用 新建立即执行且无法取消
减少嵌套 内部错误无法抛出 -->
<!-- 链式调用:当一个方法执行结束以后直接把返回值用于下一个方法
例:
num = 0;
test(){
this.num += 1
return this.num
}
test2(){
this.num += 100
return this.num
}
按理说test() 和 test2() 分别调用两次 ,console.log(ajax.test2())即1+100=101;
num = 0;
test(){
this.num += 1
return this (返回了一个this指向)
}
test2(){
this.num += 100
return this.num
}
链式调用写法:var result = ajax.test().test2() console.log(result)即可
因此,一定要确认this指向的正确性!!! -->
</body>
<script src="./ajax promise.js"></script>
<!-- promise异步方案 -->
<!-- <script>
console.log(1);
ajax.get({
url:"http://localhost",
data:{
id:1,
page:2
},
header:{
'Content-Type':'application/json;charset=UTF-8'
}
}).then(res => {
console.log("2",res);
}).catch(err => {
console.log(err);
})
console.log(3);
</script> -->
<!-- promise同步方案:将promise的异步调用转为同步调用 -->
<script>
// console.log(1);
ajax.get({
url:"http://localhost",
data:{
id:1,
page:2
},
header:{
'Content-Type':'application/json;charset=UTF-8'
}
}).then(res => {
console.log("2",res);
}).catch(err => {
console.log(err);
})
// console.log(3);
// async写在最近的方法名前面,和await配套使用
var a = async () => {
console.log(1);
var res = await ajax.get({
url:"http://localhost",
data:{
id:1,
page:2
},
header:{
'Content-Type':'application/json;charset=UTF-8'
}
})
console.log("2",res);
console.log(3);
}
console.log(4);
// a外部方法调用是异步的,a内部是同步的,先跑完异步再来跑同步
a();
console.log(5);
// 结果:4 1 5 23
// 原因如下:首先从上往下同步执行4,到a(),执行了1,发现await内部等待,外部就跑去执行5,最后等待得到2和3
</script>
</html>

View File

@@ -0,0 +1,38 @@
class Ajax{
constructor() {
this.ajax = new XMLHttpRequest();
}
get(params){ //(success,error)
return new Promise((resolve,reject) => {
var str = ""
for (const key in params.data) {
str += `&${key}=${params.data[key]}`
}
str = str.replace("&", "?")
this.ajax.open("GET", `${params.url}${str}`)
this.ajax.send()
this.readystatechange(resolve, reject)
})
}
post() { }
readystatechange(resolve, reject) {
this.ajax.onreadystatechange = () => {
if (this.ajax.readyState == 4) {
if (this.ajax.status == 200) {
var data = JSON.parse(this.ajax.responseText)
// console.log(data);
resolve(data)
} else {
reject(this.ajax)
}
}
}
}
}
var ajax = new Ajax();

View File

@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- ajax请求代码的封装一般分为三层: config 配置层 serve 请求中间层 ajax 封装层 -->
顺序: 配置 ————> 工具函数 ————>ajax ————> sever ————> page
</body>
<script src="./ajax回调函数.js"></script>
<script>
// 异步转同步 回调函数callback微信小程序常使用
ajax.get({
url:"http://localhost",
data:{
id:1,
page:2
},
header:{
'Content-Type':'application/json;charset=UTF-8'
},
success:(res)=>{
console.log(res);
},
error:(err)=>{},
})
</script>
</html>

View File

@@ -0,0 +1,75 @@
class Ajax {
constructor() {
this.ajax = new XMLHttpRequest();
// 请求监听全局只运行一次,是异步的,有需要(先send再监听)就运行,不需要就待机
// 监听放这里参数很难回调出去,原因是get和readystate是相互独立(局部)的
// this.readystatechange();
// 局部变全局
this.success = null
}
// java中“@”大多代表注解的意思。那么@param是用来在DAO层中声明参数的注解方式。
// @ param标签可以归档方法或构造器的某个单一参数,或者归档类、接口以及泛型方法的类型参数。
// 在使用@ param标签时,我们应该针对方法的每一个参数都使用一个该标签。
// 每个段落的第一个词会被当作参数名,而余下的部分则会被当作是对它的描述。
/**
* 接收多个参数,所以封装一个对象直接接收对象
*
* @param{*}params
* {
* 请求的网址 url:"",
*
* 请求的参数 data:{
* (对象) id:1,
* page:2
* },
*
* 请求头 header:{
* (对象) 'Content-Type':'application/json;charset=UTF-8'
* },
*
* 请求成功的回调 success:(res)=>{},
* (方法)
*
* 请求失败的回调 error:(err)=>{不同地方的错误提示也不一样,可以不用但必须要有},
* }
*/
get(params) {
this.success = params.success
var str = ""
// get的传参形式是url+?key=value,但我们的参数是对象,所以要转换(字符串拼接和符号替换)
// 对对象遍历,拿到值
// this.ajax.open("GET","http://localhost")
for (const key in params.data) {
// console.log("key",key);
str += `&${key}=${params.data[key]}`
}
str = str.replace("&", "?")
this.ajax.open("GET", `${params.url}${str}`)
// console.log(`${params.url}${str}`);
this.ajax.send();//send必须要有状态监听,多个共用一个状态监听即可
// 监听放在这里用可以直接把后端的参数回调出去
this.readystatechange(params.success, params.error)
}
post() { }
readystatechange(success,error) {
this.ajax.onreadystatechange = () => {
// console.log(this.ajax.readyState);
if (this.ajax.readyState == 4) {
// 后端给我们的数据保存在response和responseText里
if (this.ajax.status == 200) {
var data = JSON.parse(this.ajax.responseText)
// console.log(date);
success(data)
this.success(data)
} else {
error(this.ajax)
}
}
}
}
}
var ajax = new Ajax();

View File

@@ -0,0 +1,148 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<ul>
</ul>
<!-- <form action="">
<input type="text" name="id">
</form> -->
<!-- ajax如何调试(接口不通)控制台无数据/渲染页面不进行:
解决方案——————网络——>1 Fetch/XHR 请求状态是否为200——>2 载荷 查询参数是否传递成功——>3 预览 后端是否返回相关数据
都没问题,查找自己的代码是否有错。 -->
<!-- ajax:前后端交互的工具(无刷新的数据交互方式) -->
<!-- 数据格式:json格式=对象object+数组array (曾经用的xml——标签套标签) -->
<!-- 请求<————————>响应 -->
<!-- http(超文本传输协议)请求:
1 请求头:存放客户端亲请求基本信息
2 请求体:
3 响应头:存放服务器基被请求本信息
4 请求状态码: 200请求成功 202请求接收到但还未处理完成 204成功处理请求但不需返回信息
404找不到对应资源或请求地址 406无法响应 408请求发送超时
500 服务器内部错误无法完成请求
5 请求方式: (rsa超级加密)
① GET 要
传参在网址后面添加(?key=vaule&key=vaule...) 即:"http://127.0.0.1/index.php?id=1"
简单好用,但不适合提交一些敏感数据(账户密码等)
② POST 给
传参放在请求体里面ajax.send(参数)
请求头种类:application/json(最常用)
application/x-www-form-urlencoded form表单
multipart/form-data 上传文件
get和post的区别:参数:get———— url传递 ;post————— requestbody传递 ;
长度:get———— url长度有限(实际上是浏览器和服务器对url的限制) ;post————— 没有 ;
安全:get———— 将参数直接暴露在url上所以不能产地敏感信息 ;post————— 没有 ;
编码:get———— 只能进行url编码 ;post————— 多种 ;
速度:get———— data都在url里,所以速度较快 ;post————— ;
缓存:get———— 可以被浏览器缓存 ;post————— 不会 ;
数据包:get———— http将header和data一并发送所以只残生一个数据包服务器响应200 ;post————— 浏览器先header服务器响应100再data响应200 ;
本质:总得来说没有差别,底层都是tcp/ip协议,但由于http的规定和浏览器的限制,导致使用过程中出现差别。
③ PUT 更新 请求体
④ DELETE 删除 请求体
⑤ OPTIONS 预检测
-->
<!-- 跨域 解决 浏览器 同源策略(协议http/域名 中间内容 /端口 默认:http80——https443) -->
<!-- 三种解决方案: 1 cors 后端设置请求头 允许跨域
(只能发get请求)2 jsonp 把 ajax请求 伪装成 js文件请求,绕过 同源策略 达到 发送请求 的目的,通过 回调函数 拿回数据
3 服务器代理 a前端————>(http://127.0.0.1/my(自己后端).php) a后端 请求内容:($data = file_get_contents("http://127.0.0.1/index(别人后端).php"); echo $data()得到参数————>b后端 -->
<!-- http的请求状态码大于ajax的请求状态 -->
<!-- console.log(ajax): readyState (存储的ajax的状态(0——4),当readyState属性改变时,就会调用该函数)
0_请求未初始化 1_服务器连接已建立 2_请求已接收 3_请求处理中 4_请求已完成,且相应已就绪 -->
</body>
<script>
// 步骤:
// 1 创建一个新的ajax对象
// 2 配置需要访问的后端地址和请求方式
// 3 发送请求(传参)并监听请求
// 1 创建一个新的ajax对象
// XMLHttpRequest 和 fetch(es6) 都是ajax的请求方式
var ajax = new XMLHttpRequest()
// 2 配置需要访问的后端地址和请求方式 ajax.open("请求方式","地址")
ajax.open("GET", "http://localhost?id=1")
// 3 发送请求(传参)并监听请求
ajax.send()
// 例:post传参
// ajax.open("POST","http://localhost")
// var params = {
// id : 1
// }//"对象"
// 手动更改请求头
// ajax.setRequestHeader('Content-Type','application/json;charset=UTF-8')
// ajax.send(JSON.stringify(params)//“对象转字符串”)
// 例:form表单
// var form = new FormData();
// form.append("username",1)
//var a = "id=1"
// ajax.setRequestHeader('Content-Type','application/x-www-form-urlencoded;charset=UTF-8')
// ajax.send(a)
ajax.onreadystatechange = function () {
// console.log(ajax);
if (ajax.readyState == 4) {
// 后端给我们的数据保存在response和responseText里,但浏览器在网络传输过程中只能以 字符串 的形式。
// (询问数据类型可用typeof),因此需要手动转变一下: 字符串————对象 :JSON.parse
// 对象————字符串 :JSON.stringify
if (this.ajax.ststus == 200) {
var data = JSON.parse(ajax.responseText)
console.log(data);
date.result.forEach(v => {
document.querySelector("ul").innerHTML += `<li>${v.title}</li>`
});
}
} else {
alert("网络请求失败")
}
}
// jsonp跨域
// 前端:
// function getDate(res){
// console.log(res);
// }
// <script src="http://localhost?cb=getDate"></script>
<!-- 后端:
$cb = $_GET['getDate'];
echo json_encode($arr);
getDate(参数)
echo $cb."(".json_encode($arr).")"; -->
</script>
</html>

View File

@@ -0,0 +1,33 @@
/* 清除浏览器默认样式 */
body,h1,h2,h3,h4,h5,h6,ul,li,p {
margin: 0;
padding: 0;
}
body {
font-size: 0;
}
li {
list-style: none;
}
input {
border: none;
outline: none;
padding: 0;
}
a {
text-decoration: none;
color: #333;
}
::-webkit-scrollbar {
width: 0;
height: 0;
}
img {
width: 100%;
}

View File

@@ -0,0 +1,21 @@
.title {
padding: 0 15px;
font-size: 16px;
font-weight: 400;
padding-top: 20px;
margin-bottom: 10px;
}
.menu_list {
padding: 0 15px;
display: flex;
flex-wrap: wrap;
}
.menu_list li {
padding: 3px 10px;
font-size: 14px;
background: var(--themeColor);
margin-right: 10px;
color: #fff;
border-radius: 20px;
margin-bottom: 7px;
}

View File

@@ -0,0 +1,151 @@
.header {
position: fixed;
width: 100%;
height: 1.6rem;
top: 0;
left: 0;
right: 0;
z-index: 99;
}
.header .header_logo {
background: var(--themeColor);
height: 0.88rem;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 0.3rem;
}
.header .header_logo i {
font-size: 0.45rem;
color: var(--whiteColor);
}
.header .header_logo .search {
flex: 1;
background: var(--whiteColor);
height: 0.6rem;
border-radius: 0.6rem;
margin-left: 10px;
margin-right: 10px;
display: flex;
align-items: center;
}
.header .header_logo .search span {
font-size: var(--fontSize12);
color: var(--textColor);
}
.header .header_logo .search i {
color: var(--textColor) !important;
font-size: 0.26rem !important;
margin-right: 0.1rem;
padding-top: 0.02rem;
margin-left: 0.26rem;
}
.header_menu {
height: 0.72rem;
display: flex;
align-items: center;
background: #fe7fa2;
}
.header_menu a {
color: #fff;
text-decoration: none;
width: 0.8rem;
height: 0.72rem;
text-align: center;
line-height: 0.72rem;
}
.header_menu ul {
display: flex;
flex: 1;
overflow-x: scroll;
padding-left: 0.3rem;
}
.header_menu ul li {
font-size: 0.26rem;
margin-right: 0.26rem;
color: #d3d2d2;
flex-shrink: 0;
}
.header_menu ul .active {
color: var(--whiteColor) !important;
}
.content {
margin-top: 1.6rem;
margin-bottom: 1rem;
}
.swiper {
width: 100%;
}
/* 固定contant可视区域,超出部分则滚动 */
.swiper-slide {
height: calc(100vh - 1.6rem - 1rem);
overflow-y: scroll;
}
.list {
padding: 10px;
box-sizing: border-box;
display: flex;
justify-content: space-between;
flex-wrap: wrap;
}
.list .item {
width: 48%;
flex-shrink: 0;
margin-bottom: 0.24rem;
}
.list .item_top {
position: relative;
}
.list .item_top img {}
.list .item_top span {
bottom: 0.1rem;
right: 0.16rem;
position: absolute;
font-size: 0.24rem;
background: var(--themeColor);
color: #fff;
padding: 0.02rem 0.12rem;
border-radius: 0.16rem;
}
.list .item_text {}
.list .item_text .title {
font-size: 0.34rem;
font-weight: 400;
margin-top: 0.2rem;
}
.list .item_text .model {
font-size: 0.28rem;
color: #bdb7b7;
}
.list .item_text .source {
font-size: 0.28rem;
color: #bdb7b7;
}
.list .item_tag {
margin-top: 0.1rem;
display: flex;
flex-wrap: wrap;
}
.list .item_tag .tage_item {
font-size: 0.24rem;
flex-shrink: 0;
padding: 0.08rem 0.18rem;
background: var(--themeColor);
margin-right: 0.1rem;
color: #fff;
border-radius: 0.2rem;
margin-bottom: 0.1rem;
}

View File

@@ -0,0 +1,54 @@
.hot{
height: calc(100vh - 0.9rem - 1rem);
overflow-y: scroll;
}
.hot_model{
padding-top: 30px;
font-size: 18px;
margin-left: 10px;
}
.hot_modelAll{
display: flex;
flex-wrap: wrap;
padding: 4px 7px;
box-sizing: border-box;
}
.model{
width: 60px;
margin: 15px;
}
.model a{}
.model .model_top{
position: relative;
}
.model .model_top img{
width: 100%;
border-radius: 50%;
}
.model .model_top span{
color: var(--whiteColor);
font-size: 10px;
height: 18px;
width: 40px;
background: #3333338f;
position: absolute;
text-align: center;
line-height: 18px;
border-radius: 10px;
bottom: -2px;
left: 10px;
transform: scale(0.8);
}
.model_bottom{
color: var(--textColor);
font-size: 10px;
transform: scale(0.8);
margin-top: 8px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

View File

@@ -0,0 +1,80 @@
/* 公共使用率高的css代码 */
:root {
--themeColor: #fb7299;
--whiteColor: #fff;
--blackColor: #000;
--textColor: #999;
--fontSize12: 0.24rem;
--fontSize13: 0.26rem;
--fontSize14: 0.28rem;
--fontSize15: 0.3rem;
--fontSize16: 0.32rem;
--fontSize17: 0.34rem;
--fontSize18: 0.36rem;
--fontSize19: 0.38rem;
--fontSize20: 0.4rem;
--fontSize21: 0.42rem;
}
.ellipsis {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.footer {
justify-content: space-around;
display: flex;
height: 1rem;
align-items: center;
position: fixed;
border-top: 0.02rem solid #e2e2e2;
width: 100%;
bottom: 0;
left: 0;
right: 0;
z-index: 99;
background: var(--whiteColor);
}
.footer li {
text-align: center;
}
.footer li p {
font-size: 0.24rem;
margin-top: 0.04rem;
}
.footer .active a {
color: var(--themeColor);
}
.pub_header {
height: .9rem;
width: 100%;
position: fixed;
left: 0;
top: 0;
right: 0;
background: var(--themeColor);
color: #fff;
display: flex;
align-items: center;
padding: 0 10px;
box-sizing: border-box;
}
.pub_header i {
font-size: .4rem;
}
.pub_header .text {
font-size: .36rem;
flex: 1;
margin-left: .28rem;
}
.content {
margin-top: .9rem;
}

View File

@@ -0,0 +1,75 @@
class Ajax{
constructor(){
// 1 创建一个新的ajax对象
this.ajax = new XMLHttpRequest();
}
// 2 配置需要访问的后端地址和请求方式
// get请求
get(params){
return new Promise((success,error) =>{
//传参数?key=value格式
var str = ""
for (const key in params.data) {
str += `&${key}=${params.data[key]}`
}
str = str.replace("&", "?")
//请求基地址+接口+参数
this.ajax.open("GET",`${config.checkUrl()}${params.url}${str}`)
// 3 发送请求
this.ajax.send()
//并监听请求
this.readystatechange(success,error)
})
}
post(){}
//状态监听
readystatechange(success,error){
//状态改变就会触发
this.ajax.onreadystatechange = () => {
//ajax请求状态
if(this.ajax.readyState == 4){
//http请求状态
if(this.ajax.status == 200){
//JSON.parse一般用于将JSON字符串转化为JSON对象
var data = JSON.parse(this.ajax.responseText)
//成功走接口状态判断
success(this.checkStatus(data))
}else{
error(this.ajax)
}
}
}
}
//接口状态码判断,程序员随意定义
//所有接口都要走状态码判断,处理方式不一样的都要写,一样的写一个就可以了
checkStatus(data){
switch (data.status) {
case 200:
return data.result
break;
case 404:
//msg接口状态码解释
alert(data.msg);
//抛出一个错误,throw(打断浏览器代码运行) new error
throw new Error(data.msg)
break;
default:
break;
}
}
}

View File

@@ -0,0 +1,48 @@
var config = {
//不同阶段 不同使用地址
devBaseUrl: 'http://127.0.0.1:3000/api/json', // 开发阶段
testBaseUrl: 'http://127.0.0.1:3000/api/test', // 测试阶段
prodBaseUrl: 'http://192.168.31.100:3000/api/json', // 上线阶段
// 选择阶段循环判断使用不同地址
stage: 'dev', // dev test prod
// 总接口汇集
apiList:{
index: '/index',
//详情接口
info: '/info',
//分类列表
classList: '/class',
//分类详情列表
classListArr: '/classList',
model:`/allModel`
},
// 页面底部信息地址储存
footerList:[
{ title: '首页', icon: 'icon-home', url: 'index.html' },
{ title: '机构', icon: 'icon-jigou', url: 'mechanism.html' },
{ title: '模特', icon: 'icon-me', url: 'model.html' },
{ title: '我的', icon: 'icon-wo', url: 'my.html' },
],
//循环判断添加请求基地址
checkUrl: function () {
switch (this.stage) {
case "dev":
return this.devBaseUrl
break;
case "test":
return this.testBaseUrl
break;
case "prod":
return this.prodBaseUrl
break;
default:
break;
}
}
}

View File

@@ -0,0 +1,112 @@
class Edit {
constructor() {
header("分类编辑")
//将存储的数据提取出来使用 JSON.parse字符串转对象
this.principal = JSON.parse(localStorage.getItem("principal"))
this.additional = JSON.parse(localStorage.getItem("additional"))
this.renderPrincipal()
this.renderAdditional()
}
//渲染已选菜单
renderPrincipal() {
//生成网页
this.principal.forEach(v => {
$(".principal").html(`
<li>${v.title}</li>
`)
});
//绑定事件
this.PrincipalClick()
}
//已选菜单点击事件
PrincipalClick() {
var self = this;
//先绑定事件
click(_(".principal li"), function () {
// 首先去除首页,不可点击不可选择
if (this.index != 0) {
console.log("index: ",this.index);
// 深拷贝
// var oldArr = JSON.parse(JSON.stringify(self.principal));
//删除已选
//c先存储在a additional,再删掉b principal里面的c
self.additional.push(self.principal[this.index])
//已选里被删除的项 splice删除数组里的某元素
var deleteAItem = self.principal.splice(this.index, 1)
// 然后将修改后的内容,更新保存在本地 JSON.stringify对象转字符串
localStorage.setItem("principal", JSON.stringify(self.principal))
localStorage.setItem("additional", JSON.stringify(self.additional))
//可选追加删除项
$(".additional").html(`
<li>${deleteAItem[0].title}</li>
`)
//并为追加整体 重新绑定点击事件
self.AdditionalClick()
//已选去除删除项
$(".principal").removeChild(this)
//并为删除整体 重新绑定点击事件
self.PrincipalClick()
}
})
}
//渲染可选菜单
renderAdditional() {
//生成网页
this.additional.forEach(v => {
$(".additional").html(`
<li>${v.title}</li>
`)
});
//绑定事件
this.AdditionalClick()
}
//可选菜单点击事件
AdditionalClick() {
var self = this;
click(_(".additional li"), function () {
//已选追加
//c先存储在b,再删掉a里面的c
self.principal.push(self.additional[this.index])
//可选里的被删除项
var deleteAItem = self.additional.splice(this.index, 1)
// 然后将修改后的内容,更新保存在本地 JSON.stringify对象转字符串
localStorage.setItem("principal", JSON.stringify(self.principal))
localStorage.setItem("additional", JSON.stringify(self.additional))
// 已选追加删除项
$(".principal").html(`
<li>${deleteAItem[0].title}</li>
`)
//重新绑定点击事件
self.PrincipalClick();
//可选移除删除项
$(".additional").removeChild(this)
//重新绑定点击事件
self.AdditionalClick();
})
}
}
new Edit()

View File

@@ -0,0 +1,178 @@
class Index{
constructor(){
this.index = 0;
this.principal = []
//网页重新渲染innerhtml会导致之前绑定的事件解绑
footer();
this.getClassList()
}
//菜单列表
async getClassList(){
var that = this;
var res = await indexServe.classList();
// console.log(res);
this.principal = res.principal
// 如果本地没有储存数据,则发出请求并进行存储
if (localStorage.getItem("principal") == null) {
var res = await indexServe.classList();
this.principal = res.principal
//JSON.stringify转为字符串 principal固定菜单 additional可选菜单
localStorage.setItem("principal", JSON.stringify(this.principal))
localStorage.setItem("additional", JSON.stringify(res.additional))
} else {
// 有数据则提取出来
this.principal = JSON.parse(localStorage.getItem("principal"))
}
res.principal.forEach((v, i) => {
$(".header_menu ul").html(
` <li class="${i == 0 ? 'active' : ''}">${v.title}</li>`
)
$(".page_wrapper").html(
`<div class="swiper-slide">
<div class="list">
</div>
</div>`
);
//绑定滑动事件并判断是否滑动到底部,是否需要追加数据
_(".swiper-wrapper .swiper-slide").forEach(v => {
v.onscroll = () => {
const {clientHeight, scrollHeight, scrollTop} = v;
const distance = scrollHeight- scrollTop - clientHeight;
console.log(clientHeight, scrollHeight, scrollTop, distance);
//预加载阈值(提前加载)常在30~50之间
if(distance <= 10) {
// 首页
console.log("滚动到底部...");
if (this.index == 0) {
this.getIndex()
} else {
this.principal[this.index].page += 1
if (this.principal[this.index].page <= this.principal[this.index].total_page) {
//传一个more区别于默认的click点击事件
this.getClassListArr("more")
} else {
console.log("已经没有数据了!!!");
}
}
}
}
})
})
//箭头函数会解绑this指向,所以不能用
click(_(".header_menu ul li"), function () {
that.changeActive(this.index)
})
this.getIndex()
this.initPage()
}
//分类详情列表
//接收参数 默认点击事件
async getClassListArr(type = "click") {
//将传参方式封装起来,需要的地方直接调用即可
var getData = async () => {
var res = await indexServe.classListArr({
page: this.principal[this.index].page,
id: this.principal[this.index].id
});
//请求存储总页数详情
this.principal[this.index].total_page = res.total_page
//总内容=旧内容+新追加
this.principal[this.index].content = [
...this.principal[this.index].content,
...res.data
];
item(
//数组加下标
_(".swiper-slide .list")[this.index],
// this.principal[this.index].content
res.data
)
}
//当是点击事件时执行
if (type == "click") {
if (this.principal[this.index].id != -1) {
//数组为空请求数据(避免重复请求的问题出现)
if (this.principal[this.index].content.length == 0) {
getData()
}
}
} else {
getData()
}
}
// 更改激活态
changeActive(index) {
//最新下标保存到全局
this.index = index
_(".header_menu ul li").forEach(v => v.remove("active"))
_(".header_menu ul li")[index].add("active")
//slideTo滑向(下标)
this.mySwiper.slideTo(index)
}
//请求数据首页接口内容
//扩展运算符(...)是ES6的语法,用于取出参数对象的所有可遍历属性,然后拷贝到当前对象之中。
async getIndex() {
var res = await indexServe.index();
console.log('this.principal[this.index].content',this.principal,this.index);
this.principal[this.index].content = [
...this.principal[this.index].content,
...res.list
];
item(_(".swiper-slide .list")[this.index], res.list)
}
//滑动
initPage() {
var that = this;
// this.name在当前类里面定义一个全局变量
this.mySwiper = new Swiper('.swiper-container', {
direction: 'horizontal',
//监听滑动是否结束,结束取的其下标this.activeIndex
on:{
slideNextTransitionEnd: function() {
that.changeActive(this.activeIndex)
that.getClassListArr()
},
},
})
}
}
new Index()

View File

@@ -0,0 +1,91 @@
class Info {
constructor() {
//默认没收藏
this.isLike = false
this.Storage = []
this.indexOfStorage()
//参数= 标题 + 图标(标签)
//判断是否收藏进行相关图标更改
header("详情", `<i class="iconfont ${ this.isLike ? 'icon-aixin' : 'icon-xin' } xin"></i>`)
this.getInfo();
this.clickXin()
}
async getInfo() {
// console.log("res: ", res);
var res = await indexServe.info({
//利用query方法取得地址栏参数
id: query("id"),
quantity: query("total")
});
//循环插入图片地址
res.forEach(v => {
$(".content").html(`<img src="${v}" alt="">`)
});
// console.log("res: ", res);
}
// 执行删除元素
indexOfStorage(){
// 获取本地like数据,判断是否有值,有则以对象形式取出来,没有则依旧为[]
this.Storage = localStorage.getItem("like")? JSON.parse(localStorage.getItem("like")) : []
//为空不执行,直接return
if(this.Storage.length == 0){
return;
}
//不为-1则有值
if(this.Storage.indexOf(query("id")) != -1){
// 默认收藏
this.isLike = true
//this.Storage.indexOf(query("id"))包含则返回query("id")的下标
//splice(下标,个数)删除数组里的某个元素
this.Storage.splice( this.Storage.indexOf(query("id")) ,1)
console.log('this.Storage',this.Storage);
//删除后进行重新存储
localStorage.setItem('like',JSON.stringify(this.Storage))
}
}
//给图标绑定点击事件
clickXin() {
var that = this
// console.log('_(".iconfont .icon-xin"',_(".icon-xin"));
click(_(".xin"), function () {
//收藏
//this就是_(".xin")
// indexOf可以查找字符串值,有则返回下标,没有则返回-1
if(this.className.indexOf(("icon-xin")) != -1){
//localStorage.setItem将数据存储到本地(传输形式只有字符串),JSON.stringify将对象转为字符串
//收藏存储到本地,将id存进去,因为可能会有多个,所以是数组。
//。。。追加进去,原来的加上新的
localStorage.setItem("like", JSON.stringify([ ...that.Storage,query("id") ]))
this.remove("icon-xin")
this.add("icon-aixin")
//取消收藏
}else if(this.className.indexOf(("icon-aixin"))){
that.indexOfStorage()
this.remove("icon-aixin")
this.add("icon-xin")
}
})
}
}
new Info();

View File

@@ -0,0 +1,91 @@
class Info {
constructor() {
header("详情", `<i id="collection" class="iconfont icon-xin"></i>`)
this.getInfo();
this.Like()
}
setLike(id) {
const like = this.getLike()
//“&&”连接两个表达式,当两侧表达式都为真时,返回TRUE
//当这个是数组的时候,追加id
if (!!like && Array.isArray(like)) {
like.push(id)
// 更新本地数据
localStorage.setItem("like", JSON.stringify(like))
} else {
// 返回空数组则追加单个id
localStorage.setItem("like", JSON.stringify([id]))
}
}
//获取本地数据,有则返回数组,没有则返回空
getLike() {
const like = JSON.parse(localStorage.getItem("like"))
if (!!like && Array.isArray(like)) {
return like
}
return []
}
removeLinke(id) {
let like = this.getLike()
like = like.filter(v => v !== id)
localStorage.setItem("like", JSON.stringify(like))
}
changeLikeStyle() {
const collectionDom = $("#collection")
const id = query("id")
const like = this.getLike()
if (like.indexOf(id) === -1) {
collectionDom.remove("icon-aixin")
collectionDom.add("icon-xin")
} else {
collectionDom.remove("icon-xin")
collectionDom.add("icon-aixin")
}
}
onLinke() {
const id = query("id")
const like = this.getLike()
if (like.indexOf(id) === -1) {
this.setLike(id)
this.changeLikeStyle()
} else {
this.removeLinke(id)
this.changeLikeStyle()
}
}
Like() {
const collectionDom = $("#collection")
this.changeLikeStyle()
click(collectionDom, () => {
this.onLinke()
})
}
async getInfo() {
var res = await indexServe.info({
id: query("id"),
quantity: query("total")
});
res.forEach(v => {
$(".content").html(`<img src="${v}" alt="">`)
});
//console.log("res: ", res);
}
}
new Info();

View File

@@ -0,0 +1,32 @@
class Like{
constructor(){
header("我的收藏")
}
}

View File

@@ -0,0 +1,31 @@
class collection {
constructor() {
header("我的收藏")
this.like = JSON.parse(localStorage.getItem("like"))
this.getlike()
this.renderlike()
}
async getlike() {
var self = this;
if (localStorage.getItem("like") == null) {
var res = await indexServe.classList();
this.like = res.like
localStorage.setItem("like", JSON.stringify(this.like))
}
else {
this.like = JSON.parse(localStorage.getItem("like"))
}
}
renderlike() {
this.like.forEach(v => {
$(".item").html(`
<div>${v.title}</div>
`)
});
this.PrincipalClick()
}
}
new collection

View File

@@ -0,0 +1,10 @@
class mechanism{
constructor(){
footer();
}
}
new mechanism()

View File

@@ -0,0 +1,73 @@
class Model {
constructor () {
header("模特")
footer();
this.getModel()
this.hotscroll()
}
async getModel() {
var res = await indexServe.model()
// console.log(res);
model($('.hot_modelAll'),res)
// for(var key in data){ }
// var data = _(".hot_modelAll .model")
// for(var key in data){
// // console.log(_(".hot_modelAll .model"));
// console.log(key, data[key]);
// key = 0
// data[key].onscroll = (v => {
// const {clientHeight, scrollHeight, scrollTop} = v;
// const distance = scrollHeight- scrollTop - clientHeight;
// console.log(clientHeight, scrollHeight, scrollTop);
// if(distance <= 10){
// console.log("滚动到底部...");
// this.getModel()
// }
// })
// }
// NodeList转为数组
// _(".hot_modelAll .model") = [..._(".hot_modelAll .model")]
// Object.keys( _(".hot_modelAll .model")).forEach((value) => {
// // console.log(_(".hot_modelAll .model"));
// console.log(Object.keys( _(".hot_modelAll .model")));
// value.onscroll = () => {
// const {clientHeight, scrollHeight, scrollTop} = value;
// const distance = scrollHeight- scrollTop - clientHeight;
// console.log(clientHeight, scrollHeight, scrollTop);
// if(distance <= 10){
// console.log("滚动到底部...");
// this.getModel()
// }
// }
// })
};
hotscroll() {
console.log("$('.hot')",$('.hot'));
$('.hot').onscroll = () => {
// console.log('123');
const {clientHeight, scrollHeight, scrollTop} = $('.hot');
const distance = scrollHeight- scrollTop - clientHeight;
console.log(clientHeight, scrollHeight, scrollTop);
if(distance <= 10){
console.log("滚动到底部...");
this.getModel()
}
}
}
}
new Model()

View File

@@ -0,0 +1,11 @@
class my{
constructor(){
footer();
}
}
new my()

View File

@@ -0,0 +1,87 @@
class IndexSever{
//用接口名,方便后面的config接口数据发生更改
//apiList 的 index接口(首页)
async index(data = {}){
//调接口的时候生成独立的一个ajax保存变量,互不干扰
var ajax = new Ajax()
var res = await ajax.get({
//接口+参数
url:config.apiList.index,
data:data,
});
// 使用完以后删除ajax,减少内存占用
ajax = null;
return res
}
//apiList 的 index接口(首页)
async classListArr(data = {}){
return await (new Ajax()).get({
//接口+参数
url:config.apiList.classListArr,
data:data,
});
}
//apiList 的 classList接口(菜单)
async classList(data = {}){
var res = await (new Ajax()).get({
//接口+参数
url:config.apiList.classList,
data:data,
});
//后端数据没有首页 手动添加首页
//push 追加内容(最后) unshift追加数据(从头)
//principal后端菜单列表命名
res.principal.unshift({
id: -1,
page: 1,
title: "首页",
})
// 添加内容
res.principal.forEach(v => {
v.content = [];
//后端page从1开始
v.page = 1;
//总页数
v.total_page = 0
})
return res;
}
async info(data = {}) {
return await (new Ajax()).get({
url: config.apiList.info,
data: data,
});
}
async model(data = {}) {
return await (new Ajax()).get({
url: config.apiList.model,
data: data,
});
}
}
var indexServe = new IndexSever()

View File

@@ -0,0 +1,175 @@
class Util {
inject() {
//prototype给对象的构造函数 添加 新的属性
//去类名
Element.prototype.remove = function (removeClassName) {
this.classList.remove(removeClassName);
}
//加类名
Element.prototype.add = function (addClassName) {
this.classList.add(addClassName);
}
//返回标签内的文本值
HTMLElement.prototype.text = function (text) {
this.innerText = text;
}
//返回标签内的html
//当它插入元素时,会导致先前元素绑定的事件丢失
HTMLElement.prototype.html = function (text) {
this.innerHTML += text;
}
// HTMLElement.prototype.html = function (text) {
// this.insertAdjacentHTML += text;
// }
}
//公共头部
//参数=标题 + 图标(直接把标签作为参数传入)
header(title = "", icon) {
$("body").html(`
<div class="pub_header">
<i class="iconfont icon-back1"></i>
<div class="text">${title}</div>
${icon}
</div>
`)
//为(".icon-back1")图标绑定点击事件
click($(".icon-back1"), function() {
//返回历史记录
history.back()
})
}
//循环插入 内容 ul里面的li
//接收一个父元素(返回的虚拟dom)和数组
item(father, data) {
// 对数组进行循环
data.forEach(v => {
//${v.img_src (首页接口名称) ||(或) v.preview (其他列表接口名称)},其他同理
//详情页a标签 :参数=id+图片地址
father.html(`
<div class="item">
<a href="./info.html?id=${v.id}&total=${v.total || v.shuliang}">
<div class="item_top">
<img src="${v.img_src || v.preview}" alt="">
<span>${v.total || v.shuliang}</span>
</div>
<div class="item_text">
<div class="title ellipsis">${v.title}</div>
<div class="model ellipsis">模特:${v.user || v.renwulist[0].name}</div>
<div class="source ellipsis">机构:${v.source || v.jigoulist[0].name}</div>
</div>
</a>
<div class="item_tag">
${(v.biaoqianlist || v.tags).map(j => {
return `<div class="tage_item">${j.name || j.title}</div>`
}).toString().replaceAll(",", "")
}
</div>
</div>
`)
})
}
model(father,data){
data.forEach(v => {
father.html(`
<div class="model">
<a href="./modelinfo.html?id=${v.id}">
<div class="model_top">
<img src="${v.img}" alt="">
<span>63套</span>
</div>
<div class="model_bottom">${v.title}</div>
</a>
</div>
`)
})
}
footer(){
var ul = `
<ul class="footer">
${config.footerList.map((v, i) => {
return ` <li class="${location.href.includes(v.url) ? 'active' : ''}">
<a href="${v.url}">
<i class="iconfont ${v.icon}"></i>
<p>${v.title}</p>
</a>
</li>`
}).toString().replaceAll(",", "")
}
</ul>
`;
// console.log(ul);
$("body").html(ul)
}
//正则表达式,用来截取接口url
query(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]); return null;
}
//Array.isArray() 可判断是否是数组
// NodeList类似数组的对象 转化为数组后不为空: [ Element, Element ]
// Element对象表示HTML里的元素 转换后数组为空: [ ]
//因此,将其转化为数组后,判断长度来决定如何绑定点击事件
click(className, callback) {
//Array.from浅拷贝数组实例(将实例转化为数组),返回一个新数组
var domArr = Array.from(className);
//如果是数组,就循环为每一个都绑定点击事件
if (domArr.length != 0) {
className.forEach((v, i) => {
v.onclick = function (e) {
v.index = i;
v.e = e;
//call() bind() apply()调整this指向
callback.call(this)
}
})
} else {
//单个绑定点击事件
className.onclick = function (e) {
className.e = e;
callback.call(this)
}
}
}
//对象{}
$(className){
return document.querySelector(className)
}
//数组[]
_(className){
return document.querySelectorAll(className)
}
}
var {$, _, inject, header, item, footer, query, click ,model} = new Util()
inject()

View File

@@ -0,0 +1,12 @@
; (function (doc, win, undefined) {
var docEl = doc.documentElement,
resizeEvt = 'orientationchange' in win ? 'orientationchange' : 'resize',
recalc = function () {
var clientWidth = docEl.clientWidth;
if (clientWidth === undefined) return;
docEl.style.fontSize = 100 * (clientWidth / 750) + 'px';
};
if (doc.addEventListener === undefined) return;
win.addEventListener(resizeEvt, recalc, false);
doc.addEventListener('DOMContentLoaded', recalc, false)
})(document, window);

View File

@@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/util/rem.js"></script>
<link rel="stylesheet" href="http://at.alicdn.com/t/font_2124975_xxjerwhwts.css">
<link rel="stylesheet" href="../css/clear.css">
<link rel="stylesheet" href="../css/public.css">
<link rel="stylesheet" href="../css/edit.css">
</head>
<body>
<!-- 数据存储到本地。首页数据和编辑数据公用一个接口。 -->
<div class="content">
<div class="title">已选菜单</div>
<ul class="menu_list principal">
</ul>
<div class="title">可选菜单</div>
<ul class="menu_list additional">
</ul>
</div>
</body>
<script src="../js/util/index.js"></script>
<script src="../js/config/index.js"></script>
<script src="../js/ajax/index.js"></script>
<script src="../js/serve/index.js"></script>
<script src="../js/page/edit.js"></script>
</html>

View File

@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<!-- 滑动 -->
<link href="https://cdn.bootcdn.net/ajax/libs/Swiper/4.3.0/css/swiper.min.css" rel="stylesheet">
<script src="../js/util/rem.js"></script>
<link rel="stylesheet" href="http://at.alicdn.com/t/font_2124975_xxjerwhwts.css">
<link rel="stylesheet" href="../css/clear.css">
<link rel="stylesheet" href="../css/public.css">
<link rel="stylesheet" href="../css/index.css">
</head>
<body>
<div class="header">
<div class="header_logo">
<i class="iconfont icon-taozi1"></i>
<div class="search">
<i class="iconfont icon-search"></i>
<span>200万张图,有你想要的...</span>
</div>
<i class="iconfont icon-wo"></i>
</div>
<div class="header_menu">
<ul> </ul>
<a class="iconfont icon-edit" href="./edit.html"></a>
</div>
</div>
<div class="content">
<div class="swiper-container">
<div class="swiper-wrapper page_wrapper">
</div>
</div>
</div>
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/Swiper/4.3.0/js/swiper.min.js"></script>
<script src="../js/config/index.js"></script>
<script src="../js/util/index.js"></script>
<script src="../js/ajax/index.js"></script>
<script src="../js/serve/index.js"></script>
<script src="../js/page/index.js"></script>
</html>

View File

@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/util/rem.js"></script>
<link rel="stylesheet" href="http://at.alicdn.com/t/font_2124975_xxjerwhwts.css">
<link rel="stylesheet" href="../css/clear.css">
<link rel="stylesheet" href="../css/public.css">
<link rel="stylesheet" href="../css/info.css">
</head>
<body>
<div class="content">
</div>
</body>
<script src="../js/util/index.js"></script>
<script src="../js/config/index.js"></script>
<script src="../js/ajax/index.js"></script>
<script src="../js/serve/index.js"></script>
<script src="../js/page/info.js"></script>
</html>

View File

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/util/rem.js"></script>
<link rel="stylesheet" href="http://at.alicdn.com/t/font_2124975_xxjerwhwts.css">
<link rel="stylesheet" href="../css/clear.css">
<link rel="stylesheet" href="../css/public.css">
<link rel="stylesheet" href="../css/like.css">
</head>
<body>
</body>
<script src="../js/util/index.js"></script>
<script src="../js/config/index.js"></script>
<script src="../js/ajax/index.js"></script>
<script src="../js/serve/index.js"></script>
<script src="../js/page/like.js"></script>
</html>

View File

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/util/rem.js"></script>
<link rel="stylesheet" href="http://at.alicdn.com/t/font_2124975_xxjerwhwts.css">
<link rel="stylesheet" href="../css/clear.css">
<link rel="stylesheet" href="../css/public.css">
<link rel="stylesheet" href="../css/mechanism.css">
</head>
<body>
</body>
<script src="../js/util/index.js"></script>
<script src="../js/config/index.js"></script>
<script src="../js/ajax/index.js"></script>
<script src="../js/serve/index.js"></script>
<script src="../js/page/mechanism.js"></script>
</html>

View File

@@ -0,0 +1,39 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/util/rem.js"></script>
<link rel="stylesheet" href="http://at.alicdn.com/t/font_2124975_xxjerwhwts.css">
<link rel="stylesheet" href="../css/clear.css">
<link rel="stylesheet" href="../css/public.css">
<link rel="stylesheet" href="../css/model.css">
</head>
<body>
<div class="content">
<div class="hot">
<div class="hot_model">热门模特</div>
<div class="hot_modelAll">
</div>
</div>
</div>
</body>
<script src="../js/util/index.js"></script>
<script src="../js/config/index.js"></script>
<script src="../js/ajax/index.js"></script>
<script src="../js/serve/index.js"></script>
<script src="../js/page/model.js"></script>
</html>

View File

@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="../js/util/rem.js"></script>
<link rel="stylesheet" href="http://at.alicdn.com/t/font_2124975_xxjerwhwts.css">
<link rel="stylesheet" href="../css/clear.css">
<link rel="stylesheet" href="../css/public.css">
<link rel="stylesheet" href="../css/my.css">
</head>
<body>
</body>
<script src="../js/util/index.js"></script>
<script src="../js/config/index.js"></script>
<script src="../js/ajax/index.js"></script>
<script src="../js/serve/index.js"></script>
<script src="../js/page/my.js"></script>
</html>

View File

@@ -0,0 +1,205 @@
1802 1.19
【张婷】5:模特 列表页面
接口:7
map() 方法返回一个新数组 {.toString().replaceAll(",", "")————————>手动转为字符串},数组中的元素为原始数组元素调用函数处理后的值。
使用 prototype 属性就可以给对象的构造函数 添加 新的属性:
Element 对象可以拥有类型为元素节点、文本节点、注释节点的子节点。
NodeList 对象表示节点列表,比如 HTML 元素的子节点集合。
元素也可以拥有属性 https://blog.csdn.net/m0_53170889/article/details/119414222
location.href 可设置或返回当前显示的文档的完整 URL。
window.location.assign(url) : 加载 URL 指定的新的 HTML 文档。就相当于一个链接,跳转到指定的url,当前页面会转为新页面内容,可以点击后退返回上一个页面。
window.location.replace(url) : 通过加载 URL 指定的文档来替换当前文档,这个方法是替换当前窗口页面,前后两个页面共用一个窗口,所以是没有后退返回上一页的
正则表达式 RegExp
query(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]); return null;
}
^ 从开始行开始匹配
| 或运算符,匹配|符号前或后的字符
[] 内为字符集,匹配 [ ] 内任一字符
* 匹配 >= 0 个 * 号前的字符。
[^ ] 匹配除了方括号里的任意字符
正则表达式用于定义一些字符串的规则。计算机可以根据正则表达式,来检查一个字符串是否符合指定的规则,或者将字符串中符合规则的内容提取出来。
search 从问号 (?) 开始的 URL(查询部分)
substr(start, length)方法是用来截取字符串的 start是要截取字符串的开始下标,length是要截取的长度。
match() 方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配。返回值数组
unescape() 函数可对通过 escape() 编码的字符串进行解码 unescape() 函数已经从 Web 标准中删除,所以尽量不使用该函数,可以使用 decodeURI 或 decodeURIComponent 代替。
click(className, callback) {
var domArr = Array.from(className);
if (domArr.length != 0) {
className.forEach((v,i) => {
v.onclick = function (e) {
v.index = i;
v.e = e;
callback.call(this)
}
})
} else {
className.onclick = function (e) {
className.e = e;
callback.call(this)
}
}
}
只针对数组和对象
浅拷贝:两者之间可以相互影响,用的一个内存空间;
例:var a = [1,2,3]
var b = a
b[0] = 100 输出b=[100,2,3]
输出a=[100,2,3]
深拷贝:两者互不干扰,各用各的内存空间(方法1 对a遍历,将元素取出来依次赋值给b)
例:方法2 var a = [1,2,3]
var b = JSON.parse(JSON.stringify(a))
b[0] = 100 输出b=[100,2,3]
输出a=[1,2,3]
Array.from() 方法对一个类似数组或可迭代对象创建一个新的,浅拷贝的数组实例。 返回值 一个新的数组实例。
Array.from(arrayLike[, mapFn[, thisArg]])
arrayLike 想要转换成数组的伪数组对象或可迭代对象。
mapFn 可选 如果指定了该参数,新数组中的每个元素会执行该回调函数。
thisArg 可选 可选参数,执行回调函数 mapFn 时 this 对象。
2022.6.30
JavaScript 支持不同类型的循环:
for - 循环代码块一定的次数
for/in - 循环遍历对象的属性
while - 当指定的条件为 true 时循环指定的代码块
do/while - 同样当指定的条件为 true 时循环指定的代码块
注意: 不要使用 for/in 语句来循环数组的索引,你可以使用 for 语句替代。
每当readyState发生变化是都会触发onreadystatechange函数,总共会触发4次
JSON.parse一般用于将JSON字符串转化为JSON对象
JSON 是用于存储和传输数据的格式。
语法规则:
数据为 键/值 对。
数据由逗号分隔。
大括号保存对象
方括号保存数组
this.principal[this.index].content = [
...this.principal[this.index].content,
...res.list
];
//扩展运算符(...)是ES6的语法,用于取出参数对象的所有可遍历属性,然后拷贝到当前对象之中。
this.principal[this.index].content = 新对象[
{},{},{},{},旧对象
{},{},{},{},追加对象
];
2022.7.4
history.back() 返回历史记录(后退一步)
分类编辑和首页菜单公用的一个接口,所以要将其数据存储到本地。
存储:
cookie、localstorage和sessionStorage三者都是在开发中用到的临时存储客户端会话信息或者数据的方法。
三者区别:
一、存储的时间有效期不同
1、cookie的有效期是可以设置的,默认的情况下是关闭浏览器后失效
2、sessionStorage的有效期是仅保持在当前页面,关闭当前会话页或者浏览器后就会失效
3、localStorage的有效期是在不进行手动删除的情况下是一直有效的
二、存储的大小不同
1、cookie的存储是4kb左右,存储量较小,一般页面最多存储20条左右信息
2、localStorage和sessionStorage的存储容量是5Mb(官方介绍,可能和浏览器有部分差异性)
三、与服务端的通信
1、cookie会参与到与服务端的通信中,一般会携带在http请求的头部中,例如一些关键密匙验证等。
2、localStorage和sessionStorage是单纯的前端存储,不参与与服务端的通信
四、读写操作的便捷程度
cookie操作起来较为繁琐,并且部分数据不可以读取操作
设置cookie: document.cookie = "key=value;";
localStorage和sessionStorage相似:
存储:localStorage || sessionStorage.setItem("数据名",“数据值”)[数据名和数据值均要求为字符串]
读取:let data = localStorage || sessionStorage.getItem("数据名")
清除:localStorage || sessionStorage.removeItem("数据名")
移除所有:localStorage || sessionStorage.clear()
splice() 方法用于添加或删除数组中的元素。
返回值:如果删除一个元素,则返回一个元素的数组。 如果未删除任何元素,则返回空数组。
splice(“要删除的元素下标”,“删除几个”)
insertAdjacentHTML() 将指定的文本解析为HTML或XML,并将结果节点插入到DOM树中的指定位置。它不会重新解析它正在使用的元素,因此它不会破坏元素内的现有元素
语法:element.insertAdjacentHTML(position,text)
position是相对于元素的位置,并且必须是以下字符串之一:
beforebegin: 元素自身的前面。
afterend: 元素自身的后面。
beforebegin和afterend位置,仅在节点在树中且节点具有一个parent元素(父元素)时工作.
afterbegin: 插入元素内部的第一个子节点之前。
beforeend: 插入元素内部的最后一个子节点之后。
text是要被解析为HTML或XML,并插入到DOM树中的字符串。
var / let / const
var 声明的变量属于函数作用域,let 和 const 声明的变量属于块级作用域;
var 存在变量提升现象,而 let 和 const 没有此类现象;
var 变量可以重复声明,而在同一个块级作用域,let 变量不能重新声明,const 变量不能修改。

View File

@@ -0,0 +1,33 @@
页面写完再写功能
完整地址加信息: config.checkerurl请求基地址 + 请求短地址 + 请求参数
apilist:保存请求短地址(即 接口 ),方便更改
sever:页面 <————> sever <————> ajax
对接口返回的数据做统一处理,然后返回给页面“一对多!”
sever____config:页面调sever里面的方法,sever从config里面拿到url地址,然后去ajax里调接口,并接收返回值,retur给页面。
类里面的方法根据页面来定,相关接口放相关类里面
状态码:ajax 1~4 ; http ; 接口状态码(后端决定:状态+中文提示信息)
所有接口都要走状态码判断,处理方式不一样的都要写,一样的写一个就可以了
throw(打断浏览器代码运行) new error
config作用:存放各个阶段的基地址/接口
sever作用:page 请求中间层,sever去调ajax封装,ajax需要请求参数(短地址:sever自动读取config得到+参数:page给的) 接收数据统一处理后返回给page
ajax作用:状态码监听 状态码判断 返回数据
css定义全局变量 .root{--变量:值} 一般有颜色和字体大小(字体改rem)
调用 color:var(--变量)
rem.js放在util里面

View File

@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- 请求示例:(http://127.0.0.1:3000/api <——————请求基地址) /index/class?type=1&page=1 -->
<ul>
</ul>
<button class="more">下一页</button>
</body>
<script src="./js/ajax.js"></script>
<script src="./js/utils.js"></script>
<script src="./js/index.js"></script>
</html>

View File

@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>详情页</title>
</head>
<body>
<!-- 请求示例:(http://127.0.0.1:3000/api <——————请求基地址) /index/class?type=1&page=1 -->
<div class="main">
<img src="" alt="">
<p class="posttime"></p>
<p class="title"></p>
</div>
</body>
<script src="./js/ajax.js"></script>
<script src="./js/utils.js"></script>
<script src="./js/information.js"></script>
</html>

View File

@@ -0,0 +1,51 @@
class Ajax {
constructor() {
this.ajax = new XMLHttpRequest();
}
/**
*
* @param {*} params
* {
* url: '',
* data: {
* id: 1,
* page: 2
* },
* header: {
* 'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
* }
* }
*/
get(params) {
return new Promise((success, error) => {
var str = ""
for (const key in params.data) {
str += `&${key}=${params.data[key]}`
}
str = str.replace("&", "?")
this.ajax.open("GET", `${params.url}${str}`)
this.ajax.send()
this.readystatechange(success, error)
})
}
post() { }
readystatechange(success, error) {
this.ajax.onreadystatechange = () => {
if (this.ajax.readyState == 4) {
if (this.ajax.status == 200) {
var data = JSON.parse(this.ajax.responseText)
// console.log(data);
success(data)
} else {
error(this.ajax)
}
}
}
}
}
var ajax = new Ajax();

View File

@@ -0,0 +1,39 @@
class Index {
constructor() {
this.page = 1
this.getClassList()
this.bindEvent()
}
bindEvent() {
click(".more", (e) => {
this.page += 1
this.getClassList()
// console.log("下一页");
})
}
async getClassList() {
var res = await ajax.get({
url: 'http://127.0.0.1:3000/api/index/class',
data: {
type: 1,
page: this.page
},
});
var data = res.result.items;
data.forEach(v => {
$("ul").innerHTML += `
<li>
<a href="./information.html?url=${v.path}">
<img src="${v.img}" alt="">
<p>${v.title}</p>
</a>
</li>
`
})
}
}
new Index();

View File

@@ -0,0 +1,27 @@
class information {
constructor (){
this.getInformation ()
}
async getInformation (){
var res = await ajax.get({
url: 'http://127.0.0.1:3000/api/index/info',
data: {
url: query("url")
},
});
$(".main img").src = res.result.backImg
$(".main img").src = res.result.backImg
$(".main img").src = res.result.backImg
}
}
new information()

View File

@@ -0,0 +1,37 @@
class Util {
inject() {
Element.prototype.remove = function (removeClassName) {
this.classList.remove(removeClassName);
}
Element.prototype.add = function (addClassName) {
this.classList.add(addClassName);
}
}
click(className,callback) {
$(className).onclick = () => {
callback()
}
}
//地址栏获取多个参数
query(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) return unescape(r[2]); return null;
}
$(className) {
return document.querySelector(className)
}
_(className) {
return document.querySelectorAll(className)
}
}
var { $, _, click, inject, query} = new Util()
inject()