是否可以更改角材料垫滑动切换图标?

mic*_*est 8 angular-material angular

我使用的是 Angular 材质版本 9.2.4。

我想将切换图标覆盖为 font Awesome 图标,我发现一些示例是使用 css 代码background-image来覆盖它,但是可以使用 font-awesome 来更改切换图标吗?
这就是我想要自定义的图标切换。
在此输入图像描述

Joo*_*rts 12

这应该可以通过一些 DOM 操作来实现。在撰写本文时,这适用于材料 15。

材质 >= 15(使用 SVG)

在此输入图像描述

Material 15(带有基于 MDC 的组件)现在mat-slide-toggle带有图标(在本例中为 SVG 路径)。虽然不可能更换开关图标 - 相反,我们可以瞄准它们并更改属性path.d

  1. 我从材质图标中获取了暗/亮模式的图标,并将其下载为 SVG。https://fonts.google.com/icons?icon.query=dark+mode

  2. 我使用在线 SVG 编辑器将它们缩小了 50%:https://aydos.com/svgedit/图标需要缩小以适应开关。

  3. 用于@ViewChild查找和查询正确的 SVG 目标并替换其属性。我用缩小版本d替换了默认属性。我们需要使用to accesspath将元素读取为 ElementRef 。{ read: ElementRef }nativeElement

虽然使用querySelector不是最佳的 - 也许有更好的方法。

html:

<mat-slide-toggle #darkModeSwitch></mat-slide-toggle>
Run Code Online (Sandbox Code Playgroud)

TS:

@Component({
  selector: 'slide-toggle-overview-example',
  templateUrl: 'slide-toggle-overview-example.html',
})
export class SlideToggleOverviewExample implements AfterViewInit {

  @ViewChild('darkModeSwitch', { read: ElementRef }) element: ElementRef | undefined;


  sun = 'M12 15.5q1.45 0 2.475-1.025Q15.5 13.45 15.5 12q0-1.45-1.025-2.475Q13.45 8.5 12 8.5q-1.45 0-2.475 1.025Q8.5 10.55 8.5 12q0 1.45 1.025 2.475Q10.55 15.5 12 15.5Zm0 1.5q-2.075 0-3.537-1.463T7 12q0-2.075 1.463-3.537T12 7q2.075 0 3.537 1.463T17 12q0 2.075-1.463 3.537T12 17ZM1.75 12.75q-.325 0-.538-.213Q1 12.325 1 12q0-.325.212-.537Q1.425 11.25 1.75 11.25h2.5q.325 0 .537.213Q5 11.675 5 12q0 .325-.213.537-.213.213-.537.213Zm18 0q-.325 0-.538-.213Q19 12.325 19 12q0-.325.212-.537.212-.213.538-.213h2.5q.325 0 .538.213Q23 11.675 23 12q0 .325-.212.537-.212.213-.538.213ZM12 5q-.325 0-.537-.213Q11.25 4.575 11.25 4.25v-2.5q0-.325.213-.538Q11.675 1 12 1q.325 0 .537.212 .213.212 .213.538v2.5q0 .325-.213.537Q12.325 5 12 5Zm0 18q-.325 0-.537-.212-.213-.212-.213-.538v-2.5q0-.325.213-.538Q11.675 19 12 19q.325 0 .537.212 .213.212 .213.538v2.5q0 .325-.213.538Q12.325 23 12 23ZM6 7.05l-1.425-1.4q-.225-.225-.213-.537.013-.312.213-.537.225-.225.537-.225t.537.225L7.05 6q.2.225 .2.525 0 .3-.2.5-.2.225-.513.225-.312 0-.537-.2Zm12.35 12.375L16.95 18q-.2-.225-.2-.538t.225-.512q.2-.225.5-.225t.525.225l1.425 1.4q.225.225 .212.538-.012.313-.212.538-.225.225-.538.225t-.538-.225ZM16.95 7.05q-.225-.225-.225-.525 0-.3.225-.525l1.4-1.425q.225-.225.538-.213.313 .013.538 .213.225 .225.225 .537t-.225.537L18 7.05q-.2.2-.512.2-.312 0-.538-.2ZM4.575 19.425q-.225-.225-.225-.538t.225-.538L6 16.95q.225-.225.525-.225.3 0 .525.225 .225.225 .225.525 0 .3-.225.525l-1.4 1.425q-.225.225-.537.212-.312-.012-.537-.212ZM12 12Z'
  moon ='M12 21q-3.75 0-6.375-2.625T3 12q0-3.75 2.625-6.375T12 3q.2 0 .425.013 .225.013 .575.038-.9.8-1.4 1.975-.5 1.175-.5 2.475 0 2.25 1.575 3.825Q14.25 12.9 16.5 12.9q1.3 0 2.475-.463T20.95 11.15q.025.3 .038.488Q21 11.825 21 12q0 3.75-2.625 6.375T12 21Zm0-1.5q2.725 0 4.75-1.687t2.525-3.963q-.625.275-1.337.412Q17.225 14.4 16.5 14.4q-2.875 0-4.887-2.013T9.6 7.5q0-.6.125-1.287.125-.687.45-1.562-2.45.675-4.062 2.738Q4.5 9.45 4.5 12q0 3.125 2.188 5.313T12 19.5Zm-.1-7.425Z'

