From 20317f46992a4d6c3a2bad343515f097586d2629 Mon Sep 17 00:00:00 2001 From: lkddi Date: Sat, 25 Apr 2026 10:32:25 +0800 Subject: [PATCH] =?UTF-8?q?=E8=BF=81=E7=A7=BB=E6=88=BF=E9=97=B4=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E8=B7=B3=E8=BD=AC=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resources/js/chat-room.js | 4 +++ resources/js/chat-room/rooms.js | 55 +++++++++++++++++++++++++++------ 2 files changed, 50 insertions(+), 9 deletions(-) diff --git a/resources/js/chat-room.js b/resources/js/chat-room.js index b503a71..7bcbf07 100644 --- a/resources/js/chat-room.js +++ b/resources/js/chat-room.js @@ -62,6 +62,7 @@ export { } from "./chat-room/preferences-status.js"; export { bindChatRightPanelControls } from "./chat-room/right-panel.js"; export { + bindRoomStatusControls, normalizeRoomStatus, renderRoomStatusRow, renderRoomsOnlineStatus, @@ -131,6 +132,7 @@ import { } from "./chat-room/preferences-status.js"; import { bindChatRightPanelControls } from "./chat-room/right-panel.js"; import { + bindRoomStatusControls, normalizeRoomStatus, renderRoomStatusRow, renderRoomsOnlineStatus, @@ -207,6 +209,7 @@ if (typeof window !== "undefined") { setSoundMuted, shouldMigrateLocalChatPreferences, bindChatRightPanelControls, + bindRoomStatusControls, normalizeRoomStatus, renderRoomStatusRow, renderRoomsOnlineStatus, @@ -261,6 +264,7 @@ if (typeof window !== "undefined") { bindShopControls(); bindVipControls(); bindChatRightPanelControls(); + bindRoomStatusControls(); bindMobileDrawerControls(); bindWelcomeMenuControls(); bindBlockMenuControls(); diff --git a/resources/js/chat-room/rooms.js b/resources/js/chat-room/rooms.js index 584bc87..400b070 100644 --- a/resources/js/chat-room/rooms.js +++ b/resources/js/chat-room/rooms.js @@ -6,6 +6,9 @@ import { escapeHtml } from "./html.js"; const EMPTY_ROOMS_HTML = '
暂无房间
'; +// 事件委托只需要注册一次,避免房间在线状态定时刷新后重复绑定。 +let roomStatusControlsBound = false; + /** * 转换接口房间数据,过滤异常房间编号。 * @@ -39,18 +42,52 @@ export function resolveRoomUrl(roomId, roomUrlResolver = undefined) { } /** - * 生成可放入 onclick 属性的安全跳转语句。 - * 这里暂时保留属性字符串,是为了兼容现有 HTML 字符串渲染入口。 - * URL 先 JSON 字符串化再转义,避免地址内容突破属性上下文。 + * 生成房间跳转数据属性,实际跳转由事件委托统一处理。 + * 只输出 data 属性,避免在线房间列表继续混入内联 onclick。 * * @param {number} roomId * @param {(roomId:number) => string} [roomUrlResolver] * @returns {string} */ -function buildRoomClickHandler(roomId, roomUrlResolver = undefined) { - const safeUrlLiteral = escapeHtml(JSON.stringify(resolveRoomUrl(roomId, roomUrlResolver))); +function buildRoomClickAttributes(roomId, roomUrlResolver = undefined) { + const safeUrl = escapeHtml(resolveRoomUrl(roomId, roomUrlResolver)); - return `onclick="location.href=${safeUrlLiteral}"`; + return `data-room-url="${safeUrl}"`; +} + +/** + * 绑定房间列表跳转事件。 + * 右侧面板和手机抽屉都复用 data-room-url,刷新 HTML 后无需重新绑定。 + * + * @returns {void} + */ +export function bindRoomStatusControls() { + if (roomStatusControlsBound || typeof document === "undefined") { + return; + } + + roomStatusControlsBound = true; + + document.addEventListener("click", (event) => { + if (!(event.target instanceof Element)) { + return; + } + + const roomLink = event.target.closest("[data-room-url]"); + + if (!roomLink) { + return; + } + + const roomUrl = roomLink.getAttribute("data-room-url"); + + if (!roomUrl) { + return; + } + + event.preventDefault(); + window.location.href = roomUrl; + }); } /** @@ -73,14 +110,14 @@ export function renderRoomStatusRow(room, options = {}) { : '当前') : ""; // 当前房间不生成跳转事件,避免重复进入同一房间触发无意义刷新。 - const clickHandler = isCurrent ? "" : buildRoomClickHandler(room.id, options.roomUrlResolver); + const clickAttributes = isCurrent ? "" : buildRoomClickAttributes(room.id, options.roomUrlResolver); const badge = room.online > 0 ? `${room.online}${variant === "mobile" ? "" : " "}人` : ``; // 手机和桌面只区分容器尺寸与视觉密度,房间数据口径保持同一套。 if (variant === "mobile") { - return `
@@ -92,7 +129,7 @@ export function renderRoomStatusRow(room, options = {}) { const border = isCurrent ? "#aac5f0" : "#e0eaf5"; - return `