当前位置: 首页 > wzjs >正文

做视频好用的素材网站网址

做视频好用的素材网站,网址,网站副标题怎么修改,企业网站建设模板在 Angular 应用开发中,实现用户点击按钮后,原地切换显示一个输入框并自动获取焦点的功能,是一个常见的交互模式。例如,搜索图标点击后变为搜索框,用户可以直接输入。然而,由于 Angular 的变更检测和 DOM 更…

在 Angular 应用开发中,实现用户点击按钮后,原地切换显示一个输入框并自动获取焦点的功能,是一个常见的交互模式。例如,搜索图标点击后变为搜索框,用户可以直接输入。然而,由于 Angular 的变更检测和 DOM 更新机制的异步性,直接在改变显示状态后立即调用元素的 focus() 方法,往往会因为元素尚未完全渲染或准备就绪而失败。

本文将探讨这一问题,并介绍如何利用 ChangeDetectorRef 来更同步地更新视图,从而实现对动态出现元素的精确聚焦。

问题再现:按钮到输入框的切换与聚焦

考虑以下 Angular 模板结构:

<main class="columns-content-area" *ngIf="DictManagerStack.empty() || DictManagerStack.exists('EntriesManagement')"><div class="columns-content-header"><h1 class="columns-content-title">{{ 'EntriesManagement' | translate }}</h1><button style="margin-left: auto; margin-right: 0.5rem;" *ngIf="!isClickGlassInDictManager"(click)="onDictManagerButtonClick('SearchButton', 'search')"class="normal-toolbar-button"><i class="fa-solid fa-magnifying-glass"></i></button><input #searchInput *ngIf="isClickGlassInDictManager" style="margin-left: auto; margin-right: 0.5rem; border: 1px solid #ccc; border-radius: 4px; padding: 1px;"(keyup.enter)="onDictManagerButtonClick('SearchButton', 'EnterSearch')" type="text"(keyup.esc)="onDictManagerButtonClick('SearchButton', 'cancelSearch')"(focusout)="isClickGlassInDictManager = false"[(ngModel)]="searchWordInDictManager" placeholder="搜索"/></div><p class="columns-content-description">{{ 'EntriesManagementDescription' | translate }}</p></main>

我们希望当点击搜索按钮时,isClickGlassInDictManager 变量变为 true,导致按钮隐藏,输入框显示。同时,我们希望新出现的输入框立即获得焦点。

一个直观的想法可能是在处理按钮点击的方法中直接改变变量并调用聚焦:

import { Component, ViewChild, ElementRef } from '@angular/core';// ... other imports@Component({ /* ... */ })
export class YourComponent {isClickGlassInDictManager = false;// 使用 @ViewChild 获取输入框的引用@ViewChild('searchInput') searchInputElement!: ElementRef;onDictManagerButtonClick(itemType: 'SearchButton' | 'EntriesManagementContent', item: any) {if (itemType === 'SearchButton') {this.isClickGlassInDictManager = !this.isClickGlassInDictManager;// 问题所在:此时输入框可能还未完全呈现在 DOM 中或未准备好if (this.isClickGlassInDictManager && this.searchInputElement) {const searchInput = this.searchInputElement.nativeElement as HTMLInputElement;searchInput.focus(); // 可能失败}}}
}

之所以会失败,是因为 Angular 的变更检测通常不会在你的事件处理函数执行的 同一刻 立即更新 DOM。当 isClickGlassInDictManager 的值改变时,Angular 会安排一次视图更新,但这个更新过程可能发生在当前 JavaScript 任务完成之后。因此,在 focus() 被调用时,@ViewChild('searchInput') 对应的元素可能还不存在于 DOM 中,或者虽然存在,但浏览器还没有完成其布局和渲染,导致 focus() 方法没有效果。

解决方案:手动触发变更检测 cdr.detectChanges()

为了解决这个问题,我们可以利用 Angular 提供的 ChangeDetectorRef 服务来手动触发一次变更检测,强制 Angular 立即更新视图,从而确保输入框在调用 focus() 之前已经出现在 DOM 中。

以下是使用 ChangeDetectorRef 的解决方案:

import { Component, ViewChild, ElementRef, ChangeDetectorRef } from '@angular/core';// ... other imports@Component({ /* ... */ })
export class YourComponent {isClickGlassInDictManager = false;@ViewChild('searchInput') searchInputElement!: ElementRef;constructor(private cdr: ChangeDetectorRef) {} // 注入 ChangeDetectorRefonDictManagerButtonClick(itemType: 'SearchButton' | 'EntriesManagementContent', item: any) {if (itemType === 'SearchButton') {// 1. 改变状态,隐藏按钮,准备显示输入框this.isClickGlassInDictManager = !this.isClickGlassInDictManager;// 2. 手动触发变更检测// 这会强制 Angular 立即根据 isClickGlassInDictManager 的新值更新 DOMthis.cdr.detectChanges();// 3. 在 DOM 更新后,尝试聚焦输入框// 此时,由于 detectChanges() 已经执行,@ViewChild 应该已经获取到新创建的元素引用if (this.isClickGlassInDictManager && this.searchInputElement) {const searchInput = this.searchInputElement.nativeElement as HTMLInputElement;searchInput.focus(); // 现在聚焦操作应该能够成功}}}
}

