大量修改

This commit is contained in:
编码猿
2024-11-30 22:40:02 +08:00
commit 6b0e7cd1ed
43 changed files with 1886 additions and 0 deletions

42
js/config/index.js Normal file
View File

@@ -0,0 +1,42 @@
// var let
// 定义的新方式 let
let config = {
stage: "dev", // dev test prod
// http://127.0.0.1:8090/app/user/UserInfo
// 基地址 http://127.0.0.1:8090/app
// 短地址 /user/UserInfo
// 基地址都被 ajax封装调用
devUrl: 'https://pc.buyusdt.xyz/v1/api',
testUrl: 'http://192.168.31.101:3030/test/api',
prodUrl: 'http://abc.com/v1/api',
// 帮助ajax判断应该用哪一个基地址
checkUrl: function () {
switch (this.stage) {
case "dev":
return this.devUrl
break;
case "test":
return this.testUrl
break;
case "prod":
return this.prodUrl
break;
}
},
// 短地址 都被 serve 调用
urlList: {
homeHot: '/home/hot',
homeList: '/home/list',
homeBanner: '/home/banner',
infoList: '/info/list',
tagList: '/tag/list',
tagRecommend: '/tag/recommend',
searchHot: '/search/hot',
searchKey: '/search/key',
}
}

57
js/http/index.js Normal file
View File

@@ -0,0 +1,57 @@
class Ajax {
xhr = new XMLHttpRequest()
get(option) {
return new Promise((success, error) => {
var params = ""
for (const key in option.data) {
params += `&${key}=${option.data[key]}`
}
params = params.replace("&", "?")
// option.url == /home/hot?id=1
this.xhr.open("GET", `${config.checkUrl()}${option.url}${params}`)
this.xhr.send()
this.stateChange(success, error)
})
}
post(option) {
return new Promise((success, error) => {
this.xhr.open("POST", option.url)
this.xhr.setRequestHeader("Content-Type", "application/json")
// post 参数在请求体(body)中发送
this.xhr.send(JSON.stringify(option.data))
this.stateChange(success, error)
})
}
stateChange(suc, err) {
this.xhr.onreadystatechange = () => {
if (this.xhr.readyState == 4) {
if (this.xhr.status == 200) {
let res = JSON.parse(this.xhr.response)
switch (res.status) {
case 200:
suc(res.data)
break;
case 404:
alert(res.message)
err(this.xhr)
break;
default:
break;
}
suc()
} else {
err(this.xhr)
}
}
}
}
}

7
js/page/domestic.js Normal file
View File

@@ -0,0 +1,7 @@
class Domestic {
constructor() {
util.footer()
}
}
new Domestic

7
js/page/hot.js Normal file
View File

@@ -0,0 +1,7 @@
class Hot {
constructor() {
util.footer()
}
}
new Hot

80
js/page/index.js Normal file
View File

@@ -0,0 +1,80 @@
class Index {
constructor() {
util.header(
`
<div class="search flex1 flex ais">
<i class="iconfont icon-sousuo-m"></i>
<p>开启精彩搜索..</p>
</div>
`,
"",
""
)
util.footer()
this.getHomeBanner()
this.getTagRecommend()
this.getHomeHotData()
this.getHomeListData()
this.initSwiper()
this.event()
}
async getHomeListData() {
let res = await homeServe.homeList()
item(".default-model ul", res)
}
// 获取热门推荐的写真
async getHomeHotData() {
let res = await homeServe.homeHot()
item(".recommend-model ul", res)
}
// 请求热门分类
async getTagRecommend() {
let res = await tagServe.tagRecommend()
$(".recommend-tag").innerHTML = res.maps(v => {
return `
<li>
<div class="icon">${v.title.substr(0,1)}</div>
<div class="title">${v.title}</div>
</li>
`
})
}
// 请求banner图
async getHomeBanner() {
let res = await homeServe.homeBanner()
$(".swiper-wrapper").innerHTML = res.maps(v => {
return `
<div class="swiper-slide">
<img src="${v.src}" alt="">
</div>
`
})
}
initSwiper() {
var mySwiper = new Swiper('.banner', {
loop: true, // 循环模式选项
// 如果需要分页器
pagination: {
el: '.swiper-pagination',
},
})
}
event() {
$(".search").onclick = () => {
location.href = "./search.html"
}
}
}
new Index

