在Safari 10中,getContext('2d')返回null

3

即使在我们的 MacBook 上,我也无法重现问题本身,但是我们有一些用户的日志。问题出在当我尝试在 CanvasRenderingContext2D 上使用某些渲染方法时,它会崩溃,因为它是 null。

所以我有画布元素,它有 getContext 方法,但它返回 null。 已经检查过的潜在问题简单列表:

  1. 画布元素已被创建、存在,并具有正面的大小和 getContext 方法
  2. 在页面加载后执行了 getContext 调用(onload 监听器)
  3. 没有使用其他参数调用 getContext(例如 'webGl')
  4. 在 getContext('2d') 中,'2d' 字符串始终小写
  5. 此问题仅在 Safari 10 上重现
  6. 在某些情况下,此错误不是在页面加载后立即发生,而是在一些用户操作之后发生。这意味着画布已被销毁并重新创建了一些时间,并且它可以工作。

他们可能有一些插件(例如针对火狐浏览器,不确定是否有适用于Safari的插件)来禁用画布,因为它可以被用于指纹识别。你能否与能够重现此问题的客户进行交流? - Kaiido
找到一个可以做到这个的:http://jsblocker.toggleable.com/ - Kaiido
是的,看起来好像有东西阻止了画布,但据我所知,这些扩展并没有完全阻止画布。 - Michael Stets
我只了解我链接的第一个,是的,它只覆盖导出方法,但你知道,坏代码也会发生在扩展中。 - Kaiido
2个回答

5

我不确定这是否与此处描述的情况相关,但我曾经遇到过类似的问题并得以解决。也许这可以帮助一些人。问题的要点是浏览器对HTML5画布的处理方式有很大差异。特别是,它们愿意为画布分配的总内存量以及单个画布(高度、宽度和面积的限制)的数量似乎有所不同。我从未费心去理解细节,但在这里有一个堆栈问题解决了一些约束。

对于我来说,我正在生成许多独立的画布,并独立地管理它们的2D上下文。问题在于我没有仔细处理垃圾回收,而且它花费了我很长时间才注意到,因为我大部分时间都在Chrome中测试,其中一切都运行良好。
同时,在Firefox中的行为是我的项目完全无响应,而没有抛出有意义的错误,在Safari中,我可以得到我的上下文,直到我用尽了为画布分配的总内存,然后getContext('2d')将返回null

我的第一个解决方案是降低画布的分辨率,但更好的解决方案是处理我当前未使用的画布并在需要时生成它们。


是的...没错,就是这样。我用一个循环创建了300个1000*1000大小的画布,并在上面绘制了矩形,做了一个简单的示例。 所有浏览器都能正常工作,但Safari不行...刷新4-5次页面后,在大约160次迭代时出现了相同的错误...所以我认为这是Safari本身的一个bug。 - Michael Stets
这是代码 - https://jsfiddle.net/zLtoqxuy/ 你只需要点击运行按钮或刷新页面,都可以。 - Michael Stets
感谢提供这个代码片段!我也在Firefox中试玩了一下,显然Safari对画布的容忍度最低。但是,如果你增加画布的高度和宽度,你会发现Firefox也开始出现问题。仅将高度和宽度加倍到2000就会导致脚本无响应。 - Badam Baplan
问题在于Safari中的总画布内存限制。这个问题在https://dev59.com/NFQK5IYBdhLWcg3wEb17中提供了一些有用的细节。 - Duannx

0

我曾经遇到过同样的问题。虽然我搜索了很多资料,但仍不知道为什么会出现这种情况。但我尝试了两个方法,它们解决了我的问题:

你可以选择以下两种方法之一:

  1. 使用html标签获取画布的上下文类型,即使您不会使用它,也要进行初始化。我知道这真的很丑陋和糟糕,代码结构不好,但这只是一个解决方法 :(

    var canvas = document.getElementById('canvas');

    canvas.getContext('2d');

  2. 使用js动态创建画布并获取上下文:

    var newCanvas = document.createElement('canvas');

    newCanvas.id = 'canv';

    canvasContainer.appendChild(newCanvas);
    
    var c = newCanvas.getContext('2d'); // 任何类型的上下文
    

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接