html2canvas在iOS8系统上的兼容性问题

问题描述

由于项目需要,需要将实现网页截图的功能,在网上进行一番搜索后,最后决定使用 html2canvas 的方式 将 dom -> canvas -> png 的方式来实现。实现成功后,在安卓和iOS9以上都可以实现截屏功能。但是在iOS8 系统上却是截出了一张空白图片。

系统环境

Html2canvas 版本 v1.0.0-alpha.10

结论

先给结论,下面有自己解决问题时的思路,不想看的可以忽略。

截出来的图片是空白的原因由于被截屏的页面使用flex布局,而由于iOS8的系统并不支持flex布局,只支持-webkit-flex布局,而html2canvas并不支持-webkit-flex,所以无法将html生成canvas,从而导致了截出一张白屏。

详细分析过程

作为刚刚接触一个多月的前端的iOS码农,一开始是一脸懵逼的。这时候,Google大佬就派上用场了,&,然而这次Google大佬也没辙,也可能是我关键字搜错了,反正没找到答案。

无所不能的google跪了,那就只能撸起袖子自己干。

首先,先确定是什么原因导致生成的图片是空白图片。html2canvas使用很简单,代码如下:


html2canvas($('#share-page').get(0), {
     scale:2,
     useCORS:true
})
.then(function(canvas) {
      letdataURL=canvas.toDataURL("image/png");
      if(dataURL===undefined||dataURL===null) {
            returnnull;
       }
       shareImage(dataURL)
})

这个过程一共分为2步: dom => canvas 和 canvas => image(base64) ,首先得确定是哪一个步骤出现了问题。首先,dataURL是否有值,测试结果是dataURL是由值的,生成的base64进行解码后,就是一张空白的图片。第二部,将canvas直接显示在dom中,是否是空白的,测试结果是canvas的确是空白的,里面没有绘制出任何内容。

确定是dom=> canvas 这个过程出现了问题,那么就得查看出现问题的原因是什么。由于这个版本的html2canvas是有打印出一些必要的日志的,最简单的方法就是直接对比能够成功截图的日志和截出来图是空白的日志。

成功截图
空白截图

通过对比,能够发现成功截图的日志中相比于空白截图的日志多出了几条日志,此时猜想是是否是html2canvas在iOS8系统上没有办法成功解析出dom,导致无法将dom里面的数据绘制到canvas中。抱着这个猜想,我直接去看html2canvas的源码,直接搜索关键字Starting node parsing 定位到了node分析的地方,在html2canvas中有一个NodeParser.js的文件,顾名思义,主要是用于node的解析的,直接看到 parseNodeTree函数,发现里面有很多条件判断,但是直接看代码并不好发现到底哪一个条件判断出现问题,导致解析出错。所以,决定直接调试代码,在parseNodeTree中打上断点,一步一步调试,看到底是哪一个条件判断出现了问题。最终,终于找到了出现问题的判断 ,即下图中被红色圆圈标出的判断,container.isVisible,这个判断返回了false,导致了直接跳出,不继续执行下面的node解析。

那么,container.isVisible究竟是什么判断呢,查看源码得知,

可以看到isVisible是对node的style中的displayopacityvisibility 进行判断。通过调整成功截图(iOS10)和空白截图(iOS8),最终发现,这2者唯一的不同就是this.style.display这个值,在成功截图(iOS10)的调试中,this.style.display的值为 128 ,而在空白截图(iOS8)调试中,this.style.display的值为1,而contains(this.style.display,DISPLAY.NONE)的作用对传入的2个值做位与操作,而DISPLAY.NONE所代表的数字就是1,contains(this.style.display,DISPLAY.NONE)在空白截图(iOS8)的调试中,返回的是true,前面一取反,就是false,所以isVisible最终就返回了false。我觉得离真相越来越近了。✌️

那么,为什么同一一份代码,在iOS9即以后和iOS8的机器上container.style.display值会不同呢,我查看了下程序中css中display值的设置,发现是被设置为flex,突然想到是否iOS支持flex导致,直接上caniuse一查,发现iOS8的系统对flex的并不支持,只支持-webki-flex,此时,我心中就觉得问题一定是出在这个地方。紧接着,在iOS8调试,查看了将要截图的dom的style.display的值,如下图,很明显的可以看到,此时display的值是-webkit-flex而不是flex

到这里,就可以肯定是由于display中的flex中iOS8中并不支持导致的了生成canvas失败。但是,为什么-webkit-flex就不能够成功生成canvas能,直接看html2canvas的源码,在src/parsing/display中找到了答案,如下图,原来在html2canvas中,会将css中的display中的值映射成一个数字,而在下图的映射表中,只要找到了flex的映射值,并没有--webkit-flex的映射值,所以-webkit-flex被映射成了DISPLAY.NONE,从而导致了isVisible的计算值返回了false,最终导致了无法生成想要的canvas

解决方法

1. 不采用 flex布局

2. 修改html2canvas源码,将-webkit-flex也返回DISPLAY.FLEX

3. 不支持iOS8 , 嘿嘿😜

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342