公司开发一个音频项目用的是vue 2.0 ,vue-router 2.0 。在实现返回的时候遇到了一个坑,下面讲讲。

一般的返回是直接使用this.$router.go(-1)或者使用window.history.back()

  如果当前是第一页
  往前已经没有历史记录,使用上面的方法就不能返回 或者 直接返回到了空白页,这时我们就需要进行判断当前页是不是第一页。

//验证是否存在记录
if (BHistory.isFirstHistory()) {
                        
     this.$router.push({name: 'index'});
                        
} else {
	        			
    this.$router.go(-1)
}
需求是如果是第一页的用户点击返回到项目首页index中。

遇到的难题是如何判断当前是否是第一页。网上提供了几下几种思路:

1)先尝试进行返回,如果没有成功再进行前后地址hash值的比较,再根据document.referrer,如果document.referer为空或者不是字符串就返回到首页。代码如下:

 var defaultLocation ="http://www.mysite.com";
    var oldHash = window.location.hash;
    history.back(); // Try to go back
    var newHash = window.location.hash;
    
    if( newHash === oldHash &&
        (typeof(document.referrer) !== "string" || document.referrer  === "")
    ){
        window.setTimeout(function(){
            // redirect to default location
            window.location.href = defaultLocation;
        },1000); // set timeout in ms
    }
    if(e){
        if(e.preventDefault)
            e.preventDefault();
        if(e.preventPropagation)
            e.preventPropagation();
    }
    return false; // stop event propagation and browser default event
    利用document.referrer在使用链接形式跳转的页面可行,但是项目采用vue router进行管理的时候,他不保存历史痕迹(使用this.$router.push({name: 'XXX'})),在新的地址发现document.referrer始终是""


2)第二种方案是根据window.history.length来验证当前页是否是第一页。其中,IE,Opera从0开始,Firefox、Chrome和Safari从1开始。

isFirstHistory () { //是否是第一条记录
    	
     var flag = false;
     var length = window.history.length;
     var currentURL = window.location.href;
             
    //IE,Opera从0开始,Firefox、Chrome和Safari从1开始。        
    if (this.isIE && !this.isOpera) {
       if (length == 0) {               
        	flag = true;
          }
     } else if (this.isSafari || this.isFireFox || this.isChrome || this.isOpera) {
            if (length == 1) {                
                flag = true;
            }
     }
      return flag;
}
使用上面的方案基本可用,但如果用户直接把可直接访问地址直接复制到新开页签地址栏中,此时上面的方案又失效了。

如:http://zhangxin.mail.10086.cn/tingshu/audiodetail?columnId=56325 直接复制此链接打开,如果直接点击返回有效,但是如果用户进入到其他的页面再一直,那返回按钮又失效了。

此时需要对上面的方案进行优化,各种谷歌大法。。。。。。不得其解,最后采取了利用缓存的实现来实现。最终优化的方法如下。

3)根据window.history.length来验证,当是第一页利用HTML5的sessionStorage保存地址,后面进行返回操作时将地址栏和sessionStorage中的地址进行比较。

isFirstHistory () { //是否是第一条记录
    	
    	var flag = false;
    	var length = window.history.length;
        var currentURL = window.location.href;
        var firstURL = sessionStorage.get("fisrtHistoryURL");
        
        if (firstURL && this._compareURL(firstURL, currentURL)) {
            return true;
        }
        //IE,Opera从0开始,Firefox、Chrome和Safari从1开始。        
        if (this.isIE && !this.isOpera) {
        	if (length == 1) {
                sessionStorage.set("fisrtHistoryURL", currentURL)
        		flag = true;
        	}
        } else if (this.isSafari || this.isFireFox || this.isChrome || this.isOpera) {
            if (length == 2) {
                sessionStorage.set("fisrtHistoryURL", currentURL)
                flag = true;
            }
        }

        return flag;
    }

    _compareURL (e, t) {  
        var n = e.indexOf("?") > -1 ? e.match(/(\S*)(\:\/\/)(\S*)(?=\?)/) : e.match(/(\S*)(\:\/\/)(\S*)/)
          , i = t.indexOf("?") > -1 ? t.match(/(\S*)(\:\/\/)(\S*)(?=\?)/) : t.match(/(\S*)(\:\/\/)(\S*)/);
        if (n && i) {
            var o = n[3]
              , s = i[3];
            return o = "/" == o[o.length - 1] ? o.slice(0, -1) : o,
            s = "/" == s[s.length - 1] ? s.slice(0, -1) : s,
            o == s ? !0 : !1
        }
        return !1
    }
使用vue router push的时候居然新地址中的document. referrer是空的,太坑了。。。

如果你有更好的方案,请一起讨论,如有纰漏,还请指出。

Logo

前往低代码交流专区

更多推荐