暗模式下如何添加单个开关

时间:2020-04-06 11:40:52

标签: javascript html css

我想为网站设置一个亮/暗模式开关。目前我有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

1 个答案:

答案 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>