根源上解决Pjax加载页面不执行js的问题

[redbar]此方法可能已经失效,老老实实填回调函数吧[/redbar]

分析问题

最近在研究如何实现Pjax,在使用jquery.pjax这个插件的时候发现加载页面时不会执行jquery的初始化方法,包括一些插件的初始化方法,这就很头疼啊 ,虽说回调函数能够解决问题,但是一个主题都成型了,再修改很麻烦,这里还要说一点,就是Typecho的评论,启用Pjax后,我滴妈耶,直接报废

既然没有好的办法解决,那就看看源码吧,看看这个pjax到底是什么玩意。

查看源码后发现该jquery.pjax替换容器内容时,是将服务器端返回的html转换为了jquery dom对象然后再执行的替换。但是这样操作会导致一系列的加载事件不会被触发,导致各种js不会被执行。

于是决定将添加dom节点修改为直接添加html片段(即是返回的data。局部替换context.html(data)

修改代码

1、将jquery.pjax.js中311行的 context.html(container.contents)修改为 context.html(data)
修改代码
这样在pjax加载新页面的时候便会直接将服务器端返回html片段添加进容器。此时使用pjax加载新页面的时候,各种初始化方法即可正确执行。
2、但是这样仅处理了新增页面,而执行回退操作时pjax会从缓存中读取上一个页面的内容,同样pjax在回退上一个页面的时候依然是以dom对象键值对的方式存储和添加的,所以我们还需要继续修改。

/*将365行的*/
cachePush(pjax.state.id, [options.container, cloneContents(context)])
/*修改为:*/
cachePush(pjax.state.id, [options.container, context.html()])

继续修改
3、按上面改完后发现。第一次前进后退已经正常了,然后第二次前进后退的时候依然会出现页面js失效的情况,所以还需要更改源码457行:

/*将*/
cachePop(direction, previousState.id, [containerSelector, cloneContents(container)])
/*修改为:*/
console.log(container.html());
cachePop(direction, previousState.id, [containerSelector, container.html()]);

继续改啊
至此修改完毕!
为了方便大家,我把修改好的文件提供在下面,仅供dalao们参考

[download href="https://www.lanzous.com/i9m8zsh" target="blank"]戳我下载[/download]

打赏
评论区
头像
    头像
    李嘉图
      

    dalao,之前我就是乖乖回调的,但是正常访问能成功,浏览器前进后退有些js就不工作了,如何解决呢?网上找的资料说在on('pjax:popstate', function () {}里再调用js,我试了,没用。在线等,急!

      头像
      Veen Zhao
        
      @李嘉图

      我就是直接在end里调用的额,没问题吖

        头像
        李嘉图
          
        @Veen Zhao

        这就很难受了,我这也不是所有的js都不工作,只有俩特殊的,在前进后退中初始化就失效了。没办法啦

    头像

    晚点我试试看。谢谢大佬!