方案解释

  1. this.isClickGlassInDictManager = !this.isClickGlassInDictManager;: 这一步改变组件状态,指示输入框应该显示(如果之前是隐藏的)。
  2. this.cdr.detectChanges();: 这是关键步骤。它告诉 Angular 立即执行一次变更检测。Angular 会检查所有绑定,发现 isClickGlassInDictManager 的变化,并根据 *ngIf="isClickGlassInDictManager" 的条件,同步地在 DOM 中创建并插入搜索输入框元素。
  3. if (this.isClickGlassInDictManager && this.searchInputElement): 在 detectChanges() 执行后,@ViewChild('searchInput') 应该已经成功获取到了新创建的输入框元素的引用。这个条件确保只有当输入框确实应该显示且引用可用时,才执行聚焦操作。
  4. searchInput.focus();: 由于 detectChanges() 已经保证了输入框元素的存在,这里的 focus() 调用现在能够成功地作用于实际的 DOM 元素,使其获得焦点。

通过 cdr.detectChanges(),我们将原本可能稍后发生的 DOM 更新提前到当前方法的执行流程中,从而解决了状态改变与 DOM 准备好进行交互之间的时序不同步问题。

总结

利用 ChangeDetectorRefdetectChanges() 方法,我们可以强制 Angular 立即更新视图,确保目标元素在 DOM 中存在且可供操作,从而实现对动态出现元素的精确控制,例如自动聚焦。


文章转载自:

http://aNOHs8jT.yxmgq.cn
http://Uc3CUTX2.yxmgq.cn
http://HHy4HCoY.yxmgq.cn
http://HUUc48bH.yxmgq.cn
http://Rq3GmSiS.yxmgq.cn
http://skEynR3J.yxmgq.cn
http://mBtBwjKz.yxmgq.cn
http://KqlATWrA.yxmgq.cn
http://rJ44mKGJ.yxmgq.cn
http://fkkwsw6Q.yxmgq.cn
http://NKsZ9Q1A.yxmgq.cn
http://KoZnMCu4.yxmgq.cn
http://oDXbuKwP.yxmgq.cn
http://V40ey7wK.yxmgq.cn
http://cZZQs6iA.yxmgq.cn
http://rViBNfWq.yxmgq.cn
http://gpxxdqfY.yxmgq.cn
http://G0oVZCS7.yxmgq.cn
http://mHGLq51A.yxmgq.cn
http://3EzIwMWd.yxmgq.cn
http://zLB7EIQL.yxmgq.cn
http://G2l0x2oZ.yxmgq.cn
http://p7hqqpCv.yxmgq.cn
http://uaoyZn46.yxmgq.cn
http://UplZXZnb.yxmgq.cn
http://gWEtceZB.yxmgq.cn
http://mSyCeqEV.yxmgq.cn
http://4f46VRYz.yxmgq.cn
http://XogarpLz.yxmgq.cn
http://YHK7qfCV.yxmgq.cn
http://www.dtcms.com/wzjs/733341.html

相关文章:

  • 北京通网站建设价格低郴州发布网
  • 高青外贸公司网站建设响水专业做网站的公司
  • iis wordpress伪静态信息流优化师是什么
  • 网站手机微信三合一怎么做门户网站推广介绍方案
  • 常州网站建设哪儿好薇wordpress内容分页
  • 江西网站做的好的企业文化江北网站制作
  • 网站被电脑管家拦截做301跳转汕头网站建设方案优化
  • 网站建设分金手指专业七室内设计效果图分析
  • 广西建设网站首页flash打开网站源码
  • 单页网站制作 在线 支付中小网站建设都有哪些方案
  • 房产中介网站建设技巧怎么样推广网站
  • 高端网站建设 企业网站建站别人的wordpress打开很快
  • 搜索网站排行榜手袋 东莞网站建设
  • 六安网络推广哪家好东莞网站关键词优化排名
  • 医疗器械网站素材南京短视频制作公司
  • wordpress网站的配置文件辽宁住房和城乡建设部网站
  • 怎么自己建立公司网站怎么建自己的公众号
  • 三合一建站网站手机网站如何站点管理
  • 网上商城网站开发需求说明书大型企业网站制作
  • 网站建设成本费用汝南企业网站建设
  • 营销型网站方案ppt个人网页首页内容
  • 福州智能建站长春网站建设公司哪个好
  • wordpress网站邀请码做网站做什么主题
  • 如何制作自己的个人网站新图闻的品牌建设经验
  • 回收网站怎么做e脉通网站
  • 洛阳网站建设培训学校遵义网站建设方案
  • 广东网站设计与建设做网站十大公司哪家好
  • 做网站语言wordpress logo在哪里改
  • 高端个性化网站建设wordpress 仿小米主题下载
  • 网站空间 默认文档淘宝客的网站怎么做