<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>文字光标跟随</title>
<style>
.text-container {
position: relative;
margin: 200px;
padding: 30px;
min-height: 300px;
border: 1px solid #ccc;
--color: #333;
}
.text {
position: relative;
color: var(--color);
}
.cursor {
position: absolute;
left: 4px;
top: 4px;
display: block;
width: 16px;
height: 16px;
background-color: var(--color);
border-radius: 50%;
animation: blink 0.5s steps(1, start) infinite;
}
@keyframes blink {
50% {
opacity: 0;
}
100% {
opacity: 1;
}
}
</style>
</head>
<body>
<div class="text-container">
<div class="text"></div>
</div>
</body>
<script>
const textContainer = document.querySelector(".text-container");
const textElement = document.querySelector(".text");
const content = `
Lorem ipsum dolor sit amet consectetur, adipisicing elit. Iusto totam sed neque amet. Dolorum molestiae delectus vero, eius fugiat tempore repudiandae temporibus impedit dolores, cum facere cumque illum debitis repellat!
Ex, illum! Totam saepe labore dolores nam, hic magni architecto nemo inventore praesentium quam expedita deserunt vel quibusdam, culpa vero sequi repudiandae eveniet. Minus consequuntur aperiam repudiandae esse repellendus. Deleniti!
Earum facilis quas eveniet id, et numquam voluptatum rerum similique explicabo sint, ea omnis doloribus! Dicta assumenda eos quo quis veniam iusto molestias fugiat labore culpa? Quasi possimus praesentium labore?
Rerum temporibus corporis quisquam nulla, alias perspiciatis velit. Rem, aliquid. Corporis repudiandae unde ut nostrum eos blanditiis labore sapiente culpa distinctio iusto, quam, sunt excepturi quod provident ea! Voluptas, corrupti.
Rem, nostrum error. Dolorum voluptatibus corporis eos doloremque repellendus fuga, commodi a nobis quam asperiores adipisci quae consequatur perferendis pariatur distinctio temporibus. Delectus incidunt nesciunt minus nemo impedit, hic vitae?
`;
autoAppend(content);
async function autoAppend(content) {
// 创建光标元素
const cursor = document.createElement("div");
cursor.className = "cursor";
textContainer.appendChild(cursor);
function delay(time) {
return new Promise((resolve) => setTimeout(resolve, time));
}
function transfer(text) {
const paragraphs = text
.split("\n")
.filter(Boolean)
.map((word) => `<p>${word}</p>`);
return paragraphs.join("");
}
for (let i = 0; i < content.length; i++) {
let text = content.slice(0, i);
let result = transfer(text);
textElement.innerHTML = result;
updateCursor(cursor);
await delay(30);
}
cursor.remove();
}
// 获取最后一个文本节点
function getLastTextNode(node) {
if (node.nodeType === Node.TEXT_NODE) {
return node;
}
for (let i = node.childNodes.length - 1; i >= 0; i--) {
let result = getLastTextNode(node.childNodes[i]);
if (result) {
return result;
}
}
return null;
}
function updateCursor(cursor) {
// 获取最后一个文本元素
let lastTextNode = getLastTextNode(textElement);
// 创建一个临时的文本节点,以便选中最后一个文字
let tempText = document.createTextNode("|");
if (lastTextNode) {
lastTextNode.parentNode.appendChild(tempText);
} else {
textElement.appendChild(tempText);
}
// 选中最后一个文字
const range = document.createRange();
range.setStart(tempText, 0);
range.setEnd(tempText, 0);
// 文字是相对于视口的,所以要减去容器的左上角
const rect = range.getBoundingClientRect();
const textRect = textContainer.getBoundingClientRect();
const x = rect.left - textRect.left;
const y = rect.top - textRect.top;
cursor.style.transform = `translate(${x}px,${y}px)`;
tempText.remove();
}
</script>
</html>
类ChatGPT文字光标跟随
最新推荐文章于 2026-01-05 14:50:19 发布
GPT-oss:20b
图文对话
Gpt-oss
GPT OSS 是OpenAI 推出的重量级开放模型,面向强推理、智能体任务以及多样化开发场景
您可能感兴趣的与本文相关的镜像
GPT-oss:20b
图文对话
Gpt-oss
GPT OSS 是OpenAI 推出的重量级开放模型,面向强推理、智能体任务以及多样化开发场景
1465

被折叠的 条评论
为什么被折叠?



