我想为网站设置一个亮/暗模式开关。目前我有2个开关,一个用于网站,一个用于图表。由于切换2个开关并不是很好的UI,因此我想将两个触发器同时应用于一个开关。
是否可以用一个开关而不是2个将它们汇总起来?
const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]'); /* This switch is toggling dark/light mode on whole website. */
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);
function switchTheme(e) {
if (e.target.checked) {
document.documentElement.setAttribute('data-theme', 'dark');
localStorage.setItem('theme', 'dark'); //add this
} else {
document.documentElement.setAttribute('data-theme', 'light');
localStorage.setItem('theme', 'light'); //add this
}
}
const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
if (currentTheme) {
document.documentElement.setAttribute('data-theme', currentTheme);
if (currentTheme === 'dark') {
toggleSwitch.checked = true;
}
}
/* Here is full JS code for a chart together with a switch especially for Chart (it doesn't affect website) */
const URL_DATA = 'https://s3.eu-central-1.amazonaws.com/fusion.store/ft/data/stock-chart-with-volume_data.json';
const URL_SCHEMA = 'https://s3.eu-central-1.amazonaws.com/fusion.store/ft/schema/stock-chart-with-volume_schema.json';
const jsonify = res => res.json();
const dataFetch = fetch(URL_DATA).then(jsonify);
const schemaFetch = fetch(URL_SCHEMA).then(jsonify);
Promise.all([
dataFetch,
schemaFetch
]).then(([
data,
schema
]) => {
var fusionTable = new FusionCharts.DataStore().createDataTable(data,
schema);
new FusionCharts({
type: 'timeseries',
renderAt: 'container',
width: '100%',
height: 550,
dataSource: {
caption: {
text: "Apple Inc. Stock Price"
},
subcaption: {
text: "Stock prices from May 2014 - November 2018"
},
chart: {
exportenabled: 1,
multicanvas: true,
theme: "fusion"
},
data: fusionTable,
yaxis: [{
plot: [{
value: {
open: "Open",
high: "High",
low: "Low",
close: "Close"
},
type: "candlestick"
}],
format: {
prefix: "$"
},
title: "Stock Price"
},
{
plot: [{
value: "Volume",
color: "#228B22",
type: "column"
}],
// max: "900000000"
}
],
navigator: {
enabled: 0
}
},
events: {
beforeRender: function(e, d) {
var container = e.data.container;
// Change the sizes according to your need
var options = {
fusion: "Light",
candy: "Dark",
};
var themeSelected = "fusion";
function instantiate() {
// Create option containers
var parent = container.parentNode;
var optionsContainer = document.createElement("div");
optionsContainer.id = "config-container";
var spanLabel = document.createElement("span");
spanLabel.id = "select-text";
spanLabel.innerText = "Choose a theme: ";
var radioContainer = document.createElement("div");
addClass(radioContainer, "change-type");
window.__onThemeChange = function(option) {
e.sender.setChartAttribute("theme", option);
};
// Util to add class
function addClass(element, className) {
var element,
name = className,
arr;
arr = element.className.split(" ");
if (arr.indexOf(name) == -1) {
element.className += " " + name;
}
}
function radioWrapper(
wrapperId,
inputId,
label,
selected,
optionLabel
) {
var item = "<div id='" + wrapperId + "' >";
item +=
"<input name='dimesion-selector' id='" +
inputId +
"' type='radio' " +
(selected ? "checked='checked'" : "") +
" onchange='__onThemeChange(\"" +
optionLabel +
"\")'/>";
item += "<label for='" + inputId + "' >" + label + "</label>";
item += "</div>";
return item;
}
var changeTypeChilds = "";
Object.keys(options).forEach(function(option, index) {
var label = options[option];
var selected = themeSelected === option;
var radioOption = radioWrapper(
"radio" + (index + 1),
"radioButton" + (index + 1),
label.toUpperCase(),
selected,
option
);
changeTypeChilds += radioOption;
});
radioContainer.innerHTML = changeTypeChilds;
optionsContainer.appendChild(spanLabel);
optionsContainer.appendChild(radioContainer);
parent.appendChild(optionsContainer);
var css =
'.change-type{display:inline-block;margin:0 10px;font-family:basefontRegular,Helvetica Neue,Arial,sans-serif}.change-type>div{display:inline-flex;position:relative;margin:0 10px}.change-type label{position:relative;padding:5px 4px 5px 30px;border-radius:4px}.change-type input{opacity:0;cursor:pointer;z-index:1;width:100%;height:100%;left:0;position:absolute}.change-type label:after,.change-type label:before{content:"";position:absolute}.change-type label:before{display:block;background:#fff;border:2px solid #949697;box-shadow:none;border-radius:50%;top: 15px;left: 9px;width:1rem;height:1rem}.change-type label:after{ width: .55rem;height: .55rem;top: 18px;left: 11px;border-radius: 100%;}.change-type input:checked~label{color:#48b884;font-weight:600;box-shadow:0 4px 9px 0 rgba(104,105,128,.22)}.change-type input:checked~label:before{color:#fff;box-shadow:none;border:2px solid #48b884}.change-type input:checked~label:after{background:#55bd8d}';
var styleNode = document.createElement("style");
styleNode.innerHTML = css;
document.body.appendChild(styleNode);
}
if (!window.__sample_theme_change) {
instantiate();
}
window.__sample_theme_change = true;
}
}
}).render();
});
/* This is a CSS for a light/dark mode on a website */
:root {
--primary-color: #302AE6;
--secondary-color: #536390;
--font-color: #424242;
--bg-color: #fff;
--heading-color: #292922;
}
[data-theme="dark"] {
--primary-color: #9A97F3;
--secondary-color: #818cab;
--font-color: #e1e1ff;
--bg-color: #161625;
--heading-color: #818cab;
}
body {
background-color: var(--bg-color);
color: var(--font-color);
/*other styles*/
}
h1 {
color: var(--secondary-color);
/*other styles*/
}
a {
color: var(--primary-color);
/*other styles*/
}
<div id="container" style="width: 100%"></div>
<!-- This is container for a Chart. -->
JSFiddle镜像:https://jsfiddle.net/hz3Lva1e
答案 0 :(得分:0)
如果您希望复选框更改图表的主题,则还可以隐藏图表的#config-container
。
这是一个有效的示例:https://jsfiddle.net/MrPolywhirl/u4tsjp9w/
图表底部的主题按钮调用__onThemeChange
函数。您可以自己称呼它。
const ThemeAliases = {
dark: 'candy',
light: 'fusion'
}
const setTheme = (theme) => {
document.documentElement.setAttribute('data-theme', theme);
localStorage.setItem('theme', theme); //add this
__onThemeChange(ThemeAliases[theme]);
};
/* This switch is toggling dark/light mode on whole website. */
const toggleSwitch = document.querySelector('.theme-switch input[type="checkbox"]');
toggleSwitch.addEventListener('change', switchTheme, false);
function switchTheme(e) {
setTheme(e.target.checked ? 'dark' : 'light');
}
const currentTheme = localStorage.getItem('theme') ? localStorage.getItem('theme') : null;
let loadedTheme = null;
if (currentTheme) {
document.documentElement.setAttribute('data-theme', currentTheme);
toggleSwitch.checked = currentTheme === 'dark';
loadedTheme = ThemeAliases[currentTheme];
}
new FusionCharts({
// ...
dataSource: {
// ...
chart: {
// ...
theme: loadedTheme || ThemeAliases.light
#config-container {
display: none;
}
.theme-switch {
text-align: center;
}
.theme-switch label {
font-family: "Source Sans Pro SemiBold"
}
<div class="theme-switch">
<label>Dark Theme</label>
<input type="checkbox" />
</div>
<div id="container" style="width: 100%"></div>