【发布时间】:2016-07-21 07:29:08
【问题描述】:
我正在使用 Angular 2 开发一个网站。 有没有办法使用 Angular 2 禁用或触发浏览器后退按钮?
谢谢
【问题讨论】:
-
window.history.back()?
标签: javascript angular back-button
我正在使用 Angular 2 开发一个网站。 有没有办法使用 Angular 2 禁用或触发浏览器后退按钮?
谢谢
【问题讨论】:
window.history.back() ?
标签: javascript angular back-button
我在所有主要浏览器中使用和工作的代码段!
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();
}
【讨论】:
这很简单,使用以下代码,此示例代码来自普通的 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 并从那里调用它
【讨论】:
尝试使用这个
window.onpopstate = function (e) { window.history.forward(1); }
【讨论】:
如果您希望禁用 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]
【讨论】:
我已经尝试了上面提到的所有解决方案,但没有一个适合我。经过两天的失败尝试,我终于找到了这个 npm 模块,它可以立即完美地工作。
Github:https://github.com/Zatikyan/angular-disable-browser-back-button#readme
【讨论】:
在组件的 TS 文件中添加以下代码,您不想返回。
@HostListener('window:hashchange', ['$event'])
hashChangeHandler(e) {
window.location.hash = "dontgoback";
}
【讨论】:
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% 工作正常
【讨论】:
这个问题出现在 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;
}
}
}
【讨论】:
也许有点晚,但也许有人可以使用它。 这是我用于带有选项卡(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
【讨论】:
第 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);
}
}
【讨论】:
不确定这是否已经排序,但仍然发布答案,以供将来参考。 为了解决这个问题,您基本上需要在您的应用程序组件中添加一个侦听器并在您的角度路由器上设置一个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() 这个方法的定义/实现是什么?
如果您想阻止到达某个路由,您可以将 @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
【讨论】:
试试这个
<script type = "text/javascript" >
history.pushState(null, null, 'pagename');
window.addEventListener('popstate', function(event) {
history.pushState(null, null, 'pagename');
});
</script>
将'pagename'更改为您的页面名称并将其放入页面的头部。
【讨论】:
这不是 Angular2 相关的问题。您可以将用户发送回历史记录。具体见Manipulating the browser history、history.go()方法:
window.history.go(-1);
但是,我认为没有办法取消或禁用在浏览器窗口中按下后退按钮时的默认浏览器操作,因为这很容易被滥用。
您也可以在用户尝试离开页面时显示一个对话窗口:javascript before leaving the page
【讨论】: