Polymer 2.0中window.addEventListener监听浏览器返回点击失效求助
Hey there! Let's work through this issue with your Polymer 2.0 app. It sounds like your browser's back button is triggering an unintended logout, and your attempts to add a confirmation dialog via window.addEventListener aren't working—totally understandable, since Polymer's client-side routing can interfere with raw popstate listeners. Here's how to fix it properly:
First, Why Your Initial Attempt Might Be Failing
Polymer 2.0 typically uses components like app-location and app-route to handle routing, which already listen to the popstate event under the hood. If you add your own listener without accounting for Polymer's lifecycle or event order, it might be overridden, fire too late, or throw errors from incorrect this binding.
Solution 1: Properly Bind a Popstate Listener in Your Polymer Element
The key here is to hook into the element's lifecycle to add/remove the listener, and handle the history state correctly to avoid breaking Polymer's routing.
Here's a code example for your main app element:
class MyApp extends Polymer.Element { static get is() { return 'my-app'; } connectedCallback() { super.connectedCallback(); // Store the bound handler so we can clean it up later this._backButtonHandler = this._handleBackButton.bind(this); window.addEventListener('popstate', this._backButtonHandler); } disconnectedCallback() { super.disconnectedCallback(); // Always remove listeners to prevent memory leaks window.removeEventListener('popstate', this._backButtonHandler); } _handleBackButton(event) { // Stop Polymer's default routing behavior temporarily event.preventDefault(); // Show your confirmation dialog if (confirm('Are you sure you want to go back? This will log you out.')) { // If user confirms, proceed with logout and allow the back action this._performLogout(); history.go(-1); // Manually trigger the back navigation } else { // If user cancels, reset the history state to stay on the current page history.pushState(null, null, window.location.href); } } _performLogout() { // Insert your existing logout logic here console.log('User initiated logout via back button'); // Example: this.$.auth.signOut(); } } customElements.define(MyApp.is, MyApp);
Solution 2: Intercept Route Changes (If Using app-route)
If your logout is triggered by a route change (e.g., navigating to /logout when the back button is pressed), you can listen to Polymer's route events directly instead of raw popstate:
class MyApp extends Polymer.Element { static get is() { return 'my-app'; } static get properties() { return { route: Object, _previousRoutePath: String }; } static get observers() { return ['_onRouteChange(route.path)']; } _onRouteChange(newPath) { // Check if we're navigating to the logout route from another page if (newPath === '/logout' && this._previousRoutePath) { // Prevent the route change temporarily this.set('route.path', this._previousRoutePath); if (confirm('Are you sure you want to go back and log out?')) { this._performLogout(); } } // Track the last valid route this._previousRoutePath = newPath; } _performLogout() { // Your logout logic here } } customElements.define(MyApp.is, MyApp);
Key Tips to Avoid Issues
- Always clean up listeners: Remove event listeners in
disconnectedCallbackto prevent memory leaks in single-page apps. - Handle
thiscorrectly: Use.bind(this)or arrow functions to ensure your callback has access to the Polymer element's context. - Maintain history state: When you cancel a back action, use
history.pushStateto reset the browser's history stack so it doesn't get stuck in a loop.
内容的提问来源于stack exchange,提问作者Kapil Soni

