王子和公主合力抵抗壞皇后,他們費盡了千辛萬苦,終於打敗了壞皇后,以為從此就能過著幸福快樂美滿的日子,但是錯了,他們還有各自的王子病和公主病要先治療....
我想畫一個散佈圖,我用canvas
為什麼不用人家寫好的套件,因為別人寫好的套件不一定是我要的東西(好啦我承認是因為老闆太喜歡搞自己的格調改來改去,別人的套件風格都定義好了幾乎沒得改)
jquery這麼方便我竟然不用,因為裡面有太多的try{}catch{},我的東西很簡單,沒有表格排序沒有下拉選單要作業,所以在這裡我不需要jquery
好吧,用canvas也沒什麼特別的,就是要依瀏覽器各別做,不同瀏覽器要另外寫不同做法,遇到IE8還真是憋腳,但是excanvas.js也是能救回來將就一下啦,問題是ie8怎麼有時候OK有時候不OK?看吧~王子病和公主病開始發作了.....
1.xml資料源讀取大不同,是的,我還是用了try catch來針對瀏覽器做不同的xml讀取方式
var xmlDocTemp;
if ((xmlFilePath != null) && (xmlFilePath != "")) {
if (window.ActiveXObject)// code for IE
{
xmlDocTemp = new ActiveXObject('Microsoft.XMLDOM');
xmlDocTemp.async = false;
xmlDocTemp.load(xmlFilePath);
}
else if (window.XMLHttpRequest)// code for IE7, Firefox, Opera, etc.
{
try {
xmlDocTemp = document.implementation.createDocument("", "", null);
xmlDocTemp.async = false;
xmlDocTemp.load(xmlFilePath);
}
catch (e) {
try //Google Chrome safari
{
xmlhttp = new window.XMLHttpRequest();
xmlhttp.onreadystatechange = function () {
if (xmlhttp.readyState == 4) {// 4 = "loaded"
if (xmlhttp.status == 200) {// 200 = "OK"
xmlDocTemp = xmlhttp.responseXML; // alert(xmlhttp.responseXML);
}
}
};
xmlhttp.open("GET", xmlFilePath, false);
xmlhttp.setRequestHeader('Content-Type', 'text/xml');
xmlhttp.send(null);
}
catch (e) {
error = e.message;
alert(error);
}
}
}
else {
alert('您的瀏覽器不支持xml文件讀取,請使用 IE5.0以上 或 Chrome 或 FireFox 較高版本來嘗試瀏覽本網頁!');
return null;
}
}
else
{ return null; }
try {
return xmlDocTemp;
} finally {
xmlDocTemp = null;
}
讀取xmlDocument時,IE使用nodes[i].childNodes[j].text,Chrome使用nodes[i].childNodes[j].textContent,其他瀏覽器我沒一一確認過
2.canvas物件初始化(忍不住小小抱怨一下這個xx邦的介面好難用.....)
var c = document.getElementById(canvasF);
try { c.getContext("2d") }
catch (e) { canvasIni(); }
這個canvasIni(),是我將excanvas.js裡的函式再包裝成canvasIni()方法,以方便當我存取getContext方法失敗時可以再呼叫canvas初始化一次,至於excanvas.js檔看倌可自行google->excanvas.js,會有很多版本,你可以一一自己試試看各別版本效果有何不同
3.canvas滑鼠事件處理
try {
//非IE
c.addEventListener("mousemove", function (a) {
//滑鼠x位置 a.clientX; 滑鼠在canvas的相對位置a.offsetX; canvas位置 left c.offsetLeft;
if (c == null || c == undefined || (!c)) {
c = document.getElementById(canvasF);
}
var ctx = c.getContext("2d");
//你的畫圖程式放在這
}
catch(e)
{
//IE
c.attachEvent("onmousemove", function (a) {
//滑鼠x位置 a.clientX; 滑鼠在canvas的相對位置a.offsetX; canvas位置 left c.offsetLeft;
if (c == null || c == undefined || (!c)) {
c = document.getElementById(canvasF);
}
var ctx = c.getContext("2d");
//你的畫圖程式放在這
}
由上可看出,滑鼠事件在ie與非ie中,事件名稱不同,其他繪圖方法都一樣,但是這裡有一點要注意,我測試的結果中,IE往往top與left會比其他瀏覽器多了一點點px出來,導致算出來的位置有點偏移
4.治療王子公主病~~IE8
我發現如果網頁內容單純,canvas放在網頁最上面,執行結果都很OK~但是偏偏我家老闆很愛一條龍式的網頁排版,滑鼠中軌捲軸硬是要往下捲了3次以上,才能滑到網頁最後的內容,如果網頁內容很多時,奇怪,原來好好的canvas畫圖就錯了,還一直跟我說錯在var ctx = c.getContext("2d"),在IE8時我明明就有加<!--[if IE]><script type="text/javascript" src="js/excanvasTxt.js"></script><![endif]-->啊
這邊害我卡住非常久,原本以為是excanvas.js裡的方法沒寫好,後來發現,是excanvas在把canvas物件加上event時找不到該物件,WHY?因為ie載入html Object速度較慢,而excanvas.js在執行時html object還沒產生,所以cancas初始化這件事根本沒做~
於是乎~~我只好寫了委派事件(是叫委派嗎?小的才疏學淺不敢確定,但覺得這種寫法很像是委派)
總之就是讓網頁去判斷當html 載入完成後,才去做canvas初始化這件事
//事件listion處理
function waitObject(testobj, fun) {
if (document.readyState != 'complete') {
var c = document.getElementById(testobj);
if (c.attachEvent)//僅針對ie未load完document物件做處理
{ addLoadListener(fun); }
else
{ throw "Broswer is not IE,don't use this function."; }
}
else
{ fun(); }
}
function addLoadListener(fn) {
if (typeof window.addEventListener != 'undefined') {
window.addEventListener('load', fn, false);
}
else if (typeof document.addEventListener != 'undefined') {
document.addEventListener('load', fn, false);
}
else if (typeof window.attachEvent != 'undefined') { //ie
try {
window.attachEvent('onload', fn);
}
catch (e)
{ throw e; }
}
else {
var oldfn = window.onload;
if (typeof window.onload != 'function') {
window.onload = fn;
}
else {
window.onload = function () {
oldfn();
fn();
};
}
}
}
//我將繪圖方法包裝成drawCharBasic(canvasF)這個函式裡,方便後面呼叫引用
var c = document.getElementById(canvasF);
var cfun = function cfunf() { drawCharBasic(canvasF); };
if (c.attachEvent)//IE 特別處理
{ waitObject(canvasF, cfun); }
else
{ drawCharBasic(canvasF); }
沒有demo網頁,真的有人能體會我在寫什麼嗎?.....冏
說實話我沒有推薦什麼library,但是我要說,基本功練好了,library就能輕易上手,大家取方法屬性的名稱都大同小異,基本的會了,library在使用上就難不倒你
我沒有依主題發表適當內容,但是這裡沒有暫存的草稿功能,所以...沒關係,發了就算了
如果你有忍耐著看到這裡,想必看官canvas的功力也增進了不少,但是我要告訴你,還有個東西叫svg,正準備取代canvas....
終於有大大PO文了~~!
小弟的拋磚文 也功成身退 壽終正寢
功成身退,百姓皆曰我自然
ted99tw提到:
自然
我...我數學....
呵呵~~Javascript我也都自己寫一套~
JQ是懶人在用的~除非客戶自己想要那樣的風格~
不然Javascript我都寧願,萬丈高樓平地起~
jer5173提到:
JQ是懶人在用的
難怪大大會怕被列入黑名單...
呵呵~~
jer5173提到:
JQ是懶人
...
jer5173提到:
JQ是懶人
...
還是用YUI好了....
不過這樣最後也是要發展出自己一套框架吧,不然不同瀏覽器的行為處理,也是會累死人的
有些東西不是不交出來,是要人時地利人合,沒有遇到能理解的人,PO出來恐怕沒有人能看懂
如果有空,改天我再寫個svg實做測試版本的好了~~if...
milienchen提到:
人合