`

使用ajax和window.history.pushState无刷新改变页面内容和地址栏URL

    博客分类:
  • JS
 
阅读更多
后退时关闭当前页面
<script type="text/javascript">
jQuery(document).ready(function ($) {
        if (window.history && window.history.pushState) {
            $(window).on('popstate', function () {
      WeixinJSBridge.call('closeWindow');
      /**
      window.opener=null;
          window.open('','_self');
          window.close();
      */
            return false;
            });
            window.history.pushState('forward', null, 'Wx.AuthSuccess.jdp');
  //  window.history.pushState('forward', null, 'baidu.com');
  //window.location.href="www.baidu.com";

  //WeixinJSBridge.call('closeWindow');
        }
    });
</script>



2、替换当前历史记录点

window.history.replaceState和window.history.pushState类似,不同之处在于replaceState不会在window.history里新增历史记录点,其效果类似于window.location.replace(url),都是不会在历史记录点里新增一个记录点的。当你为了响应用户的某些操作,而要更新当前历史记录条目的状态对象或URL时,使用replaceState()方法会特别合适。

3、监听历史记录点

监听历史记录点,直观的可认为是监听URL的变化,但会忽略URL的hash部分,监听URL的hash部分,HTML5有新的API为onhashchange,我的博客里也有说到该方法和跨浏览器的兼容解决方案。可以通过window.onpopstate来监听url的变化,并且可以获取存储在该历史记录点的状态对象,也就是上文说到的json对象,如:

// 当前的url为:http://www.qingdou.me/post-1.html
window.onpopstate=function()
{
// 获得存储在该历史记录点的json对象
var json=window.history.state;
// 点击一次回退到:http://www.qingdou.me/index.html
// 获得的json为null
// 再点击一次前进到:http://www.qingdou.me/post-1.html
// 获得json为{time:1369647895656}
}
值得注意的是:javascript脚本执行window.history.pushState和window.history.replaceState不会触发onpopstate事件。

还有一点注意的是,谷歌浏览器和火狐浏览器在页面第一次打开的反应是不同的,谷歌浏览器奇怪的是回触发onpopstate事件,而火狐浏览器则不会。


======================================================================
QA team通过Tealeaf 和Avicode检测到application有很多的500 errrors,因此这2周几乎都在解决这个问题。通过reproduce这些各种不同的错误,几乎可以把原因归结在浏览器的后退按钮(pressing back button)和键盘的后退键 (backspace),和leader交流下,觉得有必要阻止页面后退。

当然,相关的文章到处走势,其实就是一篇文章都是转来转去的.基本上是3个solution:

1).设置网页过期(服务器端)

2).javascript:window.history(客户端)

3).对于键盘的backspace.通过window.event来过滤,当然要考虑的是对于Input控件,要保持删除的功能。

<script type="text/javascript">

function backspace() {

if (event.keyCode == 8 && event.srcElement.tagName != "INPUT" && event.srcElement.type != "text")

            event.returnValue = false;

     }

if (navigator.appName == "Microsoft Internet Explorer") {

         window.history.forward(1);

     }

else // if it is Mozilla than

     {

         window.history.forward(-1);

     }   

</script>

下面是我的尝试:

1) 先来说对于,网页过期的:

网页一旦过期,意味着每次页面的刷新,需要重新从服务器端获取所有的网页资源。这时候如果通过浏览器的后退按钮,进行后退,就会reload整个页面,相当于一个get request.因此对于相应页面会执行 OnLoad事件,以及OnLoadCompleted事件

若在OnLoadCompleted事件页面没能获取到所需要的资源,将会显示网页已过期的错误。但是无论讲*****怎样添加到页面中,都不能重现网页已过期的错误,

2) 对于页面可客户端的OnLoad执行脚本: Windows.History.Forward(1),对于这个方法别人说不完美,但没有说处理理由。我相说的是,对于直接点击后腿按钮的情况,Window.History.Forward(1)几乎可以Cover 大多数场景,只是一个奇怪的事情当所有的后退经过一个页面的时候,就会停止,不会继续forward 到原来页面。原以为这就是我们的解决500 errors的钥匙,但是一次不经意的聊天,让我们想起了,如果不是点击后腿按钮,而是选择HIstory List中网页,又该如何去处理? 为了解决这一问题,我有2个想法

a)获取选择HistoryList中页面的index,然后Windows.History.Froward(index), 查阅资料,最后在msdn上看到的解释是,处于安全的因素microsoft 不会暴露Window.history对象中url 实际地址和Index,也就是说无法得到HistoryList 网页的具体信息。

b)  记录后退之前页面的URL,然后直接用Windows.Location.Href,记录后退之前的url这个不难,<%= %> <%#%>, 均可做到,但是问题来了,如何区分网页的get reque是由于后退造成的,似乎有一个无解!

不过在探索a,b 的时候,想到2个问题

1)关于Windows..history.forward();如果windows.history List中只有5个页面,但是我把Windows..history.forward(100),结果会是如何。

2)如果我在history list选择一个距离当前页面距离不是1的页面 Windows..history.forward(1),会如何工作?

解释:

   1)其实Windows..history.forward(100)和Windows..history.forward(1)的效果是一样的.

   那Windows..history.forward(1),究竟是如何工作的,通过http watch

wps_clip_image-11801

可以看到,Windows..history.forward(1),总是会将windows.history.list里买你的所有页面走完,直到页面再也不能往前,对于windows.history.list.length=5的时候,无论在哪个页面发起history,forward(1),都会走到当前页面。因此是可以很好地阻止页面后退,缺点是带来了很多的额外的http request,因为需要一个页面一个页面后退。

另外一个奇怪的问题:在我们的一个application里面我发现,windows.history.forward(1),会走到某个页面,停止。以至于在那个页面之后的页面,就无法实现组织后退的功能。我偶然发现对于windows.history.forward(1)页面居然会执行OnInit ,Onload ,OnloadComplete这些事件,我很费解,为什么windows.history.forward会触发服务器端事件呢,然来是因为在基类里面设置了缓存过期,这样每次需要从server上取页面资源 。

因此页面过期和windows.history.forward是不可以一起使用的

===============================================================


     按微信产品部副总经理张颖“每一个公众号都是一个APP”的说法,我们确实可以利用微信内置浏览器访问为公众号设计WebApp单页应用,以使得客户在访问公众号时有近似原生App的体验,不过目前这样的公众号很少,原因除了使用javascript开发单页应用的难度比开发一般的Web页面难度更高一些,更重要的一点是使用微信内置浏览器访问Web页面时,Android用户一按物理返回键就回到微信界面,而Android用户按物理返回键的习惯预期是回到上一页,这样就使得微信公众号的WebApp客户体验非常差。

  有什么方法改变这一点么?最理想的解决办法是微信自己接管用户按物理返回键这个事件,然后类似像getNetworkType一样提供javascript事件给开发者使用。不过很遗憾,腾讯目前没有提供这个事件,而且看样子将来也不打算提供。

  这个问题不是大问题,但如果不解决会影响Android用户的客户体验。幸运的是,我找到了解决办法,方法就是利用javascript window history来解决。

  由于安全原因javascript不允许修改history里已有的url链接,但可以使用pushState方法往history里增加url链接,并且提供popstate事件监测从history栈里弹出url。我们可以利用这一点,在WebApp加载主界面后先往history里压入“#”链接,然后监听popstate事件,在Android手机的浏览器,按下物理返回键默认的操作是执行window.history.back(),此时将触发popstate事件。收到popstate事件时代码显示“再按一次退出程序”div顶层标签,此时history栈已经为空,如用户再次按下物理返回键将执行默认操作回到微信。接着,我们要设定一个定时器,在指定的时间(比如2秒)后如用户没有再次按下物理返回键将再次往history里压入“#”链接,并隐藏“再按一次退出程序”div顶层标签,等待用户下一次按下物理返回键。


pushHistory();

setTimeout(function () {

  window.addEventListener("popstate", function(e) {

    showBox("再按一次退出程序", 2000, function() {      

      pushHistory();

    });

  }, false);
08
}, 300);



function pushHistory() {

  var state = {

    title: "title",

    url: "#"

  };

  window.history.pushState(state, "title", "#");

}



function showBox(msg, timeOut, onTimeOut) {

  if (typeof alertBoxDiv === "undefined") {

    alertBoxDiv = $("<div/>").addClass("alert-box hide").append( $("<div/>").addClass("label label-primary")).appendTo($("body"));

  }

  alertBoxDiv.children(".label").html(msg);

  alertBoxDiv.removeClass("hide");

  if (typeof timeOut === "undefined") timeOut = 2000;

  setTimeout(function() {

    alertBoxDiv.addClass("hide");

    if (typeof onTimeOut !== "undefined") onTimeOut();

  }, timeOut);

}


  监听popstate事件的代码稍作修改就可以用于任意控制单页应用中javascript生成的任意动态页面的跳转,此方法已经在微信公众号WebApp中使用,可在微信中搜索“myfunds”公众号关注体验。这个方法也可以用于微信公众号之外的WebApp,链接就不发了,免得CSDN又要审查。




window.history.pushState('forward', null, 'Wx.deputyDiaryList.jdp?t='+new Date().getTime());
1.在一个页面中添加多少历史记录,后退,只要没有页面的转换,就不会跳转到页面;(A--B页面。再B页面pushState 多少记录,后退时 这些记录URL都不会刷新该URL的页面;只有在B到A的时候才会触发)

2.
微信中 只要按后退键就触发$(window).on('popstate', function () {};



浏览器中:
流程是:A->B,B原URL--新增一个新URL显示在地址栏--当按后退按钮时地址栏先退回原URL--
--退回A最后的RUL,这时才会触发  $(window).on('popstate', function () {}。


history.replaceState

流程是:A->B,B原URL--替换一个新URL显示在地址栏--当后退时则直接退回新URL地址页面
(好像)并不触发$(window).on('popstate', function () {};
可能是因为地址栏地址都一样导致。。


分享到:
评论

相关推荐

    使用ajax和history.pushState无刷新改变页面URL示例

    使用History API,开发者可以在不进行页面刷新的情况下改变浏览器地址栏中的URL,这包括使用history.pushState和history.replaceState方法。 #### history.pushState 该方法接受三个参数:state对象、标题(目前...

    使用ajax实现无刷新改变页面内容和地址栏URL

    使用Ajax和window.history.pushState方法实现无刷新改变页面内容和地址栏URL是Web开发中一个非常重要的技术点,它不仅提升了用户体验,还对搜索引擎优化(SEO)和网页可访问性有很大的帮助。本文将详细介绍该技术的...

    pushState实现Ajax无刷新页面切换

    pushState是HTML5提供的一种技术,它允许我们改变浏览器地址栏中的URL而不重新加载页面,这种技术常被用来实现单页应用(SPA)中的无刷新页面切换。通过pushState与window.onpopstate事件的组合,可以实现页面的前进...

    在vue中实现嵌套页面(iframe)

    在Vue.js中实现嵌套页面通常涉及到使用`iframe`元素来加载外部网页或者内部组件。`iframe`允许我们在一个Vue应用中嵌入另一个独立的HTML文档,这对于展示第三方内容、实现某些特定功能或者处理复杂交互场景时非常...

    pushState、replaceState、onpopstate 实现Ajax页面的前进后退刷新

    使用pushState和replaceState方法时,浏览器并不会立即加载对应的URL,而是更新地址栏中的URL,这意味着开发者可以使用这些方法来创建一种伪URL,从而不触发页面加载。在单页面应用中,这可以用来模拟页面的导航。 ...

    Html5无刷新修改browser Url的方法

    在某些情况下,例如用户在网页上进行某些操作时,我们可能希望在不刷新页面的前提下,改变浏览器地址栏的URL以反映当前页面状态,这时,就可以结合使用Ajax和Html5的history API。 使用这些新特性的好处在于可以...

    使用JavaScript修改浏览器URL地址栏的实现代码

    JavaScript提供了一种方式,通过`History`对象的`pushState()`方法来修改浏览器的URL地址栏,而无需刷新页面。这一功能在构建单页应用程序(SPA)时特别有用,因为它可以提供更好的用户体验,同时更新浏览器的历史...

    HTML5 History API 实现无刷新跳转

    例如,从页面A切换到页面B时,我们不再需要完全加载新页面,而是通过Ajax获取页面B的数据,然后在页面A中使用JavaScript更新内容,同时利用History API改变URL。这样,用户在浏览器地址栏看到的URL会反映出当前的...

    通过history解决ajax不支持前进/后退/刷新的问题

    因为当AJAX请求完成时,浏览器地址栏的URL并未发生改变,同时浏览器的历史记录也不会记录这种内容的变化,因此当用户尝试使用前进或后退按钮时,浏览器无法正确处理。 2. HTML5的History API: HTML5带来了新的...

    html页面传值

    虽然通常用于URL参数,但也可以通过History API(如`history.pushState()`和`history.replaceState()`)在页面跳转时不改变URL的可见部分,同时传递数据。 7. Web Storage事件监听: 使用`window....

    JavaScript_在演示中用作伪造safari式web浏览器窗口的方法.zip

    如果要实现类似Safari的前进和后退功能,可以维护一个浏览历史栈,并使用`history.pushState`和`history.back`或`history.forward`方法。 此外,为了提供更真实的用户体验,开发者可能还会关注浏览器特有的行为,...

    JavaScript的History API使搜索引擎抓取AJAX内容

    window.history.pushState(stateObject, title, URL); ``` 在这里,stateObject可以是任何可序列化的对象,用来在popstate事件触发时传递状态信息;title是历史记录项的标题,但目前大多数浏览器都不支持;URL是...

    解决浏览器记住ajax请求并能前进和后退问题

    然而,AJAX请求并不改变浏览器的URL地址栏中的地址,导致浏览器的历史记录栈中不会记录AJAX请求的页面状态。因此,当用户尝试使用浏览器的前进或后退按钮时,浏览器无法响应这些请求,而是直接跳转到上一个或下一个...

    jQuery+pjax简单示例汇总

    `pjax` 通过 `Ajax` 请求加载页面内容并利用 `HTML5` 的 `History API` 更新浏览器的地址栏,从而在不刷新整个页面的情况下实现内容的切换。这使得用户在浏览时感觉更加流畅,因为页面的加载速度更快,且历史记录...

Global site tag (gtag.js) - Google Analytics