最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

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

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

我們需要處理哪些場景

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

創(chuàng)建主題存儲

我們創(chuàng)建初始函數(shù)createThemeStore(),它將包含幾乎所有內(nèi)容。我們在這里用這種方式實(shí)現(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:這表示主題的選定模式,可能值為dark、lightsystem。它允許我們決定是否使用系統(tǒng)的主題。
  • systemTheme:它保存當(dāng)前操作系統(tǒng)主題的值。即使我們選擇了特定的主題(darklight),當(dāng)操作系統(tǒng)主題發(fā)生變化時,我們?nèi)詴麓俗兞浚源_保用戶切換到系統(tǒng)模式時,我們能正確調(diào)整主題。
  • theme:這是用戶看到的實(shí)際主題,可能值為darklight。
  • options.defaultMode:用于恢復(fù)正確的主題首選項(xiàng)。例如,您可以在localStorage中保存主題更改,然后將其用作默認(rèn)值,確保保留用戶的首選項(xiàng)。

添加訂閱

當(dāng)用戶更改主題或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àng)

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

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

這段代碼不會出現(xiàn)在我們的createThemeStore()函數(shù)中。我們將window.matchMediaprefers-color-scheme媒體查詢一起使用來確認(rèn)當(dāng)前系統(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)在每當(dāng)我們的操作系統(tǒng)首選項(xiàng)更改時,我們已經(jīng)實(shí)現(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實(shí)現(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中實(shí)現(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)文章

最新評論

搜索| 胶州市| 清远市| 静海县| 德惠市| 福建省| 双柏县| 平南县| 宣化县| 凤台县| 城市| 茌平县| 汪清县| 泸州市| 瓦房店市| 上思县| 原阳县| 龙川县| 铅山县| 九龙坡区| 和硕县| 桃园县| 宜君县| 云龙县| 普格县| 广饶县| 湖南省| 醴陵市| 法库县| 洛隆县| 乡城县| 余江县| 灵台县| 河东区| 尚义县| 喀喇沁旗| 潜江市| 云浮市| 星子县| 都昌县| 和平区|