HTML+CSS+JS实现简单的打字机
js
/*** 动态打字效果函数* (select和element只能选择一个)* @param {Object} options - 配置选项* @param {string} options.select - 选择器,用于定位要显示文本的DOM元素("#id"或".class")* @param {Object} options.element - DOM元素(Element对象)* @param {string[]} options.strings - 要依次显示的字符串数组* @param {boolean} [options.lifeLike=true] - 是否模拟真实打字速度* @param {boolean} [options.loop=true] - 是否循环显示字符串* @param {number} [options.min_speed=200] - 最小打字速度(毫秒)* @param {number} [options.max_speed=500] - 最大打字速度(毫秒)* @param {Function} [options.callback_one_txt=null] - 每个字符打字结束后的回调函数* @param {Function} [options.callback=null] - 打字结束后的回调函数(不循环时有效)* */
function typeit({select=null,element=null, strings, lifeLike = true, loop = false, min_speed = 200, max_speed = 500,callback_one_txt=null,callback=null}) {// 获取要显示文本的DOM元素let text_dom;if (element) {text_dom = element;}else{text_dom = document.querySelector(select);}// 当前要显示的字符串的第几个字符let index = 0;// 文本数组的下标let xiaBiao = 0;// 判断是要实现打字还是删除字效果,初始为真(打字)let huan = true;// 记录已经完成一轮的次数let completedRounds = 0;/*** 获取一个随机速度值* @param {number} min - 最小速度* @param {number} max - 最大速度* @returns {number} - 随机速度值*/function getRandomSpeed(min, max) {return Math.floor(Math.random() * (max - min + 1)) + min;}/*** 执行下一步操作:打字或删除字符*/function nextStep() {if (huan) {// 给.text标签添加字符,用.slice方法text_dom.innerHTML = strings[xiaBiao].slice(0, ++index);// 如果当前字符串的所有字符都已显示,则开始删除字符if (index === strings[xiaBiao].length) {// 如果数组下标超过了最后一个字符串且不循环,则停止定时器if (!loop && xiaBiao >= strings.length-1) {clearInterval(intervalId);text_dom.classList.remove("typeit_text_css");callback && callback();return;}huan = false;}} else {// 给.text标签删除字符,用.slice方法text_dom.innerHTML = strings[xiaBiao].slice(0, index--);// 如果所有字符都已删除,则准备显示下一个字符串if (index < 0) {index = 0;huan = true;xiaBiao++;// 如果数组下标超过最后一个字符串,则重新从第一个字符串开始if (xiaBiao >= strings.length) {xiaBiao = 0;completedRounds++;}}}callback_one_txt && callback_one_txt();text_dom.innerHTML += '<span class="typeit_text_css"></span>';// 根据是否需要模拟真实打字速度来设置下次执行的时间间隔setTimeout(nextStep, lifeLike ? getRandomSpeed(min_speed, max_speed) : min_speed);}// 启动定时器,开始执行第一步操作let intervalId = setTimeout(nextStep, lifeLike ? getRandomSpeed(min_speed, max_speed) : min_speed);
}
css
.typeit_text_css{display: inline-block;position: relative;
}/* 小光标 */
.typeit_text_css::after{content: '';position: absolute;right: -1px;height: 15px;width: 1px;top: 40%;transform: translateY(-50%);background-color: #ece3e3;animation: san 0.5s steps(1) infinite;
}
@keyframes san{0%,100%{background-color: #727272;}50%{background-color: transparent;}
}
使用方法
<!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="./typeit_cy.js"></script><link rel="stylesheet" href="./typeit_cy.css">
</head>
<body><h1 id="typeit_text_css"></h1><script>typeit({select: '#typeit_text_css',strings: ['你好', '欢迎'],lifeLike: true,loop: false});</script>
</body>
</html>
<!-- 引入 -->
<link rel="stylesheet" href="./typeit_cy/typeit_cy.css">
<script src="./typeit_cy/typeit_cy.js"></script>
/*** 动态打字效果函数* (select和element只能选择一个)* @param {Object} options - 配置选项* @param {string} options.select - 选择器,用于定位要显示文本的DOM元素("#id"或".class")* @param {Object} options.element - DOM元素(Element对象)* @param {string[]} options.strings - 要依次显示的字符串数组* @param {boolean} [options.lifeLike=true] - 是否模拟真实打字速度* @param {boolean} [options.loop=true] - 是否循环显示字符串* @param {number} [options.min_speed=200] - 最小打字速度(毫秒)* @param {number} [options.max_speed=500] - 最大打字速度(毫秒)* @param {Function} [options.callback_one_txt=null] - 每个字符打字结束后的回调函数* @param {Function} [options.callback=null] - 打字结束后的回调函数(不循环时有效)*/
typeit({select: '#title',strings: ['你好', '欢迎使用CYAI'],lifeLike: true,loop: false
});const messageSpan = document.createElement('span');
messageSpan.className = `message ${type}_message`;
typeit({element: messageSpan,strings: [text],lifeLike: true,loop: false,min_speed: 0,max_speed: 200,max_line_length: 1,callback_one_txt: () => {messageContainer.scrollTop = messageContainer.scrollHeight; // 滚动到底部},callback: () => {messageContainer.scrollTop = messageContainer.scrollHeight; // 滚动到底部}
});