我在一所在线大学工作,该大学使用由我们较大的母公司开发的专有学习管理系统。我们希望能够创建可嵌入的 HTML 块,为我们的课程添加一些风格。我们的 LMS 最近进行了更新,允许用户在其用户偏好中选择“深色模式”。 (LMS 无法识别浏览器是否处于深色模式)。当用户改变 LMS 的外观时,我们希望嵌入式 iframe 能够在深色和浅色之间切换。不幸的是,我们无法访问 LMS HTML 代码,因此我们无法要求父代码触发 iframe 内的更改。
我们已经能够通过为每个嵌入设置一个切换开关来解决这个问题,以便用户可以手动更新嵌入的外观方式,但这对于用户来说显然是一个相当笨重的过程。如果我们的嵌入之一可以对其父页面的颜色进行采样,以判断父页面是否正在使用深色模式,那就最好了。
现在,我们有一个 html 复选框,用于让用户手动切换到深色模式。
<div class="theme-switch-wrapper">
<label class="theme-switch" for="checkbox">
<input type="checkbox" id="checkbox" />
<div class="slider round"></div>
</label>
<em>Enable Dark Mode</em><br>
</div>
该复选框与 JavaScript 页面对话,该页面实际执行 switchTheme() 函数来进行切换。
const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
function switchTheme(e) {
if (e.target.checked) {
document.documentElement.setAttribute('data-theme', 'dark');
}
else {
document.documentElement.setAttribute('data-theme', 'light');
}
}
toggleSwitch.addEventListener('change', switchTheme, false);
一切都按设计进行,但如果能够通过识别父页面是否为深色来将主题设置为“深色”会更好。
有谁知道这是否可行?
window.frames
数组
您可以迭代主窗口的框架数组,并在每个 iframe 元素以及主窗口上设置亮/暗模式。
如果框架的内容来自不同的来源,则此方法将会失败。
以下代码是概念证明:它缺少添加新元素或更改现有 iframe 元素的内容时,代码需要在主窗口上下文中调用
switchTheme
的位。如果在 iframe 文档中执行此操作,请尝试首先以 top.switchTheme()
进行调用。
注意 由于 SO 片段的清理方式,此代码不会作为代码片段运行。在 Firefox 和 Edge 中进行测试时,它按照设计运行,没有安全错误。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Iframe themes</title>
<style>
:root[data-theme="light"] {
color: black;
background-color: ivory;
}
:root[data-theme="dark"] {
color: green;
background-color: black;
}
</style>
</head>
<body>
<div class="theme-switch-wrapper">
<label class="theme-switch" for="checkbox">
<input type="checkbox" id="checkbox">
<div class="slider round"></div>
</label>
<em>Enable Dark Mode</em><br>
</div>
<hr>
Main window
<hr>
<iframe srcdoc="Iframe content"></iframe>
<script>
"use strict";
const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
function switchTheme() {
const theme = toggleSwitch.checked ? 'dark' : 'light';
const windows = Array.from(window.frames);
windows.push(window);
windows.forEach(win => {
win.document.documentElement.dataset.theme = theme;
});
}
switchTheme() // initialise
toggleSwitch.addEventListener('change', switchTheme, false);
</script>
</body>
</html>