非活跃浏览器标签页标题动画JS脚本运行显示异常字符问题求助
问题根因
你遇到的异常符号是Unicode字符被强制截断导致的渲染乱码:
- JavaScript 内置的
substr、substring等字符串切割方法基于UTF-16码元计数,而🚂这类表情符号属于Unicode辅助平面字符,单个字符会占用2个UTF-16码元 - 当滚动计数i刚好落在表情符号占用的两个码元中间时,就会把完整的表情拆成两个无意义的半字符,最终在标题上显示为异常符号
修复方案
将字符串转为支持正确识别完整Unicode字符的数组后再做滚动操作,同时补全定时器清理逻辑避免内存泄漏。
修复后完整代码
var vis = (function () { var stateKey, eventKey, keys = { hidden: "visibilitychange", webkitHidden: "webkitvisibilitychange", mozHidden: "mozvisibilitychange", msHidden: "msvisibilitychange" }; for (stateKey in keys) { if (stateKey in document) { eventKey = keys[stateKey]; break; } } return function (c) { if (c) { document.addEventListener(eventKey, c); } return !document[stateKey]; }; })(); var storeTitle = document.title, myAnimationTimeout, myAnimationInterval; function getLokTitle() { // 用Array.from正确拆分包含Emoji的字符串为单个字符数组 let titleArr = Array.from("_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 🚂 "); let i = 0; const arrLength = titleArr.length; myAnimationTimeout = setTimeout(function () { myAnimationInterval = setInterval(function () { // 数组切片后拼接为字符串 document.title = titleArr.slice(i).concat(titleArr.slice(0, i)).join(''); i = (i + 1) % arrLength; if (vis() === true) { clearAllTimers(); document.title = storeTitle; } }, 250); }, 1000); } function clearAllTimers() { if (myAnimationTimeout) clearTimeout(myAnimationTimeout); if (myAnimationInterval) clearInterval(myAnimationInterval); myAnimationTimeout = null; myAnimationInterval = null; } function getStoreTitle() { clearAllTimers(); return storeTitle; } vis(function () { document.title = vis() ? getStoreTitle() : getLokTitle(); }); // 初始化状态 document.title = vis() ? getStoreTitle() : getLokTitle();
内容的提问来源于stack exchange,提问作者Julian
相关产品推荐
相关产品推荐

