【问题标题】:Show alert on Browser Back Button event on react js在反应js上的浏览器后退按钮事件上显示警报
【发布时间】:2019-09-21 19:22:06
【问题描述】:

我必须在 React js 上的浏览​​器返回事件上显示警报。我曾尝试使用addEventListener,但我不确定将代码放在 React 页面的什么位置。我应该放置在任何生命周期钩子中还是在渲染中?我不知道。请帮帮我。

【问题讨论】:

  • 我想用 React JS 来做。
  • 没错。你只需要适应它。这些示例只是为您提供事件侦听器名称
  • 例如,我有一个名为payment.js 的页面,它呈现付款页面视图。因此,当用户尝试单击该页面上的浏览器后退按钮时,我可以显示写在 payment.js 本身上的警报吗?

标签: reactjs


【解决方案1】:

你可以试试这个,

window.addEventListener('popstate', (event) => {
  alert("You message");
});

您可以根据需要将其放置在componentWillMount()componentDidMount()中。

Ref

【讨论】:

  • 我会尝试,但我还有一个问题。浏览器返回事件是否会调用 componeneWillMount()componentDidMount() 挂钩?
  • @AshokRRaghu 当您点击浏览器的返回按钮时,您的组件将简单地重新渲染,因此这些方法将得到执行。
  • 我用过,但它只在页面加载时显示,而不是在浏览器后退按钮点击时显示。
  • 例如,我有一个名为payment.js 的页面,它呈现付款页面视图。因此,当用户尝试单击该页面上的浏览器后退按钮时,我可以显示写在 payment.js 本身上的警报吗?
【解决方案2】:

查看此链接How to Detect Browser Back Button event - Cross Browser

那里的关键点:

document.onmouseover = function() {
    //User's mouse is inside the page.
    window.innerDocClick = true;
}

document.onmouseleave = function() {
    //User's mouse has left the page.
    window.innerDocClick = false;
}

window.onhashchange = function() {
    if (window.innerDocClick) {
        //Your own in-page mechanism triggered the hash change
    } else {
        //Browser back button was clicked
    }
}

这可以防止后退空间被用于向后导航

 $(function(){
        /*
         * this swallows backspace keys on any non-input element.
         * stops backspace -> back
         */
        var rx = /INPUT|SELECT|TEXTAREA/i;

        $(document).bind("keydown keypress", function(e){
            if( e.which == 8 ){ // 8 == backspace
                if(!rx.test(e.target.tagName) || e.target.disabled || e.target.readOnly ){
                    e.preventDefault();
                }
            }
        });
    });

【讨论】:

    【解决方案3】:

    最后,我自己解决了。我已经用下面的代码给出了解释:

    首先,在componentDidUpdatecomponentWillMount 钩子中添加以下代码:

    window.history.pushState({name: "browserBack"}, "on browser back click", window.location.href);
    window.history.pushState({name: "browserBack"}, "on browser back click", window.location.href);
    

    我推送两次的原因是只有推送两次才会更新状态。这是Ref。上面的代码会在页面加载的历史中推送当前页面的URL。

    因此,当点击后退浏览器按钮时,将再次重新加载同一页面,因为历史记录已被 pushState 方法操纵。

    然后在pushState方法上方添加如下代码:

    window.addEventListener('popstate', (event) => {
      if (event.state) {
        //do your code here
      }
     }, false);
    

    现在,当点击浏览器后退按钮时,上面的监听器将被调用,并且由于我们更新了state 其中pushState 方法,if 将是真的,你可以做任何你想做的事。

    【讨论】:

    • 它只在第一次工作。之后导航回来
    【解决方案4】:

    我尝试了很多解决方案,但在我的情况下都没有工作,在我找到这个之后

    componentDidMount() {
            window.addEventListener("beforeunload", this._confirm);
            window.history.pushState(null, "", window.location.href);
            window.onpopstate = this._backConfirm;
        }
    
        componentWillUnmount() {
            window.removeEventListener("beforeunload", this._confirm);
            window.onpopstate = () => { }
        }
    
        _backConfirm = async () => {
            let event = window.confirm("Changes that you may not be saved.");
            if(event){
                window.history.pushState(null, "", window.location.href);
            }
        }
    
        _confirm = (e) => {
            var confirmationMessage = "\o/";
            e.returnValue = confirmationMessage;
            return confirmationMessage;
        }

    【讨论】:

      【解决方案5】:

      我找到了这个解决方案,它对我来说很好。

      constructor(props) {
          super(props);
          this.state = {
              onClickBackButton: false
          };
      }
      componentDidMount() {
         window.history.pushState(null, null, window.location.pathname);
         window.addEventListener('popstate', this.onClickBackButton);
      }
      
      onBackButtonEvent = (e) => {
          e.preventDefault();
          if (!this.onClickBackButton) {
      
              if (window.confirm("Do you want to go back without submitting details?")) {
                  this.onClickBackButton= true;
                  // your custom logic to page transition,like react-router-dom 
                  history.push()
              } else {
                  window.history.pushState(null, null, window.location.pathname);
                  this.onClickBackButton= false;
              }
          }
      }
      
      componentWillUnmount = () => {
          window.removeEventListener('popstate', this.onClickBackButton);
      }
      

      Ref

      【讨论】:

        【解决方案6】:

        如果你使用 react 钩子,你可以使用 useEffect 钩子在接下来的步骤中进行操作

        import React, { useState, useEffect } from "react";
        
        const [finishStatus, setfinishStatus] = useState(false);
        
        const onBackButtonEvent = (e) => {
            e.preventDefault();
            if (!finishStatus) {
                if (window.confirm("Do you want to go back ?")) {
                    setfinishStatus(true)
                    // your logic
                    props.history.push("/");
                } else {
                    window.history.pushState(null, null, window.location.pathname);
                    setfinishStatus(false)
                }
            }
        }
        
          useEffect(() => {
            window.history.pushState(null, null, window.location.pathname);
            window.addEventListener('popstate', onBackButtonEvent);
            return () => {
              window.removeEventListener('popstate', onBackButtonEvent);  
            };
          }, []);

        【讨论】:

          猜你喜欢
          • 2020-02-12
          • 2018-06-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-10-27
          • 2020-02-16
          • 2022-11-22
          相关资源
          最近更新 更多