关于图片onload事件兼容性处理, 谷歌浏览器版本 56.0.2896.3 (64-bit) 微信客户端浏览器 canvas篇
2016-11-15 10:59
609 查看
关于图片onload事件兼容性处理
阐述:一个小demo,关于canvas 绘制 大转盘 和 指针,当同时各自添加onload事件指针图片突发性不显示.
兼容性问题-浏览器版本: 谷歌浏览器版本 56.0.2896.3 (64-bit) , 微信客户端浏览器(iphone6)PC平台 :WIN10(64-bit)
代码实例
function runLottey(Elem) { // 1. 获取画布对象 var context = Elem.getContext('2d') const WIDTH = Elem.width; const HEIGHT = Elem.height; // 2.绘制大转盘 var as = new Image(); as.src = "img/as.png"; as.onload = function () { context.drawImage(as, 0, 0); }; // 3.绘制指针 var pin = new Image(); pin.src = "img/pin.png"; var pinwidth = 358; var pinheight = 301; pin.onload= function () { context.drawImage(pin, (WIDTH / 2 - pinwidth / 2 +10) , (HEIGHT / 2 - pinheight / 2 -10)); }; }
实例效果图:
问题:
1.为什么指针会消失?
2.指针是否被绘制?
3.如何处理指针显示不正常问题?
观点整理:1
HTML5在使用drawImage绘图的时候,出现刷新就不显示的问题,原来要想是图片正常显示需要为图片添加一个onload事件.
2
setTimeout 计时器上绑定的函数不会立即执行 (不被立即执行的原因是JavaScript是单线程的)。实际上,被延迟的函数将依次排在执行队列的最后,等待下一次恰当的时间再执行。
3
若先给设置src属性,第一次浏览器执行完赋值src的语句后就要去加载图片,这个过程是很慢的,而此时程序已经执行完赋值语句,就不会等待是否加载完再执行下一条语句而是直接继续执行,然后开始给onload赋值函数,而赋值这个事件相对于从网上加载图片的时间是很短的,所以就可以执行onload函数了。假设有缓存,当执行完src的赋值语句后浏览器瞬间加载完图片,这个速度快到程序还没有执行到onload的赋值语句,所以此时onload事件被触发但此时还没有给onload事件赋值赋值,所以执行onload函数时为空函数,什么都不执行。
4
做过图片翻转效果的朋友其实都知道,要让图片轮换的时候不出现等待,最好是先让 图片下载到本地,让浏览器缓存起来。这时,一般都会用到js里边的Image对象。一般的手段无非这样:
function preLoadImg(url) { var img = new Image(); img.src = url; }
5
通过onload就能获取到图片的宽高了。但onload大一点的图通常都比较慢,不实用,但只要图片被浏览器缓存,那么图片加载几乎就不用等待即可触发onload,我们要的是占位符。所以有些人通过缓存获取也可以这么写。
//通过complete与onload一起混合使用为了测试缓存效果,注意以下测试图片的url都不加时间戳 // 图片地址 var img_url = 'http://www.qttc.net/static/upload/2013/13643608813441.jpg'; // 创建对象 var img = new Image(); // 改变图片的src img.src = img_url; // 判断是否有缓存 if(img.complete){ // 打印 alert('from:complete : width:'+img.width+',height:'+img.height); }else{ // 加载完成执行 img.onload = function(){ // 打印 alert('from:onload : width:'+img.width+',height:'+img.height); }; }
第一次执行,永远是onload触发
你再刷新,几乎都是缓存触发了
本菜鸟观点:
onload加载过快导致无法绘制指针.
通过多次实验测试,以及各位前人的观点分析,比较认同onload过快执行导致图片在已经赋值但没有加载完的情况下已经开始渲染了这样的观点.在canvas中 绘制图片 不管url前置还是后置 在当前版本谷歌浏览器中都是无法加载完图片进行绘制.
但是如果我刷新页面进行等待3s,却能不时看到指针绘制成功
这时候有两种可能 图片加载慢 或 onload过快 所以我想到了用 setTimeout 延迟绘制时间,进行异步绘制. 结果是成功的.
在这个图表中有许多信息需要理解,如果完全理解了它们,你会对JavaScript引擎如何实现异步事件有一个很好的认识。这是一个一维的图标:垂 直方向表示时间,蓝色的区块表示JavaScript代码执行块。例如第一个JavaScript代码执行块需要大约18ms,鼠标点击所触发的代码执行 块需要11ms,等等。由于JavaScript引擎同一时间只执行一条代码(这是由于JavaScript单线程的性质),所以每一个JavaScript代码执行块会“阻塞”其它异步事件的执行。这就意味着当一个异步事件发生(例如,鼠标点击,计时器被触发,或者Ajax异步请求)后,这些事件的回调函数将排在执行队列的最后等待执行(实际上,排队的方式根据浏览器的不同而不同,所以这里只是一个简化);
解决方法:
function runLottey(Elem) { // 1. 获取画布对象 var context = Elem.getContext('2d') const WIDTH = Elem.width; const HEIGHT = Elem.height; var as = new Image(); as.src = "img/as.png"; as.onload = function () { context.drawImage(as, 0, 0); }; var pin = new Image(); pin.src = "img/pin.png"; var pinwidth = 358; var pinheight = 301; pin.onload= function () { //此处增加一个异步setTimeout setTimeout(function () { context.drawImage(pin, (WIDTH / 2 - pinwidth / 2 +10) , (HEIGHT / 2 - pinheight / 2 -10)); },0); }; }
**
总结: setTimeout异步方法可以让图片绘制放在队列后面以致于不会出现空绘. 但真的是这样吗?
期待大神们指导 ——相关文章推荐
- IE处理GIF动画图片onload事件的一个BUG
- 各浏览器对页面 onload 事件处理方式不一致
- 微信浏览器返回刷新,监听微信浏览器返回事件,网页防复制,移动端禁止图片长按和vivo手机点击img标签放大图片
- 各版本浏览器_兼容性处理_01
- 转载:SD9022: 各浏览器对页面 onload 事件处理方式不一致
- 关于IE中不同版本浏览器对parseFloat的处理问题
- 客户端早会 每日一享(关于需要动态更换图片的接口处理技巧?)
- js中关于简单事件的处理与浏览器对象
- 关于windows版本电脑版微信更新后无法显示好友头像以及接收图片和表情的解决方案
- IE,firefox 里对浏览器事件处理的兼容性处理
- 关于客户端上传图片和文字,服务器对上传的数据的接收和图片压缩处理
- 关于在ie7,8等低版本浏览器的获得<select>元素的值的的兼容性问题
- 关于安卓手机微信浏览器中使用XMLHttpRequest 2上传图片显示字节数为0的解决办法
- GridView控件常见问题及处理方法===1. 关于隐藏字段的处理:==2. 关于按钮列的事件:==3. 关于按钮的客户端提示:==4. 关于时间字段的格式化输出:==5. 关于绑定空记录:
- 用JS判断浏览器是否是IE9以下,处理可能遇到的兼容性问题,或者给出浏览器版本过低的升级提醒。
- 关于ie浏览器和w3c浏览器在事件方面的兼容性问题
- Centos 6.5 x86_64环境下编译hadoop 2.2.0 mvn版本兼容性问题处理
- 处理各种浏览器 获取事件目标的兼容性
- 各浏览器对页面 onload 事件处理方式不一致
- 【专】各浏览器对页面 onload 事件处理方式