【问题标题】:How to disable Browser back button in Angular 2如何在Angular 2中禁用浏览器后退按钮
【发布时间】:2016-07-21 07:29:08
【问题描述】:

我正在使用 Angular 2 开发一个网站。 有没有办法使用 Angular 2 禁用或触发浏览器后退按钮?

谢谢

【问题讨论】:

标签: javascript angular back-button


【解决方案1】:

我在所有主要浏览器中使用和工作的代码段!

ngOnInit() {
   history.pushState(null, null, location.href);

   this.subscription = fromEvent(window, 'popstate').subscribe(_ => {
      history.pushState(null, null, location.href);
      this.openModal(`You can't make changes or go back at this time.`, 'Okay');
   });
}

ngOnDestroy() {
   this.subscription.unsubscribe();
}

【讨论】:

    【解决方案2】:

    这很简单,使用以下代码,此示例代码来自普通的 javascript,我已将其转换为 angular,并在我的 2-3 个项目中使用

    // Inject LocationStrategy Service into your component
        constructor(
            private locationStrategy: LocationStrategy
          ) { }
    
    
    // Define a function to handle back button and use anywhere
        preventBackButton() {
            history.pushState(null, null, location.href);
            this.locationStrategy.onPopState(() => {
              history.pushState(null, null, location.href);
            })
          }
    

    您也可以在任何服务中定义 preventBackButton 并从那里调用它

    【讨论】:

    • 这会在 Safari 上导致很多错误:“每 30.000000 秒尝试使用 history.pushState() 超过 100 次”
    • 可能有一些代码在重复运行。我不确定确切的原因是什么。您能否在此处粘贴导致此错误的代码或错误的一些屏幕截图。
    【解决方案3】:

    尝试使用这个

    window.onpopstate = function (e) { window.history.forward(1); }
    

    【讨论】:

    【解决方案4】:

    如果您希望禁用 angular(7/8/9/10) 中的浏览器后退按钮...试试这个链接并使用 npm 安装包。

    1) npm install --save angular-disable-browser-back-button
    2) import { NgModule } from '@angular/core';
    import { BackButtonDisableModule } from 'angular-disable-browser-back-button';
     
    @NgModule({
      ...
      imports: [
        ...
        BackButtonDisableModule.forRoot()
      ],
      ...
    })
    export class AppModule {}
    
    3)  BackButtonDisableModule.forRoot({
          preserveScrollPosition: true
        })
    

    请使用下面给出的这个链接。参考取自。

    [https://www.npmjs.com/package/angular-disable-browser-back-button][1]

    【讨论】:

      【解决方案5】:

      我已经尝试了上面提到的所有解决方案,但没有一个适合我。经过两天的失败尝试,我终于找到了这个 npm 模块,它可以立即完美地工作。

      Github:https://github.com/Zatikyan/angular-disable-browser-back-button#readme

      【讨论】:

        【解决方案6】:

        在组件的 TS 文件中添加以下代码,您不想返回。

          @HostListener('window:hashchange', ['$event'])
          hashChangeHandler(e) {
            window.location.hash = "dontgoback";
          }
        

        【讨论】:

          【解决方案7】:
          import { LocationStrategy } from '@angular/common';
          constructor( private location: LocationStrategy){  
          // preventing back button in browser implemented by "Samba Siva"  
           history.pushState(null, null, window.location.href);  
          this.location.onPopState(() => {
            history.pushState(null, null, window.location.href);
          });  
          }
          

          它在 angular2/4/5 中对我 100% 工作正常

          【讨论】:

          • 即使在 Angular 11 中也能工作(仅在 chrome 中测试)
          • 不,它在 Angular 11 中对我不起作用,它说,“'null' 类型的参数不能分配给 'string' 类型的参数”
          • @Satrughna 你可以试试这个,它对我来说很好用:history.pushState(null, "null", window.location.href);
          【解决方案8】:

          这个问题出现在 IE 浏览器上。使用下面提到的代码它将解决您的问题。

          
                  @HostListener('document:keydown', ['$event'])
                    onKeyDown(evt: KeyboardEvent) {
                      if (
                          evt.keyCode === 8 || evt.which === 8
                      ) {
                        let doPrevent = true;
                        const types =['text','password','file','search','email','number','date','color','datetime','datetime-local','month','range','search','tel','time','url','week'];
                        const target = (<HTMLInputElement>evt.target);
          
                    const disabled = target.disabled || (<HTMLInputElement>event.target).readOnly;
                    if (!disabled) {
                      if (target.isContentEditable) {
                        doPrevent = false;
                      } else if (target.nodeName === 'INPUT') {
                        let type = target.type;
                        if (type) {
                          type = type.toLowerCase();
                        }
                        if (types.indexOf(type) > -1) {
                          doPrevent = false;
                        }
                      } else if (target.nodeName === 'TEXTAREA') {
                        doPrevent = false;
                      }
                    }
          
          
                  if (doPrevent) {
                      evt.preventDefault();
                      return false;
                    }
          
                  }
              }
          
          

          【讨论】:

            【解决方案9】:

            也许有点晚,但也许有人可以使用它。 这是我用于带有选项卡(Bootstrap 4 样式)的页面的解决方案,其中每个选项卡都是一个组件。

                @Injectable()
                export class CanNavigateService {
            
                  private static _isPermissionGranted = true
                  public navigationAttempt = new Subject<boolean>()
            
                  //-------------------------------------------------------------//
            
                  /**Will the next navigation attempt be permitted? */
                  updatePermission(isPermissionGranted: boolean) {   
                    CanNavigateService._isPermissionGranted = isPermissionGranted
                  }//updatePermission
            
                  //-------------------------------------------------------------//
            
                  /**Broadcast the last attempt and whether it was permitted */
                  updateNavigationAttempt(wasPermissionGranted: boolean) {    
                    this.navigationAttempt.next(wasPermissionGranted)
                  }//updatePermission
            
                  //-------------------------------------------------------------//
            
                  /**Can we navigate? */
                  public isPermissionGranted(): boolean {
                    return CanNavigateService._isPermissionGranted
                  }//isPermissionGranted
            
                }//Cls
            

            NavigationGuard 类似于上面的@Jithin Nair,但也会广播何时尝试导航以及是否允许。 CanNavigateService 的订阅者可以使用它来决定做什么而不是返回导航。

            @Injectable()
            export class NavigationGuard implements CanDeactivate<any> {
            
            constructor(private canNavigateService: CanNavigateService) { }
            
            //--------------------------------------------------------------------//
            
            // will prevent user from going back if permission has not been granted
            canDeactivate(component: any) {
            
                let permitted = this.canNavigateService.isPermissionGranted()
                this.canNavigateService.updateNavigationAttempt(permitted)        
            
                if (!permitted) {
                    // push current state again to prevent further attempts.
                    history.pushState(null, null, location.href)
                    return false
                }
            
                return true
            
            }//canDeactivate
            
            }//Cls
            

            用法:

            constructor(private _navigateService: CanNavigateService) {
                super()
            
                _navigateService.navigationAttempt.subscribe(wasPermitted => {
                    //If navigation was prevented then just go to first tab
                    if (!wasPermitted)
                       this.onTabSelected( this._firstTab)            
                })
            }//ctor
            
            //----------------------------------------------------------------------------//
            
            onTabSelected(tab) {
            
                this._selectedTab = tab
                //If it's not the first tab you can't back navigate
                this._navigateService.updatePermission(this._selectedTab == this._firstTab)
            }//onTabSelected
            

            【讨论】:

              【解决方案10】:

              第 1 步: 从 angular commmon 导入 Locatoion

              import {Location} from "@angular/common";
              

              第二步:在构造函数中初始化

              private location: Location
              

              步骤 3:在相应组件的 ngOnInit 中添加函数,

              this.location.subscribe(currentLocation => {
              if (currentLocation.url === '*/basic-info*') {
                  window.onpopstate = function (event) {
                      history.go(1);
                  }
              }
              

              });

              注意:这里 /basic-info 将被您的路径替换。

              如果第一次不起作用,请尝试添加外部订阅,

              let currentUrl = window.location.href;
              let tmpVar = currentUrl.includes('/basic-info');
              if (currentUrl.includes('/basic-info')) {
                window.onpopstate = function (event) {
                  history.go(1);
                }
              }
              

              【讨论】:

                【解决方案11】:

                不确定这是否已经排序,但仍然发布答案,以供将来参考。 为了解决这个问题,您基本上需要在您的应用程序组件中添加一个侦听器并在您的角度路由器上设置一个canDeactivate 保护。

                // in app.component.ts
                import { LocationStrategy } from '@angular/common';
                
                @Component({
                  selector: 'app-root'
                })
                export class AppComponent {
                  constructor(
                    private location: LocationStrategy
                  ) {
                    // check if back or forward button is pressed.
                    this.location.onPopState(() => {
                      // set isBackButtonClicked to true.
                      this.someNavigationService.setBackClicked(true);
                      return false;
                    });
                  }
                }
                
                // in navigation guard
                @Injectable()
                export class NavigationGuard implements CanDeactivate<any> {
                  constructor(private someNavigationService: SomeNavigationService) {}
                  canDeactivate(component: any) {
                    // will prevent user from going back
                    if (this.someNavigationService.getBackClicked()) {
                      this.someNavigationService.setBackClicked(false);
                      // push current state again to prevent further attempts.
                      history.pushState(null, null, location.href);
                      return false;
                    }
                    return true;
                  }
                }

                【讨论】:

                • this.someNavigationService.setBackClicked() 这个方法的定义/实现是什么?
                • @Vinod 该方法只是根据发送的参数将标志更新为真或假。该服务基本上带有一个用于告诉您是否单击后退按钮的标志的设置器和获取器。单击后退/前进按钮将其设置为 true,然后在处理后重置为 false。
                • @JithinNair 请也为 SomeNavigationService 编写代码。
                【解决方案12】:

                如果您想阻止到达某个路由,您可以将 @CanActivate() 装饰器添加到您的路由组件中

                @Component({selector: 'control-panel-cmp', template: `<div>Settings: ...</div>`})
                @CanActivate(checkIfWeHavePermission)
                class ControlPanelCmp {
                }
                

                另请参阅
                - Angular 2: Inject a dependency into @CanActivate? 用于访问全球服务。
                - Angular2 Router - Anyone know how to use canActivate in app.ts so that I can redirect to home page if not logged in

                【讨论】:

                  【解决方案13】:

                  试试这个

                  <script type = "text/javascript" >
                  history.pushState(null, null, 'pagename');
                  window.addEventListener('popstate', function(event) {
                  history.pushState(null, null, 'pagename');
                  });
                  </script>
                  

                  将'pagename'更改为您的页面名称并将其放入页面的头部。

                  【讨论】:

                    【解决方案14】:

                    这不是 Angular2 相关的问题。您可以将用户发送回历史记录。具体见Manipulating the browser historyhistory.go()方法:

                    window.history.go(-1);
                    

                    但是,我认为没有办法取消或禁用在浏览器窗口中按下后退按钮时的默认浏览器操作,因为这很容易被滥用。

                    您也可以在用户尝试离开页面时显示一个对话窗口:javascript before leaving the page

                    【讨论】:

                    • onbeforeunload 不会在 Angular 的后退按钮上触发。
                    猜你喜欢
                    • 2022-10-25
                    • 2011-08-06
                    • 1970-01-01
                    • 1970-01-01
                    • 2010-10-31
                    • 2014-04-17
                    • 1970-01-01
                    相关资源
                    最近更新 更多