如何在 Angular 中禁用或覆盖 cdk-focused

Posted

技术标签:

【中文标题】如何在 Angular 中禁用或覆盖 cdk-focused【英文标题】:How to disable or overwrite cdk-focused in Angular 【发布时间】:2018-08-03 20:54:25 【问题描述】:

我正在研究 mat-button-toggle-group,我通过覆盖 mat-button-toggle-checked 类来修改现有的 css,如下所示。现在,当我在按钮之间切换时,css 在我获得焦点之前无法工作,那是因为当单击的按钮处于焦点时添加了 2 个 cdk 类 'cdk-focused' 和 'cdk-program-focused' 。有什么方法可以使这些类禁用或使它们不应用或用相同的 mat-button-toggle-checked 覆盖它们?

<mat-button-toggle-group #group="matButtonToggleGroup" value="line">
    <mat-button-toggle (click)="showLine()" value="line">Line</mat-button-toggle>
    <mat-button-toggle (click)="showChart()" value="chart">Chart</mat-button-toggle>
</mat-button-toggle-group>

和css

mat-button-toggle-group 
    border: solid 1px #d1d8de;
    width:260px;
    height:41px;
    text-align: center;
    .mat-button-toggle-checked
      background-color: #ffffff;
      font-weight: bold;
    
    .mat-button-toggle
      width:50%;
      font-size: 15px;
    
  

【问题讨论】:

你摆脱了cdk-focusedcdk-program-focused 类吗? 我的情况是一个垫子按钮打开垫子对话框时,对话框关闭时仍然有焦点。我通过在对话框关闭后自动调用按钮上的模糊来解决它 - github.com/angular/components/issues/… 【参考方案1】:

最干净的解决方案是删除 box-shadow:

.mat-raised-button, .mat-flat-button 
  background-color: #4bcd3e;
  color: #ffffff;
  border-color: #4bcd3e;
  box-shadow: none;


.mat-raised-button:not([disabled]).cdk-keyboard-focused,
.mat-raised-button:not([disabled]).cdk-program-focused 
  background-color: #41b336;
  border-color: #41b336;
  color: #ffffff;
  box-shadow: none;

【讨论】:

【参考方案2】:

对于 mat-radio-button 作品:

.mat-radio-button .mat-radio-ripple 
  height: 0px !important;
  width: 0px !important;

【讨论】:

【参考方案3】:

你可以的 如果你使用 sass:

::host 
  &::ng-deep 
    .cdk-program-focused 
      background-color: transparent !important;
    
  

【讨论】:

【参考方案4】:

对于以 cdk 为重点的类作为问题的基础,请使用:

.cdk-focused, .cdk-mouse-focused 
  outline: 0 !important;

【讨论】:

【参考方案5】:

摆脱由 cdk-focused、cdk-program-focused、cdk-mouse-focused 和 cdk-touch-focused 创建的轮廓的最简单方法是添加

button:focus  outline: none; 

在您的 styles.css 文件中

之前

之后

【讨论】:

【参考方案6】:

如果按钮包含在父 mat 元素中,则可以使用 autoFocus @input 某些元素的属性来禁用自动对焦。 例如,mat dialog 或 mat sidenav 有。

【讨论】:

【参考方案7】:

我用cdk-focused!important的类css选择器解决了这个问题:

.cdk-focused 
  background-color: transparent!important;

【讨论】:

【参考方案8】:

在我的例子中,真正的问题在于按钮结构,“材质”构建各种子组件,最后一个是带有 CSS 类“mat-button-focus-overlay”的“div”:

我的解决方案很简单,在'style.css'文件中,添加或订阅'mat-button-focus-overlay'

.mat-button-focus-overlay  
background-color: transparent!important; 

【讨论】:

我了解到最好的做法是避免 !important 覆盖样式。这通常意味着进口可以做得更好。【参考方案9】:

最简单的“禁用”只是将以下css覆盖添加到您的组件中。

:host 
  /deep/ .mat-button-toggle-focus-overlay 
    display: none;    
  

【讨论】:

【参考方案10】:

懒人的 CSS 方法:

.your-elements-class-name:focus 
  outline: 0px solid transparent;

【讨论】:

【参考方案11】:

你可以使用Angular CDK's FocusMonitor service通过调用服务的stopMonitoring()方法来禁用.cdk-focused.cdk-program-focused类。

可以在以下链接中分别找到此和 API 的文档: 1)FocusMonitor documentation& 2)FocusMonitor API

我遇到的问题:

我的sidenav 有 4 个使用 *ngFor 创建的按钮。这些按钮中的每一个也是routerLink。只有路由器链接处于活动状态的按钮才应具有主背景颜色。

现在,如果与我的第 4 个按钮关联的 routerLink 处于活动状态,因为第 4 个按钮将具有 primary background color 而第一个按钮具有 focused styling,因为 .cdk-focused.cdk-program-focused 类,这会变得令人困惑由按钮上的FocusMonitor 应用。

解决办法:

import  Component, AfterViewInit  from '@angular/core';
import  FocusMonitor  from '@angular/cdk/a11y';

@Component(
    selector   : 'test-component',
    templateUrl: 'test-component.template.html',
)

export class TestComponent implements AfterViewInit 
    constructor(private _focusMonitor: FocusMonitor) 

    ngAfterViewInit() 
        this._focusMonitor.stopMonitoring(document.getElementById('navButton_1'));
    

您可以查看文档以根据您的需要进行定制。

【讨论】:

优秀的答案,正如你所说,我已经以编程方式移除焦点?【参考方案12】:

我在使用侧导航组件时遇到了同样的问题。

在阅读了Aravind在这里How to use EventEmitter(onClose) of the sidenav提供的解决方案后,我决定调用以下方法:

onSideNavOpened() 
    let buttonsList = document.getElementsByClassName('mat-button');

    for(let currentButton of buttonsList) 
      currentButton.classList.remove("cdk-focused");
      currentButton.classList.remove("cdk-program-focused");
    
  

也许你可以在你的 ngOnInit() 方法中或多或少地做同样的事情?

(为了记录,我的打开侧导航标签如下所示: &lt;mat-sidenav #snav class="menu-sidenav" mode="over" position="end" opened="false" (open)="onSideNavOpened()"&gt;)

【讨论】:

【参考方案13】:

向下滚动到粗体文本以获取答案。

在更改元素的样式时,最好不要按元素引用,而是按类引用。 例如,而不是使用:

mat-button-toggle-group 
    border: solid 1px #d1d8de;

你会写

.mat-button-toggle-group 
    border: solid 1px #d1d8de;

再说一遍,这只是一个好习惯。

另一件重要的事情(不是双关语)是要指出的是,您应该避免使用!important。一般来说,这应该保留用于特殊的边缘情况(如打印)。这是因为它会导致更难维护样式表。一个很好的例子就是想改变这个的边界:

.mat-button-toggle-group 
    border: solid 1px #d1d8de !important;

因为覆盖!important 的唯一方法是使用另一个!important

您的答案的可能解决方案

有一个 material-theme-overrides.scss 文件,它基本上覆盖了类的样式。当您希望所有类默认以这种方式运行时,此方法是理想的。就像您希望所有 .mat 按钮都具有半径一样。材料提供了一个很好的指导: https://material.angular.io/guide/theming

另一种选择 使用::ng-deep 这允许您将样式强制到子组件。在此处阅读更多信息:

How and Where to use ::ng-deep?

【讨论】:

谢谢唐。正如你提到的,我已经有一个自定义主题类。但是,这些是 cdk 类 完美!你可以用同样的方法覆盖它们。你可以去那里的主题文件查看材料是如何做到的。那在你的 node_modules/@angular/material/_theming.scss【参考方案14】:

您是否尝试将!important 添加到选择器的属性中:

mat-button-toggle-group 
    border: solid 1px #d1d8de !important;
    width:260px !important;
    height:41px !important;
    text-align: center !important;
    .mat-button-toggle-checked
      background-color: #ffffff !important;
      font-weight: bold !important;
    
    .mat-button-toggle
      width:50% !important;
      font-size: 15px !important;
    
  

这样,您将覆盖 cdk-focusedcdk-program-focused 类。

【讨论】:

是的,我做到了,我的问题是我的 css 正在工作,但是当单击切换按钮时添加了 2 个新的 CDK 类,直到它专注于它'cdk-focused' 和 'cdk-以程序为中心'是类..一旦焦点消失,我的 css 就会被应用。请让我知道是否有办法覆盖 cdk 类

以上是关于如何在 Angular 中禁用或覆盖 cdk-focused的主要内容,如果未能解决你的问题,请参考以下文章

如何在角度5中禁用或覆盖cdk-focused

如何在Angular 2中禁用浏览器后退按钮

如何在 IntelliJ 中禁用装订线“覆盖”图标?

默认情况下如何禁用或覆盖网页中从svg继承的字体

如何在 Angular 小吃店中禁用背景?

在 Sublime Text 2 中禁用或覆盖 JSLint 选项