102
js/page/info.js Normal file
View File

@@ -0,0 +1,102 @@
class Info {
title = ""
defaultArr = []
allArr = []
// 收藏的数据,本地有收藏就读取本地之前的收藏数据,没有就给默认值
// likeArr = JSON.parse(localStorage.getItem("like")) || []
likeArr = getItem("like")
constructor() {
this.getInfoListData()
.then(() => {
util.header(
`<div class="title flex1 ellipsis">${this.title}</div>`,
`
<div class="ilist">
<i class="iconfont icon-wujiaoxing"></i>
<i class="iconfont icon-fenxiang"></i>
</div>
`
)
this.event()
})
}
async getInfoListData() {
let { title, src_list, recommend } = await infoServe.infoList({ id: query("id") })
this.title = title
// 手动实现 懒加载
this.allArr = src_list
this.defaultArr = [ this.allArr[0], this.allArr[1] ]
$(".info_img_list .img_list").innerHTML = this.defaultArr.maps(v => `<img src="${v}" alt="">`)
item(".recommend-model ul", recommend)
}
event() {
$(".view_all").onclick = () => {
$(".img_list").style.height = "auto"
$(".view_all").style.display = "none"
$(".info_img_list .img_list").innerHTML = this.allArr.maps(v => `<img src="${v}" alt="">`)
}
// TODO 找一个合适分享
$(".icon-fenxiang").onclick = async () => {
await navShare({
title: this.title,
text: `我这有个好看的,快来看看 ${this.title}`,
url: location.href
})
}
let sc = $(".icon-wujiaoxing")
console.log("this.likeArr: ", this.likeArr);
let isHave = this.likeArr.filter(v => v.id == query("id"))
if (isHave.length != 0) {
sc.classList.add("icon-wujiaoxing1")
}
$(".icon-wujiaoxing").onclick = async () => {
// 已收藏,应该变成未收藏
if (sc.classList.contains("icon-wujiaoxing1")) {
sc.classList.remove("icon-wujiaoxing1")
this.likeArr = this.likeArr.filter(v => v.id != query("id"))
setItem("like", this.likeArr)
// 未收藏,应该变成已收藏
} else {
this.likeArr.push({
id: query("id"),
thumbnail: this.allArr[0],
title: this.title,
time: query("time"),
// TODO 这个浏览量需要后端提供
view: "42"
})
setItem("like", this.likeArr)
sc.classList.add("icon-wujiaoxing1")
}
// await navShare({
// title: this.title,
// text: `我这有个好看的,快来看看 ${this.title}`,
// url: location.href
// })
}
}
}
new Info

7
js/page/me.js Normal file
View File

@@ -0,0 +1,7 @@
class Me {
constructor() {
util.footer()
}
}
new Me

97
js/page/search.js Normal file
View File

@@ -0,0 +1,97 @@
class Search {
page = 1;
totalPage = 0;
keyword = "";
totalArr = [];
constructor() {
util.header(
`<input class="flex1" type="text" placeholder="输入关键字">`,
`<div class="button">搜索</div>`,
`<i class="iconfont icon-fanhui"></i>`
)
this.getSearchHotData()
this.event()
}
async getSearchHotData() {
let { hotKeyword, recommend } = await searchServe.searchHot()
$(".search_list ul").innerHTML = hotKeyword.maps(v => {
return `
<li>
<a>${v}</a>
</li>
`
});
item(".search_recommend", recommend, 2)
$(".search_recommend ul li").forEach(v => {
v.onclick = () => {
// 把你点击的文字放到搜索框里面
$(".header input").value = v.innerText
$(".header .button").onclick()
}
})
}
event() {
let input = $(".header input")
$(".header .button").onclick = async () => {
if (input.value.length != 0) {
this.keyword = input.value
this.totalArr = []
await this.getSearchKeyData()
if (this.totalArr.length != 0) {
util.hidden(".no-search")
item(".have-search ul", this.totalArr)
util.show(".have-search")
this.onscroll()
}
}
}
input.oninput = () => {
if (input.value.length == 0) {
util.show(".no-search")
util.hidden(".have-search")
}
}
}
// 用来发送搜索请求的
async getSearchKeyData() {
let { totalPage, list } = await searchServe.searchKey({
keyword: this.keyword,
page: this.page
})
this.totalPage = totalPage
list.forEach(v => this.totalArr.push(v));
}
// 滚动到底部实现自动加载下一页数据
onscroll() {
window.onscroll = async () => {
var scrollHeight = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
var scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
var clientHeight = window.innerHeight || Math.min(document.documentElement.clientHeight, document.body.clientHeight);
if (clientHeight + Math.ceil(scrollTop) >= scrollHeight) {
this.page += 1
if (this.page <= this.totalPage) {
await this.getSearchKeyData()
item(".have-search ul", this.totalArr)
}
}
}
}
}
new Search

35
js/serve/home.js Normal file
View File

@@ -0,0 +1,35 @@
class HomeServe {
// data 是接口请求的参数,默认为空对象,表示这个接口不需要参数
async homeHot (data = {}) {
let http = new Ajax()
// suc的返回值ajax请求到的后端给我们的数据
return await http.get({
url: config.urlList.homeHot,
// data: data key 和 value 名字一样的时候,可以直接只写一个
data
})
}
async homeBanner (data = {}) {
let http = new Ajax()
// suc的返回值ajax请求到的后端给我们的数据
return await http.get({
url: config.urlList.homeBanner,
// data: data key 和 value 名字一样的时候,可以直接只写一个
data
})
}
async homeList (data = {}) {
let http = new Ajax()
// suc的返回值ajax请求到的后端给我们的数据
return await http.get({
url: config.urlList.homeList,
// data: data key 和 value 名字一样的时候,可以直接只写一个
data
})
}
}
let homeServe = new HomeServe

14
js/serve/info.js Normal file
View File

@@ -0,0 +1,14 @@
class InfoServe {
// data 是接口请求的参数,默认为空对象,表示这个接口不需要参数
async infoList (data = {}) {
let http = new Ajax()
// suc的返回值ajax请求到的后端给我们的数据
return await http.get({
url: config.urlList.infoList,
// data: data key 和 value 名字一样的时候,可以直接只写一个
data
})
}
}
let infoServe = new InfoServe

28
js/serve/search.js Normal file
View File

@@ -0,0 +1,28 @@
class SearchServe {
// data 是接口请求的参数,默认为空对象,表示这个接口不需要参数
async searchHot (data = {}) {
let http = new Ajax()
// suc的返回值ajax请求到的后端给我们的数据
return await http.get({
url: config.urlList.searchHot,
// data: data key 和 value 名字一样的时候,可以直接只写一个
data
})
}
async searchKey (data = {}) {
let http = new Ajax()
// suc的返回值ajax请求到的后端给我们的数据
return await http.get({
url: config.urlList.searchKey,
// data: data key 和 value 名字一样的时候,可以直接只写一个
data
})
}
}
let searchServe = new SearchServe

25
js/serve/tag.js Normal file
View File

@@ -0,0 +1,25 @@
class TagServe {
// data 是接口请求的参数,默认为空对象,表示这个接口不需要参数
async tagList (data = {}) {
let http = new Ajax()
// suc的返回值ajax请求到的后端给我们的数据
return await http.get({
url: config.urlList.tagList,
// data: data key 和 value 名字一样的时候,可以直接只写一个
data
})
}
async tagRecommend (data = {}) {
let http = new Ajax()
// suc的返回值ajax请求到的后端给我们的数据
return await http.get({
url: config.urlList.tagRecommend,
// data: data key 和 value 名字一样的时候,可以直接只写一个
data
})
}
}
let tagServe = new TagServe

161
js/utils/index.js Normal file
View File

@@ -0,0 +1,161 @@
class Utils {
// 类被初始化的时候,构造函数就会自己运行了
constructor() {
this.newMap()
}
newMap() {
Array.prototype.maps = function (callback) {
// var callback = e => `<li>${e}</li>`
var res = []
for (let i = 0; i < this.length; i++) {
var ddd = callback(this[i], i, this)
res.push(ddd)
}
return res.toString().replaceAll(",", "")
}
}
$(className) {
var classNameArr = className.split(" ");
if (classNameArr.length == 1) {
var isAll = document.querySelectorAll(classNameArr[0])
return isAll.length == 1 ? isAll[0] : isAll
} else {
var lastChild = classNameArr[classNameArr.length - 1];
var lastChildFather = classNameArr[classNameArr.length - 2];
var lastChildFatherDOM = document.querySelector(lastChildFather);
var key = "";
lastChild.includes(".")
? (key = "className")
: lastChild.includes("#")
? (key = "id")
: (key = "localName");
var res = Array.from(lastChildFatherDOM.children).filter(
(e) => e[key] == lastChild.replace(".", "")
);
}
return res.length <= 1 ? res[0] : res;
}
footer() {
// ajax 接口返回的底部导航数据
let arr = [
{ icon: 'icon-shouye', title: '首页', href: 'index.html' },
{ icon: 'icon-changchenglogo', title: '分类', href: 'domestic.html' },
{ icon: 'icon-hot', title: '热门', href: 'hot.html' },
{ icon: 'icon-wo', title: '我的', href: 'me.html' },
]
let body = this.$("body")
// TODO innerHTML 会导致事件丢失
body.innerHTML += `
<ul class="footer fixed flex ja ais">
${arr.maps(v => {
return `
<li class="${location.pathname.includes(v.href) ? 'active' : ''}">
<a href="${v.href}">
<i class="iconfont ${v.icon}"></i>
<p>${v.title}</p>
</a>
</li>
`
})
}
</ul>
`
}
item(dom, data, theme = 1) {
$(dom).innerHTML = data.maps(v => {
return `
<li class="${theme == 2 ? 'item-theme-horizontally' : ''}">
<a href="./info.html?id=${v.id}&time=${v.time}">
<img src="${v.thumbnail}" alt="">
<div class="r">
<div class="text ellipsis">${v.title}</div>
<div class="desc flex ais js">
<div class="time">${v.time}</div>
<div class="view flex ais">
<i class="iconfont icon-yanjing"></i>
<span>${v.view}</span>
</div>
</div>
</div>
</a>
</li>
`
})
}
query(name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)");
var r = window.location.search.substr(1).match(reg);
if (r != null) return decodeURIComponent(r[2]); return null;
}
header(content, action, back = `<i class="iconfont icon-fanhui"></i>`) {
this.$("body").insertAdjacentHTML('afterbegin', `
<div class="header fixed flex ais flex1 border-box p15">
${back}
${content}
${action}
</div>
`);
this.$(".icon-fanhui").onclick = () => {
history.back()
}
}
async navShare(title = "", text = "", url = "") {
console.log(navigator.share && navigator.canShare);
if (navigator.share && navigator.canShare) {
await navigator.share({
title, text, url
});
} else {
alert(`当前浏览器版本不支持分享此功能`);
}
}
show(className) {
this.$(className).style.display = "block"
}
hidden(className) {
this.$(className).style.display = "none"
}
setItem(key, value) {
localStorage.setItem(key, JSON.stringify(value))
}
getItem(key) {
let local = localStorage.getItem(key)
return local ? JSON.parse(local) : []
}
}
let u = new Utils
let util = u, { $, item, query, navShare, getItem, setItem } = u
// let util = new Utils
// let $ = (new Utils).$
// util.$
// $
// footer

10
js/utils/rem.js Normal file
View File

@@ -0,0 +1,10 @@
(function (w, d) {
function setSize() {
var screenWidth = d.documentElement.clientWidth;
var currentFontSize = (screenWidth * 100) / 750;
d.documentElement.style.fontSize = currentFontSize + "px";
}
w.addEventListener("resize", setSize);
w.addEventListener("pageShow", setSize);
w.addEventListener("DOMContentLoaded", setSize);
})(window, document);