JBolt极速开发平台里的自动化时间组件,用的是laydate.js,在layui里可以使用,在非layui里也可以独立版使用。
这里我使用的是独立版。
遇到的问题:
和前面我分享的PJAX下的UEditor和Webcam组件,都是出现二次渲染的问题。
第二次执行laydate.render的时候,组件失效,不报错,也不显示了!
【分享】Pjax模式下集成一个同时支持IE和Chrome的webcam组件
【分享】PJAX模式下使用UEditor如何避免二次加载页面初始化失败?
laydate的调用方式如下:
调用方式针对一个输入框元素,给一个ID就行了,自动完成了初始化和事件绑定,这里我设置的是click的时候,触发渲染时间组件的弹出,默认不写就是focus的时候。
组件效果点击输入框,正常弹出了。
那么,二次渲染怎么重现这个问题呢?
pjax加载的,只要打开新页面,然后浏览器返回到本界面,就完成了二次调用laydate.render,这样bug就复现了!
如何处理?
我们现在分析一下这个bug出现的原因:
首先,我们来看第一次渲染之后,组件和页面里都有什么变化?
1、input组件本身变化
从下图可以看出,经过laydate的render之后,在全局laydate给input组件初始化,增加了一个属性lay-key="1" 有具体的赋值,而且重新刷新页面之后,这个值还是lay-key="1”说明这个值是一个渲染顺序。页面上其他的input经过laydate渲染后也有了相应的值。
代码分析那么这个值有何用?正是下面要说的第二个变化:
2、页面底部动态增加元素,id与lay-key对应。
代码分析 代码分析好了,经过页面代码的分析我们就知道,laydate.render执行后呢,页面的元素都有了绑定和变化。
lay-key和弹出层都是对应的。而且手动点击左侧导航去切换页面,在点击laydate的demo页面进来,这种主动触发加载的行为,是没有问题的,而且laydate组件的渲染lay-key的顺序是继续增加的,同样第一个input组件,在首次render的时候给的lay-key="1",再次主动触发加载页面,相当于是全新加载的页面,laydate把它当做是全新组件渲染,会给自身队列中继续累加数量。
这个可以看一下,点击进入几次之后的lay-key="23"
关键lay-key变更但是PJAX技术是类似浏览器自身缓存了加载的界面的状态,当使用浏览器返回按钮返回到本页面的时候,并不是去后台重新加载渲染的本页面,而是拿到的缓存,组件因为已经被渲染过了,自身的lay-key="1"还存在呢,laydate自己也懵逼了,一看有值就不重新绑定渲染了。
这就是,pjax下浏览器返回已经渲染过的界面后,laydate.render二次渲染失效的根本原因。
那么,怎么办呢?
这个要么是Layui作者修复这个问题,能针对这种PJAX加载和回退浏览器重新渲染的问题做处理,要么就按照我的方案,搞之。
我的方案是:
主动给它把lay-key去了,让它再次懵逼,一看没有lay-key那么好吧,重新render一次。
具体就是,在laydate.render之前判断是否已经有了lay-key 有就去掉。
一行代码搞定
一行代码,搞定之。
哈哈哈哈哈哈哈~~
问题咨询,加我微信:
image.png
网友评论