d
This commit is contained in:
@@ -1,163 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<title>Document</title>
|
|
||||||
<script src="./lazyload.min.js"></script>
|
|
||||||
<style>
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
list-style: none;
|
|
||||||
font-size: 0;
|
|
||||||
line-height: 0;
|
|
||||||
}
|
|
||||||
ul {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
}
|
|
||||||
ul li {
|
|
||||||
width: 20%;
|
|
||||||
background: #000;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
ul li .lazy {
|
|
||||||
display: block;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<ul></ul>
|
|
||||||
</body>
|
|
||||||
<script>
|
|
||||||
let page = "";
|
|
||||||
// 获取当前页面的滚动高度
|
|
||||||
let currentTop = document.documentElement.scrollTop,
|
|
||||||
lload = null,
|
|
||||||
scrollLock = false,
|
|
||||||
handlerId = null,
|
|
||||||
ul = document.querySelector("ul");
|
|
||||||
|
|
||||||
let getHttpData = async () => {
|
|
||||||
let res = await fetch(`http://127.0.0.1:3000?page=${page}`);
|
|
||||||
let data = await res.json();
|
|
||||||
scrollLock = false;
|
|
||||||
render(data);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 渲染页面
|
|
||||||
let render = (data) => {
|
|
||||||
let { feeds, pcursor } = data;
|
|
||||||
console.log(feeds, pcursor);
|
|
||||||
page = pcursor;
|
|
||||||
|
|
||||||
let index = 0;
|
|
||||||
|
|
||||||
function add() {
|
|
||||||
const li = document.createElement("li");
|
|
||||||
const video = document.createElement("video");
|
|
||||||
video.className = "lazy";
|
|
||||||
video.preload = "metadata";
|
|
||||||
|
|
||||||
video.poster = feeds[index].photo.coverUrl;
|
|
||||||
video.dataset.src = feeds[index].photo.photoUrl;
|
|
||||||
|
|
||||||
video.muted = true;
|
|
||||||
video.autoplay = true;
|
|
||||||
|
|
||||||
li.appendChild(video);
|
|
||||||
ul.appendChild(li);
|
|
||||||
|
|
||||||
index += 1; //修改图像的位置
|
|
||||||
|
|
||||||
if (index < feeds.length) {
|
|
||||||
//在动画没有结束前,递归渲染
|
|
||||||
requestAnimationFrame(add);
|
|
||||||
} else {
|
|
||||||
initLazyLoad();
|
|
||||||
if (currentTop == 0) {
|
|
||||||
autoLoad();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
requestAnimationFrame(add);
|
|
||||||
};
|
|
||||||
|
|
||||||
let initLazyLoad = () => {
|
|
||||||
lload = new LazyLoad({
|
|
||||||
// use_native: true,
|
|
||||||
threshold: 0,
|
|
||||||
elements_selector: ".lazy",
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
let autoLoad = () => {
|
|
||||||
var setScroll = () => {
|
|
||||||
scroll(0, (currentTop += 2));
|
|
||||||
handlerId = requestAnimationFrame(setScroll);
|
|
||||||
};
|
|
||||||
|
|
||||||
handlerId = requestAnimationFrame(setScroll);
|
|
||||||
|
|
||||||
// // 设置一个计时器,每隔200ms执行一次滚动操作
|
|
||||||
// var time = setInterval(() => {
|
|
||||||
// // 使用 window.scroll 方法滚动页面,currentTop 增加 2 实现向下滚动
|
|
||||||
// window.scroll(0, (currentTop += 1));
|
|
||||||
// }, 10);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 当用户点击页面时,停止自动滚动
|
|
||||||
document.onclick = function () {
|
|
||||||
cancelAnimationFrame(handlerId);
|
|
||||||
handlerId = null
|
|
||||||
};
|
|
||||||
|
|
||||||
document.onkeydown = function (e) {
|
|
||||||
//对整个页面监听
|
|
||||||
var keyNum = window.event ? e.keyCode : e.which; //获取被按下的键值
|
|
||||||
//判断如果用户按下了回车键(keycody=13)
|
|
||||||
if (keyNum == 13 && handlerId == null) {
|
|
||||||
autoLoad();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
window.onscroll = function () {
|
|
||||||
//文档内容实际高度(包括超出视窗的溢出部分)
|
|
||||||
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 + scrollTop >= scrollHeight - 150) {
|
|
||||||
if (scrollLock == false) {
|
|
||||||
console.log("满足");
|
|
||||||
scrollLock = true;
|
|
||||||
getHttpData();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
getHttpData();
|
|
||||||
</script>
|
|
||||||
</html>
|
|
||||||
138
ksAll/test.js
138
ksAll/test.js
@@ -1,138 +0,0 @@
|
|||||||
const { GraphQLClient, gql } = require("graphql-request");
|
|
||||||
|
|
||||||
let endpoint = "https://www.kuaishou.com/graphql"
|
|
||||||
|
|
||||||
|
|
||||||
const client = new GraphQLClient(endpoint,{
|
|
||||||
headers: {
|
|
||||||
Cookie: `kpf=PC_WEB; clientid=3; did=web_fca770657d0a24abb53ddc92bb42e612; userId=58344290; kuaishou.server.web_st=ChZrdWFpc2hvdS5zZXJ2ZXIud2ViLnN0EqAB1fPdEwVz-66onvsCh3_P63LjDKblDxAADr2K_kXSZrxEVrX_oU2KKUvZl5YqwPjiOUq-a9m0TlOEs10dBkNF5QpOYQ_s3fbtjyCLi1qrDML64T3Nv3pFwAl1GFULe4arg_hUh6AATsNaXUVr_BteoLpk1WW804aC1U_F1oUPwxulQzqXvUIXngHXO6YPd1dAHtgR77dRIXaK9UswU846xhoS7YoRGiN2PM_7zCD1Dj9m5oYoIiAxx8D3DhwHW8EIVCxWj6oplmurEtbP8DIF7aORbq6y1igFMAE; kuaishou.server.web_ph=bd89383a1964446aa9fb3a806f64776467fc; kpn=KUAISHOU_VISION`,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
const document = gql`
|
|
||||||
fragment photoContent on PhotoEntity {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
duration
|
|
||||||
caption
|
|
||||||
originCaption
|
|
||||||
likeCount
|
|
||||||
viewCount
|
|
||||||
commentCount
|
|
||||||
realLikeCount
|
|
||||||
coverUrl
|
|
||||||
photoUrl
|
|
||||||
photoH265Url
|
|
||||||
manifest
|
|
||||||
manifestH265
|
|
||||||
videoResource
|
|
||||||
coverUrls {
|
|
||||||
url
|
|
||||||
__typename
|
|
||||||
}
|
|
||||||
timestamp
|
|
||||||
expTag
|
|
||||||
animatedCoverUrl
|
|
||||||
distance
|
|
||||||
videoRatio
|
|
||||||
liked
|
|
||||||
stereoType
|
|
||||||
profileUserTopPhoto
|
|
||||||
musicBlocked
|
|
||||||
}
|
|
||||||
fragment recoPhotoFragment on recoPhotoEntity {
|
|
||||||
__typename
|
|
||||||
id
|
|
||||||
duration
|
|
||||||
caption
|
|
||||||
originCaption
|
|
||||||
likeCount
|
|
||||||
viewCount
|
|
||||||
commentCount
|
|
||||||
realLikeCount
|
|
||||||
coverUrl
|
|
||||||
photoUrl
|
|
||||||
photoH265Url
|
|
||||||
manifest
|
|
||||||
manifestH265
|
|
||||||
videoResource
|
|
||||||
coverUrls {
|
|
||||||
url
|
|
||||||
__typename
|
|
||||||
}
|
|
||||||
timestamp
|
|
||||||
expTag
|
|
||||||
animatedCoverUrl
|
|
||||||
distance
|
|
||||||
videoRatio
|
|
||||||
liked
|
|
||||||
stereoType
|
|
||||||
profileUserTopPhoto
|
|
||||||
musicBlocked
|
|
||||||
}
|
|
||||||
fragment feedContent on Feed {
|
|
||||||
type
|
|
||||||
author {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
headerUrl
|
|
||||||
following
|
|
||||||
headerUrls {
|
|
||||||
url
|
|
||||||
__typename
|
|
||||||
}
|
|
||||||
__typename
|
|
||||||
}
|
|
||||||
photo {
|
|
||||||
...photoContent
|
|
||||||
...recoPhotoFragment
|
|
||||||
__typename
|
|
||||||
}
|
|
||||||
canAddComment
|
|
||||||
llsid
|
|
||||||
status
|
|
||||||
currentPcursor
|
|
||||||
tags {
|
|
||||||
type
|
|
||||||
name
|
|
||||||
__typename
|
|
||||||
}
|
|
||||||
__typename
|
|
||||||
}
|
|
||||||
query visionProfileLikePhotoList(
|
|
||||||
$pcursor: String
|
|
||||||
$page: String
|
|
||||||
$webPageArea: String
|
|
||||||
) {
|
|
||||||
visionProfileLikePhotoList(
|
|
||||||
pcursor: $pcursor
|
|
||||||
page: $page
|
|
||||||
webPageArea: $webPageArea
|
|
||||||
) {
|
|
||||||
result
|
|
||||||
llsid
|
|
||||||
webPageArea
|
|
||||||
feeds {
|
|
||||||
...feedContent
|
|
||||||
__typename
|
|
||||||
}
|
|
||||||
hostName
|
|
||||||
pcursor
|
|
||||||
__typename
|
|
||||||
}
|
|
||||||
}`
|
|
||||||
|
|
||||||
const variables = {
|
|
||||||
page: "profile",
|
|
||||||
pcursor: ""
|
|
||||||
}
|
|
||||||
|
|
||||||
client.request(document,variables)
|
|
||||||
.then(res => {
|
|
||||||
console.log("请求的数据为:");
|
|
||||||
console.log(res);
|
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.log("请求的错误为:");
|
|
||||||
console.log(error);
|
|
||||||
})
|
|
||||||
1616
newKs/package-lock.json
generated
Normal file
1616
newKs/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
23
newKs/package.json
Normal file
23
newKs/package.json
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "newks",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "tsx watch src/app.ts"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"type": "commonjs",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "^25.9.1",
|
||||||
|
"axios": "^1.16.1",
|
||||||
|
"express": "^5.2.1",
|
||||||
|
"tsx": "^4.22.3",
|
||||||
|
"typescript": "^6.0.3"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/express": "^5.0.6"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
newKs/rest.http
Normal file
6
newKs/rest.http
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
POST http://127.0.0.1:3030 HTTP/1.1
|
||||||
|
content-type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"pcursor": ""
|
||||||
|
}
|
||||||
51
newKs/src/app.ts
Normal file
51
newKs/src/app.ts
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
import express from "express";
|
||||||
|
import axios from "./utils/axios";
|
||||||
|
import config from "./config";
|
||||||
|
|
||||||
|
const app = express()
|
||||||
|
|
||||||
|
|
||||||
|
//解决跨域
|
||||||
|
app.use((req, res, next) => {
|
||||||
|
// 设置是否运行客户端设置 withCredentials
|
||||||
|
// 即在不同域名下发出的请求也可以携带 cookie
|
||||||
|
res.header("Access-Control-Allow-Credentials", "true")
|
||||||
|
// 第二个参数表示允许跨域的域名,* 代表所有域名
|
||||||
|
res.header('Access-Control-Allow-Origin', '*')//配置80端口跨域
|
||||||
|
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, OPTIONS') // 允许的 http 请求的方法
|
||||||
|
// 允许前台获得的除 Cache-Control、Content-Language、Content-Type、Expires、Last-Modified、Pragma 这几张基本响应头之外的响应头
|
||||||
|
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Content-Length, X-Requested-With')
|
||||||
|
if (req.method == 'OPTIONS') {
|
||||||
|
res.sendStatus(200)
|
||||||
|
} else {
|
||||||
|
next()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* http://127.0.0.1:3030?pcursor=""
|
||||||
|
*/
|
||||||
|
app.get('/', async (req, res) => {
|
||||||
|
let { pcursor } = req.query
|
||||||
|
let data = {
|
||||||
|
page: "profile",
|
||||||
|
pcursor: pcursor || ""
|
||||||
|
};
|
||||||
|
|
||||||
|
console.log("请求参数:", data);
|
||||||
|
|
||||||
|
let result = await axios.post({
|
||||||
|
url: config.urlList.liked,
|
||||||
|
data
|
||||||
|
})
|
||||||
|
|
||||||
|
console.log("请求响应:", result);
|
||||||
|
|
||||||
|
|
||||||
|
res.json(result)
|
||||||
|
})
|
||||||
|
|
||||||
|
app.listen(3030, () => {
|
||||||
|
console.log(`backend is run: http://127.0.0.1:3030`)
|
||||||
|
})
|
||||||
7
newKs/src/config/index.ts
Normal file
7
newKs/src/config/index.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export default {
|
||||||
|
url: "https://www.kuaishou.com/rest/v",
|
||||||
|
urlList: {
|
||||||
|
// 点赞
|
||||||
|
liked: "/feed/liked"
|
||||||
|
}
|
||||||
|
}
|
||||||
229
newKs/src/public/index.html
Normal file
229
newKs/src/public/index.html
Normal file
@@ -0,0 +1,229 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Document</title>
|
||||||
|
<script src="./lazyload.min.js"></script>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
font-size: 0;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
ul {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
ul li {
|
||||||
|
width: 20%;
|
||||||
|
background: #000;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
ul li .lazy {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
object-fit: cover;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ul></ul>
|
||||||
|
</body>
|
||||||
|
<script>
|
||||||
|
// 分页游标
|
||||||
|
let page = "";
|
||||||
|
|
||||||
|
// 滚动相关状态
|
||||||
|
const defaultSpeed = 2; // 默认速度(最小值)
|
||||||
|
let scrollSpeed = defaultSpeed; // 当前滚动速度
|
||||||
|
|
||||||
|
let currentTop = document.documentElement.scrollTop; // 当前滚动高度
|
||||||
|
let lload = null; // 懒加载实例
|
||||||
|
let scrollLock = false; // 滚动加载锁(防止重复请求)
|
||||||
|
let handlerId = null; // 自动滚动帧ID
|
||||||
|
let ul = document.querySelector("ul"); // 视频列表容器
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取接口数据
|
||||||
|
*/
|
||||||
|
let getHttpData = async () => {
|
||||||
|
try {
|
||||||
|
let res = await fetch(`http://127.0.0.1:3030?pcursor=${page}`);
|
||||||
|
let data = await res.json();
|
||||||
|
scrollLock = false;
|
||||||
|
render(data);
|
||||||
|
} catch (err) {
|
||||||
|
scrollLock = false;
|
||||||
|
console.error("数据加载失败", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 渲染视频列表
|
||||||
|
*/
|
||||||
|
let render = (data) => {
|
||||||
|
let { feeds, pcursor } = data;
|
||||||
|
page = pcursor;
|
||||||
|
|
||||||
|
let index = 0;
|
||||||
|
|
||||||
|
function add() {
|
||||||
|
const li = document.createElement("li");
|
||||||
|
const video = document.createElement("video");
|
||||||
|
|
||||||
|
video.className = "lazy";
|
||||||
|
video.preload = "metadata";
|
||||||
|
video.muted = true;
|
||||||
|
video.loop = true;
|
||||||
|
video.autoplay = false;
|
||||||
|
|
||||||
|
// 封面 + 视频地址
|
||||||
|
const posterUrl = feeds[index].photo.animatedCoverUrl || feeds[index].photo.coverUrl;
|
||||||
|
video.poster = posterUrl;
|
||||||
|
video.dataset.src = feeds[index].photo.photoUrls[0].url;
|
||||||
|
|
||||||
|
li.appendChild(video);
|
||||||
|
ul.appendChild(li);
|
||||||
|
|
||||||
|
// 鼠标移入 → 播放
|
||||||
|
video.onmouseenter = () => {
|
||||||
|
if (video.readyState >= 2) video.play();
|
||||||
|
};
|
||||||
|
|
||||||
|
// 鼠标移出 → 暂停并显示封面
|
||||||
|
video.onmouseleave = () => {
|
||||||
|
video.pause();
|
||||||
|
video.src = "";
|
||||||
|
video.src = video.dataset.src;
|
||||||
|
};
|
||||||
|
|
||||||
|
index++;
|
||||||
|
if (index < feeds.length) {
|
||||||
|
requestAnimationFrame(add);
|
||||||
|
} else {
|
||||||
|
initLazyLoad();
|
||||||
|
// 页面加载完成 → 自动开始滚动(修复这里!)
|
||||||
|
if (!handlerId) {
|
||||||
|
startScroll();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
requestAnimationFrame(add);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 初始化懒加载
|
||||||
|
*/
|
||||||
|
let initLazyLoad = () => {
|
||||||
|
if (lload) lload.destroy();
|
||||||
|
lload = new LazyLoad({
|
||||||
|
threshold: 0,
|
||||||
|
elements_selector: ".lazy",
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始自动滚动
|
||||||
|
*/
|
||||||
|
let startScroll = () => {
|
||||||
|
const setScroll = () => {
|
||||||
|
// 核心修复:每次都实时获取当前滚动位置,而不是用固定值
|
||||||
|
let currentTop = window.scrollY || document.documentElement.scrollTop;
|
||||||
|
|
||||||
|
currentTop += scrollSpeed;
|
||||||
|
window.scroll(0, currentTop);
|
||||||
|
handlerId = requestAnimationFrame(setScroll);
|
||||||
|
};
|
||||||
|
handlerId = requestAnimationFrame(setScroll);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止自动滚动
|
||||||
|
*/
|
||||||
|
let stopScroll = () => {
|
||||||
|
cancelAnimationFrame(handlerId);
|
||||||
|
handlerId = null;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统一开关函数(点击 + 空格共用)
|
||||||
|
*/
|
||||||
|
let toggleScroll = () => {
|
||||||
|
if (handlerId) {
|
||||||
|
stopScroll();
|
||||||
|
} else {
|
||||||
|
startScroll();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ====================== 核心修改 ======================
|
||||||
|
/**
|
||||||
|
* 点击页面 → 开关滚动(开始/暂停)
|
||||||
|
*/
|
||||||
|
document.onclick = toggleScroll;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 空格键 → 开关滚动(开始/暂停)
|
||||||
|
*/
|
||||||
|
document.onkeydown = (e) => {
|
||||||
|
console.log("e: ", e);
|
||||||
|
|
||||||
|
if (e.keyCode === 32) {
|
||||||
|
e.preventDefault();
|
||||||
|
toggleScroll();
|
||||||
|
}
|
||||||
|
|
||||||
|
// R键:重置速度
|
||||||
|
if (e.keyCode === 82) {
|
||||||
|
e.preventDefault();
|
||||||
|
scrollSpeed = defaultSpeed;
|
||||||
|
console.log("重置速度", scrollSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 上键:速度 +2
|
||||||
|
if (e.keyCode === 40) {
|
||||||
|
e.preventDefault();
|
||||||
|
scrollSpeed += 2;
|
||||||
|
console.log("当前速度:", scrollSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下键:速度 -2(最低不小于默认 2)
|
||||||
|
if (e.keyCode === 38) {
|
||||||
|
e.preventDefault();
|
||||||
|
if (scrollSpeed > defaultSpeed) {
|
||||||
|
scrollSpeed -= 2;
|
||||||
|
console.log("当前速度:", scrollSpeed);
|
||||||
|
} else {
|
||||||
|
console.log("已达到最低速度:", scrollSpeed);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
// ======================================================
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 滚动到底部加载更多
|
||||||
|
*/
|
||||||
|
window.onscroll = () => {
|
||||||
|
if (scrollLock) return;
|
||||||
|
|
||||||
|
const scrollHeight = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
|
||||||
|
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
|
||||||
|
const clientHeight = window.innerHeight || document.documentElement.clientHeight;
|
||||||
|
|
||||||
|
if (clientHeight + scrollTop >= scrollHeight - 150) {
|
||||||
|
scrollLock = true;
|
||||||
|
getHttpData();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 初始化加载
|
||||||
|
getHttpData();
|
||||||
|
</script>
|
||||||
|
</html>
|
||||||
1
newKs/src/public/lazyload.min.js
vendored
Normal file
1
newKs/src/public/lazyload.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
59
newKs/src/utils/axios.ts
Normal file
59
newKs/src/utils/axios.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import axios, { AxiosInstance, AxiosError, AxiosRequestConfig } from "axios";
|
||||||
|
import config from "../config";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* axios的封装
|
||||||
|
*/
|
||||||
|
export class AxioDao {
|
||||||
|
instance: AxiosInstance;
|
||||||
|
|
||||||
|
public constructor() {
|
||||||
|
this.instance = axios.create({
|
||||||
|
baseURL: config.url,
|
||||||
|
timeout: 10000,
|
||||||
|
headers: {
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"cookie": "kpf=PC_WEB; clientid=3; did=web_7aa35438f931e14fe470f001c9f567ec; kwpsecproductname=kuaishou-vision; userId=58344290; kuaishou.server.webday7_st=ChprdWFpc2hvdS5zZXJ2ZXIud2ViZGF5Ny5zdBKwAQHxyR5bWVNh7KrpNyCMIujOnqy383HvNuUVP0dWkTKvgVdJgpk3_gzZcVaGGxY2SMKV_-t34ND4_nM6tKtBhs7PXiwSWdT-fbK8EVQhZkyTrfRwVNxnKxGYvyaN4bcX8ZSyetkuuwMW8wVJJDhFjlVOK37qRRdJz_1MtpVIyFyy-gZ0iG0xwQJXnAZIKXakmH72qc7Ta-r0EWdwXdapM1FAB7SYUEsb5JBCoq60QA1VGhJd10MMXKUTryN4EXEM1nBv898iIGhj1Z7oQnnDhZLRTJasZqh85Pt6iycf0azzgPQRW9NjKAUwAQ; kuaishou.server.webday7_ph=8afd3b47e4f2ae941c5f0a2f6683f7176d0a; kwpsecproductname=kuaishou-vision; ktrace-context=1|MS44Nzg0NzI0NTc4Nzk2ODY5LjU4Mjc1MjU2LjE3ODAxNTg4NDQ5MjMuMjc5ODA3MjU=|MS44Nzg0NzI0NTc4Nzk2ODY5LjI1Njc3MzQ5LjE3ODAxNTg4NDQ5MjMuMjc5ODA3MjY=|0|webservice-user-growth-node|webservice|true|src-Js; kpn=KUAISHOU_VISION; kwssectoken=Sk26dfFAjJDb+qp06cbMoxr2vOGxFQS48Demb7hzLQDAF/SYzVNnuyba6Bjd7KkXYsb5nBCaYcOS4gbqp1Ic2w==; kwscode=a715a587d1b6832f2760590584b05c42663b5eae5c68614a6b055f2e0f6069b7; kwfv1=PnGU+9+Y8008S+nH0U+0mjPf8fP08f+98f+nLlwnrIP9+Sw/ZFGfzY+eGlGf+f+e4SGfbYP0QfGnLFwBLU80mYGApj+f+08eHF+AQYG/chP/cI8eSD+/+jPfHFPAZ9+04YP/Q0G/ZUPBpj+BLhwerIwePU+fHMPBLIPArl+fQfP9G98fGE8fLlwBzYwn+SGAWI+AP7we4jPArI8n8jP04j+Z=="
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.ResponseInterceptor();
|
||||||
|
this.RequestInterceptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public async post(params: AxiosRequestConfig): Promise<any> {
|
||||||
|
return await this.instance.post(<string>params.url, params.data, {
|
||||||
|
headers: Object.assign({}, params.headers)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应拦截器
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
public async ResponseInterceptor(): Promise<any> {
|
||||||
|
this.instance.interceptors.response.use(
|
||||||
|
(response: any) => {
|
||||||
|
return response.data;
|
||||||
|
},
|
||||||
|
(error: AxiosError) => {
|
||||||
|
console.log(`❌ 请求错误 ❌: ${error}`);
|
||||||
|
return Promise.reject(error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加请求拦截器
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
public async RequestInterceptor(): Promise<any> {
|
||||||
|
this.instance.interceptors.request.use((config: any) => {
|
||||||
|
return config
|
||||||
|
}, function (error: AxiosError) {
|
||||||
|
return Promise.reject(error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new AxioDao();
|
||||||
22
newKs/tsconfig.json
Normal file
22
newKs/tsconfig.json
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
|
||||||
|
// Treat files as modules even if it doesn't use import/export
|
||||||
|
"moduleDetection": "force",
|
||||||
|
|
||||||
|
// Ignore module structure
|
||||||
|
"module": "Preserve",
|
||||||
|
|
||||||
|
// Allow JSON modules to be imported
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
|
||||||
|
// Allow JS files to be imported from TS and vice versa
|
||||||
|
"allowJs": true,
|
||||||
|
|
||||||
|
// Use correct ESM import behavior
|
||||||
|
"esModuleInterop": true,
|
||||||
|
|
||||||
|
// Disallow features that require cross-file awareness
|
||||||
|
"isolatedModules": true,
|
||||||
|
},
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user