IE下canvas使用问题归集


1.同一页HTML要兼容低版本IE,需要在HTML header里包括:

   

2.动态生成的Canvas对象将不支持getContext方法,
  要使IE中的Canvas对象支持getContext等方法需要调用excanvas中的G_vmlCanvasManager_.initElement方法,由于最后的
 G_vmlCanvasManager = G_vmlCanvasManager_;
使得G_vmlCanvasManager的作用域是当前window,所以在需要初始化Canvas的时候可以采用如下的方法:
var cav = document.createElement("canvas");

if(!cav.getContext) { G_vmlCanvasManager.initElement(cav); }

var ctx = cav.getContext("2d");

....

3.drawImage方法不能用Canvas对象作为第一个参数,

excanvas中的drawImage方法只接受Image对象为第一个参数,为了使其支持Canvas对象的绘制,可修改如下代码(在excanvas.js中检索到"contextPrototype.drawImage"所在行):
contextPrototype.drawImage = function(image, var_args) {  
    if (image.getContext) { // draw canvas  
      this.element_.innerHTML += image.getContext("2d").element_.innerHTML;  
    }  
  var dx, dy, dw, dh, sx, sy, sw, sh;  
..   

4.不支持fillText等方法.

fillText,measureText也已成为CanvasRenderingContext2D对象的标准方法,为了使IE也能支持,在excanvas.js中添加以下代码:
contextPrototype.measureText = function(textToDraw) { 
  var hiddenSpan = document.createElement('span'); 
  hiddenSpan.style.font = this.font; 
  hiddenSpan.innerHTML = textToDraw;  
  var bodyNode = document.getElementsByTagName("body")[0]; 
  bodyNode.appendChild(hiddenSpan);  
  var width = hiddenSpan.offsetWidth; 
  bodyNode.removeChild(hiddenSpan);  
  return {"width" : width + 1}; 
}  
  
contextPrototype.fillText = function(textToDraw, x, y) { 
  var vmlStr = [];  
  var textHeightStr = this.font.split("px")[0].replace(/(^\s+)|(\s+$)/g,""); 
  var textHeight = /^\d+$/.test(textHeightStr) ? parseInt(textHeightStr) : 0; 
  vmlStr.push('                  ' color:' + this.fillStyle + ';', 
                  ' position:absolute;', 
                  ' left:' + x + 'px;',  
                 ' top:' + (y - textHeight) +'px;', 
                 ' width:' + this.measureText(textToDraw).width + 'px;', 
                  ' height:' + textHeight +'px;"', 
                  ' >' + textToDraw, 
                  '
', 
                  ''); 
  
 this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join('')); 
}  
 其中measureText是通过在页面上添加一个隐藏的临时文字容器并获得其宽度来实现.
另外在属性声明的地方要添加默认字体:
// Canvas context properties  
    this.strokeStyle = '#000';  
    this.fillStyle = '#000';  
    this.font = '12px sans-serif';  
... 

 5.IE与其他浏览器的不同处理

下面的部分包括在HTML的BODY里, canvas元素的后面:
 
 

下面是mycode.ie.js不同于mycode.js的部分. 

1) addEventListener -> attachEvent
别的浏览器用addEventListener. IE用attachEvent. 对于事件名, IE要多加一个"on". 比如IE用"onmousedown", 别的浏览器用"mousedown".

2)为了兼容手机, 鼠标事件为触屏事件取代, 所以mousedown/mouseup/mousemove改用如下的事件: touchstart/touchend/touchmove.

3)event.pageX -> pageX(event)
别的浏览器直接用event.pageX. IE完全不同, 所以另外自定义一个函数pageX(event)来达到相同效果:
function pageX(e) {
  if (e.pageX) return e.pageX;
  else if (e.clientX)
  return e.clientX + (document.documentElement.scrollLeft ?
  document.documentElement.scrollLeft : document.body.scrollLeft);
  else return null;
}

4)in event handlers, this.offsetLeft/Top -> vCanvas.offsetLeft/Top
别的浏览器this指代事件发生的元素, 这里是canvas. IE的this指代window, 所以要专门指明vCanvas.offsetLeft/Top.

5)onmouseout在IE里行为不稳定, 所以应避免使用, 或者改用onmouseleave.

6)辨认鼠标的左右键, 别的浏览器用event.which, IE用event.button.

7)DIV元素的半透明效果,别的浏览器用 style="background-color:rgba(255,255,255,0.75);", IE用style="background-color: white; opacity:0.75;filter:alpha(opacity=75);"

8)定义元素高度和宽度时,IE常要指明单位px,别的浏览器不用. 比如: