重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
效果
创新互联专注于铁西企业网站建设,响应式网站建设,商城网站定制开发。铁西网站建设公司,为铁西等地区提供建站服务。全流程按需网站设计,专业设计,全程项目跟踪,创新互联专业和态度为您提供的服务
首先看看效果:
本文将介绍如何基于Angular 8和Bootstrap 4来实现上面的主题切换效果。
设计
遵循Bootstrap的设计,我们会使用 bootswatch.com 提供的免费主题来实现上面的效果。Bootswatch为前端程序员提供了多达21种免费的Bootstrap主题,并且提供了API文档 和 实例页面 ,介绍如何在HTML+jQuery的环境中实现主题切换。其实,我们也可以使用Bootstrap官网提供的主题设计工具来设计自己的主题,这些自定义的主题也是可以用在本文介绍的方法里的,只需要替换相关的资源地址就可以。如果你打开Bootswatch的API,你就会看到各种主题的元数据信息,我们可以使用其中的cssMin链接来替换主页的link地址,以达到切换主题的目的。
在开工之前,还是要做一些粗略的设计。为了简单起见,我使用Bootstrap的Navbar来完成这个功能,因为Navbar的代码可以直接从Bootstrap官网拷贝过来,稍微改改就行。不同的是,我将Navbar封装在一个组件(Component)里,这样做的好处是,可以将切换主题的功能封装起来,以实现模块化的设计。下图展示了这一设计:
基本流程如下:
步骤
首先,根据Bootswatch API所返回的数据结构,定义一个数据模型:
export class ThemeDefinition { name: string; description: string; thumbnail: string; preview: string; css: string; cssMin: string; csscdn: string; scss: string; scssVariables: string; } export class Themes { version: String; themes: ThemeDefinition[]; }
然后,创建theme.service.ts服务,用来调用Bootswatch API:
import { Injectable } from '@angular/core'; import { HttpClient } from '@angular/common/http'; import { Observable } from 'rxjs'; import { Themes } from '../models/themes'; @Injectable({ providedIn: 'root' }) export class ThemeService { constructor(private http: HttpClient) { } getThemes(): Observable{ return this.http.get ('https://bootswatch.com/api/4.json'); } }
接下来,创建Navbar组件,关键代码部分就是将主题的名称绑定到dropdown上,并根据选择的主题名称决定当前所显示的主题名称是否应该是active的。当然,dropdown的每个item还应该响应用户的点击事件:
Navbar组件的代码如下:
import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core'; import { Themes } from 'src/app/models/themes'; import { ThemeService } from 'src/app/services/theme.service'; import { ThemeDefinition } from 'src/app/models/theme-definition'; @Component({ selector: 'app-nav-bar', templateUrl: './nav-bar.component.html', styleUrls: ['./nav-bar.component.css'] }) export class NavBarComponent implements OnInit { @Input() themes: Themes; @Input() selectedTheme:string; @Output() themeSelectionChanged : EventEmitter= new EventEmitter(); constructor(private themeService: ThemeService) { } ngOnInit() { } onThemeItemSelected(event: any) { const selectedThemeName = event.target.text; const selectedTheme = this.themes.themes.find(t => t.name === selectedThemeName); this.themeSelectionChanged.emit(selectedTheme); } }
在onThemeItemSelected事件处理函数中,会读取被点击dropdown item的名称,根据该名称找到所选的主题,然后将其作为事件数据,发起themeSelectionChanged事件,然后,就是app.component.ts来处理这个事件了。在该事件处理函数中,从事件数据获取主题信息,然后调用applyTheme方法来应用主题:
import { Component, OnInit } from '@angular/core'; import { ThemeDefinition } from './models/theme-definition'; import { Themes } from './models/themes'; import { ThemeService } from './services/theme.service'; import { environment } from 'src/environments/environment'; import { StorageMap } from '@ngx-pwa/local-storage'; @Component({ selector: 'app-root', templateUrl: './app.component.html', styleUrls: ['./app.component.css'] }) export class AppComponent implements OnInit { title = 'nblogger'; themes: Themes; selectedTheme: string; constructor(private themeService: ThemeService, private storage: StorageMap) { } ngOnInit() { this.themeService.getThemes() .subscribe(data => { this.themes = data; this.storage.get('app-theme-name').subscribe(name => { const themeName = name ? name : environment.defaultTheme; const currentTheme = this.themes.themes.find(t => t.name === themeName); this.applyTheme(currentTheme); }); }); } onThemeSelectionChanged(event: ThemeDefinition) { this.applyTheme(event); } private applyTheme(def: ThemeDefinition): void { this.storage.set('app-theme-name', def.name).subscribe(()=>{}); this.selectedTheme = def.name; const links = document.getElementsByTagName('link'); for(let i = 0; i < links.length; i++) { const link = links[i]; if (link.getAttribute('rel').indexOf('style') !== -1 && link.getAttribute('type').indexOf('text') !== -1) { link.setAttribute('href', def.cssMin); } } } }
在applyTheme方法中,首先会将所选主题名称设置到LocalStorage中,以便下次打开页面的时候能够直接应用主题;然后,从当前document中找到所需的link tag,并将其href值替换为所选主题信息的cssMin链接地址(内容可以参考Bootswatch的API结果)以此完成主题替换。
当重新打开页面时,app.component.ts中的ngOnInit初始化方法会被首先调用,它会通过theme.service.ts来读取主题信息,之后判断LocalStorage中是否有已经设置好的主题。如果有,则使用该主题,否则就从environment.ts的默认值中选择主题名称进行设置。
app.component.ts所使用的template就比较简单,主体是对Navbar组件的引用,还可以加一些额外的HTML元素进行效果测试:
Heading 1
Heading 2
Heading 3
Heading 4
这是一个警告框A simple secondary alert—check it out!A simple success alert—check it out!A simple danger alert—check it out!A simple warning alert—check it out!A simple info alert—check it out!A simple light alert—check it out!A simple dark alert—check it out!
当然,记得在index.html中加入link的占位符,以便上面的applyTheme方法能够找到它:
Nblogger
总结
我们可以将Bootswatch的所有主题下载到本地,由本地服务来提供主题的API,这样切换主题会变得更快,也可以自己自定义主题然后扩展这个自制的本地API来提供更丰富的主题,根据需要来定吧。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持创新互联。