  ngAfterViewInit() {
    if (this.element){
      this.element.nativeElement.querySelector('.mdc-switch__icon--on').firstChild.setAttribute('d', this.moon);
      this.element.nativeElement.querySelector('.mdc-switch__icon--off').firstChild.setAttribute('d', this.sun);
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

工作示例:https://stackblitz.com/edit/angular-3fkfgv ?file=src%2Fapp%2Fslide-toggle-overview-example.ts


材质 < 15(使用 mat-icon)

在此输入图像描述

html

<mat-slide-toggle
  #darkModeSwitch
  (change)="changeTheme()"
  [checked]="checked"
  [disabled]="disabled">
</mat-slide-toggle>
Run Code Online (Sandbox Code Playgroud)

ts

import {AfterViewInit, Component, ElementRef, Renderer2, ViewChild} from '@angular/core';

@Component({
  selector: 'slide-toggle-overview-example',
  templateUrl: 'slide-toggle-overview-example.html',
  styleUrls: ['slide-toggle-overview-example.css'],
})
export class SlideToggleOverviewExample implements AfterViewInit {
  constructor(private renderer: Renderer2) {}

  @ViewChild('darkModeSwitch', { read: ElementRef }) element: ElementRef | undefined;

  checked = false;
  disabled = false;

  ngAfterViewInit() {
    this.setIcon();
  }

  setIcon() {
    if (this.element) {
      const targetSpan: HTMLElement = this.element.nativeElement.querySelector('.mat-slide-toggle-thumb');
      while (targetSpan.firstChild) {
        targetSpan.firstChild.remove();
      }
      const elem = this.renderer.createElement('mat-icon');
      const icon = this.checked ? 'dark_mode' : 'light_mode';
      elem.setAttribute('class', 'mat-icon notranslate material-icons mat-icon-no-color light-mode-switch-icon');
      elem.textContent = icon
      targetSpan.appendChild(elem);
    }
  }

  changeTheme() {
    this.checked = !this.checked;
    console.log('I am now ', this.checked);
    this.setIcon();
  }
}
Run Code Online (Sandbox Code Playgroud)

示例:https://stackblitz.com/edit/angular-nnj29e ?file=app%2Fslide-toggle-overview-example.ts


pc_*_*der 5

演示在项目中导入 fontawesome 后,在 style.css 中执行此操作

.mat-slide-toggle.mat-checked:not(.mat-disabled) .mat-slide-toggle-thumb:before { 
    content: "\f00c";
    font: normal normal normal 14px/1 FontAwesome;
}
Run Code Online (Sandbox Code Playgroud)