欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解如何使用JavaScript構(gòu)建主題切換器

 更新時間:2024年01月29日 09:54:26   作者:南城FE  
這篇文章主要為大家詳細介紹了如何使用JavaScript構(gòu)建一個主題切換器,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學習一下

本文翻譯自 How to implement Theme Switcher in JavaScript,作者:Pavel Keyzik, 略有刪改。 

在本文中,您將學習如何在JavaScript中構(gòu)建主題切換器。這應該是一件很容易的事情,但你也可以從我的代碼中學到一些東西。

我們需要處理哪些場景

  • 我們應該解決的最基本的場景之一是將主題從亮到暗,反之亦然。
  • 我們需要解決的第二件事是,有些人更喜歡使用與系統(tǒng)中相同的設(shè)置。這對那些整天在黑暗和光明主題之間切換的人很有用。
  • 第三件事是保存用戶首選項,否則刷新頁面后所有設(shè)置將再次設(shè)置為默認值。

創(chuàng)建主題存儲

我們創(chuàng)建初始函數(shù)createThemeStore(),它將包含幾乎所有內(nèi)容。我們在這里用這種方式實現(xiàn),但這可能不是最佳方法。

function createThemeStore(options) {
  // Initial mode
  const initialMode = options.defaultMode || 'system'

  // Initial state
  const state = {
    mode: initialMode,
    systemTheme: getSystemTheme(),
    theme: getThemeByMode(initialMode),
  }
}

在這里,我們創(chuàng)建一個只有3個變量的狀態(tài):

  • mode:這表示主題的選定模式,可能值為darklightsystem。它允許我們決定是否使用系統(tǒng)的主題。
  • systemTheme:它保存當前操作系統(tǒng)主題的值。即使我們選擇了特定的主題(darklight),當操作系統(tǒng)主題發(fā)生變化時,我們?nèi)詴麓俗兞浚源_保用戶切換到系統(tǒng)模式時,我們能正確調(diào)整主題。
  • theme:這是用戶看到的實際主題,可能值為darklight。
  • options.defaultMode:用于恢復正確的主題首選項。例如,您可以在localStorage中保存主題更改,然后將其用作默認值,確保保留用戶的首選項。

添加訂閱

當用戶更改主題或OS主題更新時,我們需要一種方法來通知我們的代碼,這就是使用訂閱的地方,我們需要允許訂閱state對象中的更改。下面的代碼將幫助我們完成它,記住現(xiàn)在我們在createThemeStore()中執(zhí)行所有操作。

function createThemeStore(options) {
  // ...

  // Create subscriptions object to be able notify subscribers
  const subscriptions = new Map()
  let subscriptionId = 0 // Just a unique id for every subscriber

  // A place where we send notification to all of our subscribers
  function notifyAboutThemeChange(theme) {
    subscriptions.forEach((notify) => {
      const notificationData = {
        mode: state.mode,
        theme,
      }

      notify(notificationData) // Calls subscribed function (The example how we use it will be later)
    })
  }

  // A function that allows to subscribe to state changes
  function subscribe(callback) {
    subscriptionId++
    subscriptions.set(subscriptionId, callback)

    state.systemTheme = getSystemTheme() // We'll define it later

    if (state.mode === 'system') {
      notifyAboutThemeChange(state.systemTheme)
    } else {
      notifyAboutThemeChange(state.theme)
    }

    return subscriptionId
  }

  // A function that allows to unsubscribe from changes
  function usubscribe(subscriptionId) {
    subscriptions.delete(subscriptionId)
  }

  return {
    subscribe,
    usubscribe,
  }
}

使用方式:

// Create a theme store
const store = createThemeStore()

// Suscribe to changes
const subscriptionId = store.subscribe((newTheme) => {
  // Here you'll be seeing theme changes
  console.log(newTheme)
})

// When you need to unsubscribe from theme change, you just call
store.usubscribe(subscriptionId)

檢測系統(tǒng)主題首選項

現(xiàn)在我們有了基本的代碼結(jié)構(gòu),讓我們再定義兩個helper函數(shù):

  • getSystemTheme():該函數(shù)返回當前OS主題darklight
  • getThemeByMode():該函數(shù)根據(jù)我們的主題模式返回darklight。例如,如果模式設(shè)置為dark,則返回dark。但是,當模式設(shè)置為系統(tǒng)時,我們會檢查系統(tǒng)主題,并根據(jù)操作系統(tǒng)的首選項,以darklight作為返回值。

這段代碼不會出現(xiàn)在我們的createThemeStore()函數(shù)中。我們將window.matchMediaprefers-color-scheme媒體查詢一起使用來確認當前系統(tǒng)的主題值。

const mediaQuery = '(prefers-color-scheme: dark)'

// Get's current OS system
function getSystemTheme() {
  if (window.matchMedia(mediaQuery).matches) {
    return 'dark'
  }
  return 'light'
}

// Based on user's preferences we return correct theme
function getThemeByMode(mode) {
  if (mode === 'system') {
    return getSystemTheme()
  }
  return mode
}

function createThemeStore(options) {
  // ...
}

現(xiàn)在我們唯一需要做的就是添加事件監(jiān)聽器,以檢測操作系統(tǒng)主題的變化。

function createThemeStore(options) {
  // ...

  // When the OS preference has changed
  window.matchMedia(mediaQuery).addEventListener('change', (event) => {
    const prefersDarkMode = event.matches

    // We change system theme
    state.systemTheme = prefersDarkMode ? 'dark' : 'light'

    // And if user chose `system` mode we notify about the change
    // in order to be able switch theme when OS settings has changed
    if (state.mode === 'system') {
      notifyAboutThemeChange(state.systemTheme)
    }
  })
}

添加手動更改主題模式的功能

現(xiàn)在每當我們的操作系統(tǒng)首選項更改時,我們已經(jīng)實現(xiàn)了主題的自動更新。我們還沒有討論的是主題模式的手動更新。你將在你的深色、淺色和系統(tǒng)主題按鈕上使用這個功能。

function createThemeStore(options) {
  // ...

  function changeThemeMode(mode) {
    const newTheme = getThemeByMode(mode)

    state.mode = mode
    state.theme = newTheme

    if (state.mode === 'system') {
      // If the mode is system, send user a system theme
      notifyAboutThemeChange(state.systemTheme)
    } else {
      // Otherwise use the one that we've selected
      notifyAboutThemeChange(state.theme)
    }
  }

  return {
    subscribe,
    usubscribe,
    changeThemeMode,
  }
}

使用示例

我們的代碼是純JavaScript實現(xiàn),你可以在任何地方使用它。我將在React中演示一個示例,但您可以在任何您喜歡的框架或庫中嘗試它。

// Create a theme store from saved theme mode
// or use `system` if user hasn't changed preferences
const store = createThemeStore({
  defaultMode: localStorage.getItem("theme") || "system",
});

function MyComponent() {
  // Initial active theme is `null` here, but you could use the actual value
  const [activeTheme, setActiveTheme] = useState(null)

  useEffect(() => {
    // Subscribe to our store changes
    const subscriptionId = store.subscribe((notification) => {
      // Update theme
      setActiveTheme(notification.theme)

      // Save selected theme mode to localStorage
      localStorage.setItem('theme', notification.mode)
    })

    return () => {
      store.usubscribe(subscriptionId)
    }
  }, [])

  return (
    <>
      <p>
        Active theme: <b>{activeTheme}</b>
      </p>
      <p>Change theme to:</p>
      <button onClick={() => store.changeThemeMode("dark")}>Dark</button>
      <button onClick={() => store.changeThemeMode("light")}>Light</button>
      <button onClick={() => store.changeThemeMode("system")}>System</button>
    <>
  )
}

最后

本文介紹了如何在JavaScript中實現(xiàn)主題切換。通過創(chuàng)建一個主題存儲器以及添加訂閱功能以便在主題發(fā)生變化時通知調(diào)用方,最后還增加了手動切換主題模式和在React中演示的代碼示例。

如果你的網(wǎng)站正有主題切換的需求,不妨可以試試看。

到此這篇關(guān)于詳解如何使用JavaScript構(gòu)建主題切換器的文章就介紹到這了,更多相關(guān)JavaScript主題切換器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaScript模擬數(shù)組合并concat

    JavaScript模擬數(shù)組合并concat

    這篇文章主要介紹了JavaScript模擬數(shù)組合并concat的相關(guān)資料,需要的朋友可以參考下
    2016-03-03
  • Javascript拖拽系列文章1之offsetParent屬性

    Javascript拖拽系列文章1之offsetParent屬性

    這個系列文章主要是講述實現(xiàn)Javascript拖拽功能的基礎(chǔ)知識,并將在最后給出一個完整的示例。適合對拖拽完全不懂的人閱讀
    2008-09-09
  • 全面解析Bootstrap彈窗的實現(xiàn)方法

    全面解析Bootstrap彈窗的實現(xiàn)方法

    這篇文章全面解析Bootstrap彈窗的實現(xiàn)方法,對其結(jié)構(gòu)進行詳細分析,感興趣的小伙伴們可以參考一下
    2015-12-12
  • JavaScript導航腳本判斷當前導航

    JavaScript導航腳本判斷當前導航

    這篇文章主要介紹了JavaScript導航腳本判斷當前導航的相關(guān)資料,非常不錯,具有參考借鑒價值,需要的朋友可以參考下
    2016-07-07
  • 通過DOM腳本去設(shè)置樣式信息

    通過DOM腳本去設(shè)置樣式信息

    在大多數(shù)場合,我們都用CSS去設(shè)置樣式,但在某些特殊情況下,例如要根據(jù)元素在節(jié)點樹里的位置來設(shè)置節(jié)點樣式信息時,目前CSS還沒辦法做到這一點。但利用DOM就可以很輕易的完成。
    2010-09-09
  • JS中把函數(shù)作為另一函數(shù)的參數(shù)傳遞方法(總結(jié))

    JS中把函數(shù)作為另一函數(shù)的參數(shù)傳遞方法(總結(jié))

    下面小編就為大家?guī)硪黄狫S中把函數(shù)作為另一函數(shù)的參數(shù)傳遞方法(總結(jié))。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • js實現(xiàn)單擊可修改表格

    js實現(xiàn)單擊可修改表格

    這篇文章主要為大家詳細介紹了js實現(xiàn)單擊可修改表格,類似成績單,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • 中國地區(qū)三級聯(lián)動下拉菜單效果分析

    中國地區(qū)三級聯(lián)動下拉菜單效果分析

    主要的數(shù)據(jù)和功能實現(xiàn)都是在js文件中,網(wǎng)上找的地區(qū)數(shù)據(jù)有的地方不完整,需要自己添加,本文將詳細介紹
    2012-11-11
  • Js四則運算函數(shù)代碼

    Js四則運算函數(shù)代碼

    javascript的除法結(jié)果會有誤差,在兩個浮點數(shù)相除的時候會比較明顯。這個函數(shù)返回較為精確的除法結(jié)果
    2012-07-07
  • 微信小程序自定義可滑動的tab切換

    微信小程序自定義可滑動的tab切換

    這篇文章主要為大家詳細介紹了微信小程序自定義tab切換,可滑動,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07

最新評論