开幕小剧场
了解如何制作个性化的开幕小剧场
开幕小剧场可以通过生成 HTML 的美化,制作个性化的开幕效果(模拟预热论坛、角色的日记、手机朋友圈等)。
此功能为进阶玩法,有一定难度,可以在创作者页面预览效果。想要添加调试有问题的可以联系小助手。
基本格式
用 ``` 代码块包裹的开幕小剧场内容会被放进独立的 iframe 中渲染(沙盒隔离,与聊天页主样式隔离),平台会把里面的内容作为 iframe 的 HTML 文档加载。不用 ``` 包裹时 HTML 也会被渲染,但走的是内联渲染(经安全过滤),失去了 iframe 的隔离保护。
```
(这里面写 HTML 样式,也可以写 JS,见下方「脚本(JS)」)
```前后的 符号不要漏!只有被 包裹的内容才会放进独立的 iframe 沙盒中隔离渲染;漏掉的话,HTML 会改为内联渲染(仍会经过安全过滤),虽然大多也能显示,但失去了 iframe 隔离,容易和聊天页样式互相干扰。
样式必须写在小剧场自己的 HTML 里
所以小剧场的样式要写在它自己的 HTML 内部:
```
<style>
.my-forum { background: #14141c; border-radius: 12px; padding: 16px; }
.my-forum .post { border-bottom: 1px solid rgba(255,255,255,.08); }
</style>
<div class="my-forum">
<div class="post">……</div>
</div>
```两种渲染方式的能力差异
| 用 ``` 包裹(iframe 沙盒) | 不包裹(内联渲染) | |
|---|---|---|
你写的 <style> | ✅ 生效,且完全隔离 | ✅ 生效 |
| 全局 CSS 样式 | ❌ 不注入 | ❌ 不注入 |
| 自定义正则规则 | ❌ 不执行 | ❌ 不执行 |
预设标签(<narration> / <bubble> 等) | ❌ 标签被剥掉,只留纯文字 | ✅ 按系统默认样式渲染(但你在全局 CSS 里对它们的改写不生效) |
| Markdown 语法 | ❌ 不解析 | ✅ 解析 |
{{user}} / {{char}} 占位符 | ❌ 原样显示 | ✅ 会替换 |
| JavaScript | ✅ 支持(见下方「脚本(JS)」) | ❌ <script> 被整段删掉 |
结论:想完全掌控排版就用 ``` 包裹并自带 <style>;想顺手用 Markdown 和预设标签的默认样式,就不包裹。两者都拿不到全局 CSS。
脚本(JS)
只有用 ``` 包裹的小剧场能跑脚本。 不包裹的内联渲染里,<script> 会被整段删掉,不报任何错。
脚本直接内联写在小剧场自己的 HTML 里:
```
<div class="tabs">
<button data-t="1" class="on">序章</button>
<button data-t="2">回忆</button>
</div>
<div class="panel on" id="p1">雨停了。</div>
<div class="panel" id="p2">三年前的今天……</div>
<script>
document.querySelectorAll('.tabs button').forEach(function (b) {
b.addEventListener('click', function () {
document.querySelectorAll('.tabs button').forEach(function (x) { x.classList.remove('on'); });
b.classList.add('on');
document.querySelectorAll('.panel').forEach(function (p) { p.classList.remove('on'); });
document.getElementById('p' + b.dataset.t).classList.add('on');
});
});
</script>
```可以用
- 完整的 JS 语法:
class/async-await/Promise/ 解构 /Map、Set等 - DOM 操作:
querySelector、createElement、innerHTML、classList、style、dataset - 事件:
addEventListener全部事件(点击、触摸、键盘、输入、变更…) - 定时与动画:
setTimeout、setInterval、requestAnimationFrame、element.animate() - 观察器:
ResizeObserver、MutationObserver、IntersectionObserver - Canvas 2D 绘图:
getContext('2d') - 音视频控制:
video.play()/pause()/currentTime(必须由玩家点击触发) - 写入剪贴板:
navigator.clipboard.writeText()
不能用
下面这些不要用:
| 写法 | 结果 |
|---|---|
fetch / XMLHttpRequest / WebSocket / sendBeacon | 无法联网,请求被拦截 |
eval / new Function | 被安全策略禁止 |
<script src="..."> / import() / Worker | 加载不了,代码请内联写 |
localStorage / sessionStorage / document.cookie | 直接抛错,请改用普通变量 |
alert / confirm / prompt | 无效,请用页面内的元素代替 |
window.open / target="_blank" / 跳转页面 | 打不开 |
parent / top 访问外层页面 | 抛错 |
history.pushState / replaceState | 抛错 |
navigator.clipboard.readText() | 只支持写入剪贴板,不支持读取 |
| WebGL、全屏 | 不支持 |
<video autoplay> 自动播放 | autoplay 会被移除,请让玩家点击播放 |
内联事件 onclick="..." | 属性会被移除,请用 addEventListener |
<iframe> / <form> | 会被删除 |
排版上要注意
position: fixed请改用absolute—— 小剧场里没有页面视口- 不要用
vh撑高(min-height: 100vh等)—— 高度由内容决定,vh算不准 - 不要手动设
document.body.style.height—— 高度会自动跟随内容变化,包括脚本切换内容之后
创作台的开幕小剧场输入框会自动体检,写到上面这些不生效的写法时会用红字提示你。
外投影 / 溢出元素被裁掉了? 平台在小剧场外面包了一层容器,它带 overflow: hidden 和圆角。你的内容(尤其 iframe 里的)超出边界的部分会被裁掉,从内部改不了。需要方角或让内容溢出时,在全局 CSS里改 .lore-bubble:
.lore-bubble {
border-radius: 0;
overflow: visible;
}