问题
Currently I am studying the dark mode function.
I have a question while studying the dark mode feature.
Clicking the dark mode button changes other tags, but not the iframe tag.
I want to apply dark mode to iframe tag as well.
What should I do?
The source below is the source in the file.
01. file : index.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<style>
iframe {
margin:0;
padding:0;
}
.layout-01 {
border: 1px solid #ddd;
padding:10px;
margin-bottom: 20px;
background: var(--bg-color);
color: var(--font-color);
}
.iframe-layout {
border: 1px solid #ddd;
background: var(--bg-color);
color: var(--font-color);
}
.iframe-layout iframe html p {
color: var(--font-color);
}
:root {
--bg-color: #fff;
--font-color: #000;
}
html.darkmode:root {
--bg-color: #000;
--font-color: #fff;
}
</style>
</head>
<body>
<div>
<button onClick="userTheme(true);">Toogle Theme</button>
</div>
<script>
function userTheme(toggle = false) {
let userMode = localStorage.userThemeMode || 'auto';
const osMode = !!window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? 'dark' : 'light';
if(toggle) {
switch(userMode) {
case 'auto':
userMode = 'dark'; break;
case 'dark':
userMode = 'light'; break;
default:
userMode = 'auto';
}
localStorage.userThemeMode = userMode;
}
console.log(`current mode : ${userMode}`);
window.__THEME_MODE = userMode === 'auto' ? osMode : userMode;
document.getElementsByTagName('html')[0].classList[window.__THEME_MODE === 'dark' ? 'add' : 'remove']('darkmode');
//document.querySelectorAll('iframe')[0].classList[window.__THEME_MODE === 'dark' ? 'add' : 'remove']('darkmode');
}
if (!!window.matchMedia) {
['light', 'dark'].forEach(mode => {
window.matchMedia(`(prefers-color-scheme: ${mode})`).addListener(e => {
if(!!e.matches) {
userTheme();
}
});
});
}
userTheme();
</script>
<div>
<div class="layout-01">
<p>text</p>
</div>
<div i="iframe-layout">
<iframe src="test.html" frameborder="0" sandbox="allow-same-origin allow-scripts" seamless></iframe>
</div>
</div>
</body>
</html>
02. test.html
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<style>
iframe {
margin:0;
padding:0;
}
.layout-01 {
border: 1px solid #ddd;
padding:10px;
margin-bottom: 20px;
background: var(--bg-color);
color: var(--font-color);
}
.iframe-layout {
border: 1px solid #ddd;
background: var(--bg-color);
color: var(--font-color);
}
.iframe-layout iframe html p {
color: var(--font-color);
}
:root {
--bg-color: #fff;
--font-color: #000;
}
html.darkmode:root {
--bg-color: #000;
--font-color: #fff;
}
</style>
</head>
<body>
<div>
<button onClick="userTheme(true);">Toogle Theme</button>
</div>
<script>
function userTheme(toggle = false) {
let userMode = localStorage.userThemeMode || 'auto';
const osMode = !!window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches ? 'dark' : 'light';
if(toggle) {
switch(userMode) {
case 'auto':
userMode = 'dark'; break;
case 'dark':
userMode = 'light'; break;
default:
userMode = 'auto';
}
localStorage.userThemeMode = userMode;
}
console.log(`current mode : ${userMode}`);
window.__THEME_MODE = userMode === 'auto' ? osMode : userMode;
document.getElementsByTagName('html')[0].classList[window.__THEME_MODE === 'dark' ? 'add' : 'remove']('darkmode');
//document.querySelectorAll('iframe')[0].classList[window.__THEME_MODE === 'dark' ? 'add' : 'remove']('darkmode');
}
if (!!window.matchMedia) {
['light', 'dark'].forEach(mode => {
window.matchMedia(`(prefers-color-scheme: ${mode})`).addListener(e => {
if(!!e.matches) {
userTheme();
}
});
});
}
userTheme();
</script>
<div>
<div class="iframe-layout">
<p>sdfsdfsdf</p>
</div>
</div>
</body>
</html>
回答1:
You can take the following approach:
- On click of the dark mode button, change the URL of iframe by passing a query parameter. For eg: www.example.com?theme=dark.
- Within iframe, use JS to retrieve the query parameter. Based on the parameter, add/remove the css class which would affect the theme of the iframe. For eg:
let theme = 'dark' //Get this from URL
let class = theme=='dark'?'dark-theme-class':'default-theme';
document.body.classList.toggle(class);
This should work in your case.
回答2:
Use the CSS filter: invert()
property.
Check out
- the CSS invert,
- CSS invert summary &
- the CSS filter on MDN.
This snippet should show what I mean.
const iframes = document.querySelectorAll('iframe');
function toggleTheme() {
for (i = 0; i < iframes.length; i++) {
iframes[i].classList.toggle('is-dark');
}
}
.is-dark {
filter: invert(80%);
}
<!doctype html>
<html lang="en">
<body>
<button onClick="toggleTheme();">Toogle Theme</button>
<iframe id="the-iframe" src="https://wikipedia.org/"></iframe>
</body>
</html>
In a similar fashion, you can apply a sepia filter as shown in the following snippet.
const iframes = document.querySelectorAll('iframe');
function toggleTheme() {
for (i = 0; i < iframes.length; i++) {
iframes[i].classList.toggle('is-sepia');
}
}
.is-sepia {
filter: sepia(100%);
}
<!doctype html>
<html lang="en">
<body>
<button onClick="toggleTheme();">Toogle Theme</button>
<iframe id="the-iframe" src="https://wikipedia.org/"></iframe>
</body>
</html>
来源:https://stackoverflow.com/questions/63351439/when-i-click-the-dark-mode-button-i-want-to-apply-the-dark-mode-to-the-iframe-t