讓excanvas支持動態創建的canvas標簽(附演示文件)


  大名鼎鼎的excanvas讓低版本IE也能支持HTML5標准的canvas標簽,雖然功德無量,但也留有小小的缺憾,比如由於excanvas是在頁面初始化的時候統一把所有canvas標簽初始化一次。一旦動態生成或者未初始化之前就有腳本操作了canvas標簽,就會報錯了。

  參考ITEYE的一篇博文 給excanvas添加fillText方法 ,里面提供了不少的增強改進方法,非常值得借鑒。

  但美中不足的是,該文中對於動態創建canvas標簽的初始化,解決方式不夠智能,需要程序員自己額外些初始化代碼。而且由於excanvas對所有canvas標簽的初始化是在document准備完畢時才進行的,如果頁面中有實時執行的腳本調用或創建了canvas標簽,就會導致錯誤,因為此時canvas標簽的屬性和方法還沒有被初始化。

  那么如何解決這個問題呢,如何讓excanvas智能的處理各種情況下對canvas標簽的初始化呢?非常簡單,我們可以對通過對document方法的劫持重載來達到這個目的。當document的createElement、getElementById、getElementsByTagName、getElementsByName以及getElementsByClassName方法被調用時,我們可以先獲取對象,然后檢查對象是否為沒有初始化的canvas標簽,是則進行初始化,處理完成后,再把對象返回。

  具體方法是,先用一個變量緩存這些方法,然后劫持重載這些方法,重新定義為我們自己寫的處理函數即可。自定義函數中,我們先用緩存的原始方法獲取對象,然后檢查對象是否為未初始化的canvas標簽,是則進行初始化,最后將處理過的對象返回。這樣一來我們就對document的幾個主要的對象獲取方法都進行了重載,實現了自動動態初始化canvas的目的。

  具體的JS代碼如下,可自行添加到excanvas.js的最后一行之前,以確保該代碼和excanvas同步工作。

//截獲並重載元素獲取方法,對canvas動態初始化
(function() {
	var _createElement=document.createElement;
	document.createElement=function(elementTag) {
		var obj=_createElement(elementTag);
		if (elementTag.toLowerCase() == 'canvas') {
			G_vmlCanvasManager.initElement(obj);
		}
		return obj;
	};
	
	var _getElementById=document.getElementById;
	document.getElementById=function(elementId) {
		var obj=_getElementById(elementId);
		if (obj.tagName.toLowerCase() == 'canvas' && !obj.getContext) {
			G_vmlCanvasManager.initElement(obj);
		}
		return obj;
	};
	
	var _getElementsByTagName=document.getElementsByTagName;
	document.getElementsByTagName=function(elementTagName) {
		var obj=_getElementsByTagName(elementTagName);
		for(var i=0;i<obj.length;i++) 
		if (obj[i].tagName.toLowerCase() == 'canvas' && !obj[i].getContext) {
			G_vmlCanvasManager.initElement(obj[i]);
		}

		return obj;
	};
	
	var _getElementsByName=document.getElementsByName;
	document.getElementsByName=function(elementName) {
		var obj=_getElementsByName(elementName);
		for(var i=0;i<obj.length;i++) 
		if (obj[i].tagName.toLowerCase() == 'canvas' && !obj[i].getContext) {
			G_vmlCanvasManager.initElement(obj[i]);
		}

		return obj;
	};
	
	if (!document.getElementsByClassName) {   
  document.getElementsByClassName=function(className) {
   var all = document.all ? document.all : document.getElementsByTagName('*');
   var elements = new Array();
   for (var i = 0; i < all.length; i++)
     if (all[i].className == className) {
        elements[elements.length] = all[i];
      }

    return elements;
   };
  }
  var _getElementsByClassName=document.getElementsByClassName;
  document.getElementsByClassName=function(className) {
  	var obj = _getElementsByClassName(className);
      for (var i = 0; i < obj.length; i++)
          if (obj[i].tagName.toLowerCase() == 'canvas' && !obj[i].getContext) {
              G_vmlCanvasManager.initElement(obj[i]);
          }

      return obj;
  };
})();

演示例子(IE678_ExCanvas支持測試.zip)下載 請使用IE6\7\8進行測試。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM