1 2 /** 3 * @name CeL function for web 4 * @fileoverview 5 * 本檔案包含了 web 的 functions。 6 * @since 7 */ 8 9 /* 10 http://www.comsharp.com/GetKnowledge/zh-CN/It_News_K902.aspx 11 http://www.nczonline.net/blog/2010/01/12/history-of-the-user-agent-string/ 12 當 IE 初次推出它們的 User Agent 標誌的時候,是這個樣子: 13 MSIE/3.0 (Win95; U) 14 15 TODO: 16 don't use .innerHTML 17 通盤確認所有 HTMLElement 變數已經設成 null 18 19 20 功能探測 vs 瀏覽器探測 21 http://www.comsharp.com/GetKnowledge/zh-CN/It_News_K987.aspx 22 Mark Pilgrim 有一個清單,它可以讓你探測任何功能。 23 http://diveintohtml5.org/everything.html 24 25 */ 26 27 if (typeof CeL === 'function') 28 CeL.setup_module('interact.DOM', 29 { 30 require : 'data.code.compatibility.is_DOM|data.split_String_to_Object', 31 code : function(library_namespace, load_arguments) { 32 33 // requiring 34 var is_DOM,split_String_to_Object; 35 eval(library_namespace.use_function(this)); 36 37 38 /** 39 * null module constructor 40 * @class web 的 functions 41 */ 42 CeL.interact.DOM 43 = function() { 44 // null module constructor 45 }; 46 47 /** 48 * for JSDT: 有 prototype 才會將之當作 Class 49 */ 50 CeL.interact.DOM 51 .prototype = { 52 }; 53 54 55 56 57 58 59 /* 60 HTML only ------------------------------------------------------- 61 */ 62 63 /** 64 * NodeType: const unsigned short. 65 * @see 66 * http://www.w3.org/TR/2004/REC-DOM-Level-3-Core-20040407/core.html#ID-1950641247 67 * http://www.w3.org/TR/DOM-Level-2-Core/core.html 68 * ELEMENT_NODE,ATTRIBUTE_NODE,TEXT_NODE,CDATA_SECTION_NODE,ENTITY_REFERENCE_NODE,ENTITY_NODE,PROCESSING_INSTRUCTION_NODE,COMMENT_NODE,DOCUMENT_NODE,DOCUMENT_TYPE_NODE,DOCUMENT_FRAGMENT_NODE,NOTATION_NODE 69 * @inner 70 */ 71 var ELEMENT_NODE = 1, 72 TEXT_NODE = 3, 73 DOCUMENT_NODE = 9; 74 75 if(is_DOM('document') && 76 // IE8: undefined 77 !isNaN(document.ELEMENT_NODE)) 78 ELEMENT_NODE = document.ELEMENT_NODE, 79 TEXT_NODE = document.TEXT_NODE, 80 DOCUMENT_NODE = document.DOCUMENT_NODE; 81 82 // IE 中 Object.prototype.toString.call(HTML Element)==='[object Object]', 得用 ''+node 83 var get_object_type = Object.prototype.toString, 84 element_pattern = /^\[object HTML([A-U][A-Za-z]{1,15})?Element\]$/; 85 86 87 88 CeL.interact.DOM 89 . 90 /** 91 * 判斷是否為 HTML Element。 92 * @param value value to test 93 * @return {Boolean} value is HTML Element 94 * @since 2010/6/23 02:32:41 95 * @memberOf CeL.interact.DOM 96 * @see 97 * http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-58190037, 98 * http://www.w3.org/DOM/ 99 */ 100 is_HTML_element = function(value) { 101 // return get_object_type.call(value).indexOf('[object HTML')===0; 102 return element_pattern.test(get_object_type.call(value)) 103 || '[object Text]' === get_object_type.call(value) 104 && value.nodeType === TEXT_NODE; 105 // return get_object_type.call(value).match(element_pattern); 106 }; 107 108 CeL.interact.DOM 109 . 110 /** 111 * 判斷為指定 nodeType 之 HTML Element。 112 * @param value value to test 113 * @param type type 114 * @return {Boolean} value is the type of HTML Element 115 * @since 2010/6/23 02:32:41 116 * @memberOf CeL.interact.DOM 117 * @see 118 * http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-58190037, 119 * http://www.w3.org/DOM/ 120 */ 121 is_HTML_element_type = function(value, type) { 122 return type === TEXT_NODE ? 123 '[object Text]' === get_object_type.call(value) && value.nodeType === TEXT_NODE 124 : element_pattern.test(get_object_type.call(value)) && value.nodeType === type; 125 }; 126 127 CeL.interact.DOM 128 . 129 /** 130 * 判斷為 HTML Element。 131 * @param value value to test 132 * @return {Boolean} value is HTML Element 133 * @since 2010/6/23 02:32:41 134 * @memberOf CeL.interact.DOM 135 * @see 136 * http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-58190037, 137 * http://www.w3.org/DOM/ 138 */ 139 is_element_node = function(value) { 140 //library_namespace.debug('Test '+get_object_type.call(value)+' '+((typeof value==='object'||typeof value==='function')&&value.nodeType||'')+': '+element_pattern.test(get_object_type.call(value))+','+(value.nodeType === 1)); 141 return element_pattern.test(get_object_type.call(value)) && value.nodeType === ELEMENT_NODE; 142 }; 143 144 145 /* 146 147 IE5DOM @ IE9 test: 148 IE7DOM @ IE9 test: 149 node <DIV>: type object, toString.call: [object Object], ""+node: [object], nodeType: 1: 150 151 IE8: 152 IE8DOM @ IE9 test: 153 IE9DOM @ IE9 test: 154 node <DIV>: type object, toString.call: [object Object], ""+node: [object HTMLDivElement], nodeType: 1: 155 156 IE8: 157 node <A>: type object, toString.call: [object Object], ""+node: , nodeType: 1: 158 node <OBJECT>: type object, toString.call: [object Object], ""+node: [object], nodeType: 1: 159 160 */ 161 function show_node(node) { 162 if(_.is_element_node(node)) 163 library_namespace.debug('node' 164 + (node.tagName ? ' <' + node.tagName 165 + (node.id ? '#' + node.id : '') + '>' : '') + ': type ' 166 + typeof node + ', toString.call: ' + get_object_type.call(node) 167 + ', ""+node: ' + ('' + node) + ', nodeType: ' + node.nodeType 168 + ('innerHTML' in node ? ': ' + node.innerHTML : '')); 169 } 170 171 try { 172 // workaround for IE, 因用 General type, 效能較差 173 var d = document.createElement('div'), s; 174 // alert('toString test: ' + element_pattern.test(get_object_type.call(d))); 175 176 if(d.nodeType !== ELEMENT_NODE) 177 // doesn't support W3C DOM? 178 throw 0; 179 180 if (!(s = element_pattern.test(get_object_type.call(d)))) { 181 if (element_pattern.test('' + d)) 182 // IE8-9 183 _.is_HTML_element = function(value) { 184 return element_pattern.test('' + value) 185 // for IE8. value 可能是 null! 186 || typeof value === 'object' && value !== null && value.nodeType === ELEMENT_NODE// && value.tagName === "OBJECT" 187 && "[object NamedNodeMap]" === '' + value.attributes; 188 }; 189 else if (get_object_type.call(d) === '[object Object]') 190 // IE5-7, 這種判別方法有漏洞! 191 _.is_HTML_element = function(value) { 192 return '[object Object]' === get_object_type.call(value) && value !== null && typeof value.nodeType === 'number'; 193 }; 194 else 195 throw 1; 196 197 // General type 198 _.is_HTML_element_type = function(value, type) { 199 return _.is_HTML_element(value) && value.nodeType === type; 200 }; 201 _.is_element_node = function(value) { 202 return _.is_HTML_element(value) && value.nodeType === ELEMENT_NODE; 203 }; 204 } 205 206 } catch (e) { 207 // TODO: handle exception 208 } finally { 209 d = null; 210 } 211 212 213 214 /* test if can use flash 215 216 better use SWFObject: 217 http://code.google.com/p/swfobject/ 218 219 Browser detect: http://www.quirksmode.org/js/detect.html 220 var plugin=(window.navigator.mimeTypes && window.navigator.mimeTypes["application/x-shockwave-flash"]) ? window.navigator.mimeTypes["application/x-shockwave-flash"].enabledPlugin : 0; 221 if ( plugin ) { 222 plugin=parseInt(plugin.description.substring(plugin.description.indexOf(".")-1)) >= 3; 223 } 224 else if (window.navigator.userAgent && window.navigator.userAgent.indexOf("MSIE")>=0 && window.navigator.userAgent.indexOf("Windows")>=0) { 225 document.write('<SCRIPT LANGUAGE=VBScript\> \n'); 226 document.write('on error resume next \n'); 227 document.write('plugin=( IsObject(CreateObject("ShockwaveFlash.ShockwaveFlash.6")))\n'); 228 document.write('<\/SCRIPT\> \n'); 229 } 230 if ( plugin ) { 231 document.write('<OBJECT classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'); 232 document.write(' codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0" '); 233 document.write(' ID=flash5clickTAG WIDTH='+n_width+' HEIGHT='+n_height+'>'); 234 document.write(' <PARAM NAME=movie VALUE="'+ n_flashfile +'"><param name=wmode value=opaque><PARAM NAME=loop VALUE=true><PARAM NAME=quality VALUE=high> '); 235 document.write(' <EMBED src="'+ n_flashfile +'" loop=true wmode=opaque quality=high '); 236 document.write(' swLiveConnect=FALSE WIDTH='+n_width+' HEIGHT='+n_height+''); 237 document.write(' TYPE="application/x-shockwave-flash" PLUGINSPAGE="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash">'); 238 document.write(' <\/EMBED>'); 239 document.write(' <\/OBJECT>'); 240 } else if (!(window.navigator.appName && window.navigator.appName.indexOf("Netscape")>=0 && window.navigator.appVersion.indexOf("2.")>=0)){ 241 document.write('<A HREF="'+ n_altURL +'" target="'+n_target+'"><IMG SRC="'+ n_altimg +'" WIDTH='+n_width+' HEIGHT='+n_height+' BORDER=0><\/A>'); 242 } 243 */ 244 245 // copy from base.js 246 //window.onerror=HandleError; 247 function HandleError(message, url, line) { 248 // if(window.confirm())_DO_CONTINUE_ 249 if (window.navigator.appName == "Microsoft Internet Explorer") 250 return !window.confirm(url + '\n\nJavaScript Error: ' + line 251 + '\n' + message + '\n\nSee more details?'); 252 else if (window.navigator.appName == "Netscape") 253 // document.location.href="javascript:"; 254 window.navigate('javascript:'); 255 256 //return message; 'Warning: function HandleError does not always return a value' in some Firebird with user_pref("javascript.options.strict", true); @ prefs.js 257 } 258 259 //window.onresize=OnResize; // 預防(舊版)NS resize時版面亂掉 260 function OnResize() { 261 // 回上一頁 history.go(-1),history.back()/history.forward() this.location.replace(document.referrer) 262 // Opera's document.referrer returns only null if referrer logging is disabled 263 //location.replace(),location.reload() 264 history.go(0); 265 } 266 267 /* 268 IE only!! 269 http://blog.livedoor.jp/dankogai/archives/50952477.html DOM時代のdocument.write() 270 271 if (typeof document == 'object') 272 write = document.write; 273 */ 274 275 /* 276 http://blog.taragana.com/index.php/archive/how-to-enable-windowstatus-in-firefox/ 277 window.status在firefox下默認是不能修改的。 278 可以通過工具->選項->網頁特性->啟用javascript->高級->把修改狀態欄文本打上勾就好了。 279 280 Open about:config in browser and search for dom.disable_window_status_change. Change it to false. 281 Additionally in Firefox v1.0, this can be changed via "Tools → Options → Web Features → Enable JavaScript / Advanced → Allow scripts to change status bar text" 282 In Firefox v1.5, this can be changed via "Tools → Options → Content → Enable JavaScript / Advanced → Allow scripts to change status bar text" 283 via MozillaZine; learnt the hard way. 284 */ 285 function RollStatus(m,v,from,RollStatusL){//message,速度velocity,from where,unit length(基本上後兩者勿設定) 286 var s=' ';//間隔以s 287 if(!RollStatusL)RollStatusL=m.length,m+=s+m;if(!from||from>=RollStatusL+s.length)from=0; 288 if(!m)if(window.status)RollStatus(window.status,v);else return;else if(m.slice(from)!=window.status&&m.length>L)return; 289 var L=99,V=v||999;//L:least length 290 while(m.length<L)m+=s+m; 291 window.status=m.slice(++from); 292 RollStatusS=window.setTimeout('RollStatus("'+m+'",'+V+','+from+','+RollStatusL+');',V); 293 //RollStatusS=window.setInterval('RollStatus("'+m+'",'+V+','+from+')',V) 294 } 295 296 // ↑copy from base.js 297 298 299 /* 預防hack:禁止鍵盤keyboard&滑鼠mouse輸入,可以再加上一層div於最上方以防止copy 300 下面一行調到檔案頭 301 var disabledKM=0; 302 */ 303 //disableKM[generateCode.dLK]='disabledKM'; 304 function disableKM(s,m){ // s=1:回復,s=2:使螢幕亦無法捲動(對NS無效),m:message,輸入時發出警告 305 /* 306 window.onerror=function(){return ture;}; 307 // 定義亦可用 function document.onmousedown(){..} 308 document.onmousedown=document.oncontextmenu=document.onselectstart=document.ondragstart=function(e){return false;}; 309 // 印刷を禁止して 310 window.onbeforeprint=function(){for(i=0;i<document.all.length;i++){if(document.all[i].style.visibility!="hidden"){document.all[i].style.visibility="hidden";document.all[i].id="elmid";}}}; 311 window.onafterprint=function(){for(i=0;i<document.all.length;i++){if(document.all[i].id=="elmid"){document.all[i].style.visibility="";}}}; 312 */ 313 if(!document.body)return; 314 if(typeof s=='undefined')s=1; 315 if(typeof disabledKM=='undefined')disabledKM=0; 316 317 if(!s){ 318 if(disabledKM){ 319 ondragstart=document.body.Oondragstart||null, 320 oncontextmenu=document.body.Ooncontextmenu||null, 321 onselectstart=document.body.Oonselectstart||null; 322 with(window.document.body) 323 if(disabledKM==2)style.overflow=typeof document.body.Ooverflow=='string'?Ooverflow:'auto'; 324 onmousedown=window.Oonmousedown||null, 325 onkeydown=window.Oonkeydown||null; 326 onmousedown=document.Oonmousedown||null, 327 onkeydown=document.Oonkeydown||null; 328 } 329 disabledKM=0; 330 return; 331 } 332 333 if(disabledKM){with(document.body) // 已lock時不執行多餘的動作與覆蓋舊資訊 334 if(s==2)style.overflow='hidden'; 335 else if(typeof document.body.Ooverflow=='string')style.overflow=Ooverflow; 336 }else{ 337 // <body oncontextmenu="return false" ondragstart="return false" onselectstart="return false"> 338 with(document.body){ // 預防hack 339 //leftMargin=topMargin=rightMargin=bottomMargin=0; // 使body填滿視窗 340 document.body.Ooverflow=style.overflow; 341 if(s==2)style.overflow='hidden'; // 使螢幕亦無法捲動 342 if(typeof onselectstart!='undefined')document.body.Oonselectstart=onselectstart; 343 if(typeof oncontextmenu!='undefined')document.body.Ooncontextmenu=oncontextmenu; 344 if(typeof ondragstart!='undefined')document.body.Oondragstart=ondragstart; 345 ondragstart=oncontextmenu=onselectstart= 346 //new Function("return false;"); 347 function(){return false;}; 348 } 349 // 不要在 document 对象中设置 expando 属性,在 window 对象上设置 expando 属性。 350 with(window){ 351 if(typeof onmousedown!='undefined')document.Oonmousedown=onmousedown; 352 if(typeof onkeydown!='undefined')document.Oonkeydown=onkeydown; 353 } 354 with(window.document){ 355 //ndblclick= 356 if(typeof onmousedown!='undefined')document.Oonmousedown=onmousedown; 357 if(typeof onkeydown!='undefined')document.Oonkeydown=onkeydown; 358 } 359 } 360 window.onmousedown=window.onkeydown=document.onmousedown=document.onkeydown=document.onContextMenu 361 =new Function('e', 362 'if(window.navigator.appName=="Microsoft Internet Explorer"&&event.button!=1||window.navigator.appName=="Netscape"&&e.which!=1){' 363 +(m?'alert('+dQuote(m)+');':'')+'return false;}'); 364 /* 365 'if(window.navigator.appName=="Microsoft Internet Explorer"\ 366 &&event.button!=1||window.navigator.appName=="Netscape"&&e.which!=1){'+(m?'alert('+dQuote(m)+');':'')+'return false;}'); 367 */ 368 369 // window.captureEvents(Event.MOUSEUP|Event.MOUSEDOWN); 370 // window.onmousedown=function(e){if(e.which==1){window.captureEvents(Event.MOUSEMOVE);window.onmousemove=rf;}}; 371 // window.onmouseup=function(e){if(e.which==1){window.releaseEvents(Event.MOUSEMOVE);window.onmousemove=null;}}; 372 // Navigator 4.0x 373 // http://topic.csdn.net/t/20020125/13/498661.html 374 if(!disabledKM && window.Event && window.captureEvents) 375 window.captureEvents(Event.MOUSEDOWN), 376 window.captureEvents(Event.KEYDOWN); 377 378 disabledKM=s; 379 }; 380 381 382 CeL.interact.DOM 383 . 384 /** 385 * toggle/swap display and visibility. 386 * display:none or visibility:hidden. 387 * TODO: computed style 388 * @param element HTML element 389 * @param {String|Number} type show or hidden or set the status type: 390 * {Number} type: 0: hidden(→none), 1: show(→block), 2||undefined: switch, others: get status only with no change 391 * {String} type: set CSS: display type: none, '', block, inline, list-item. 其他恐造成 error? 392 * @return display status 393 * @since 2010/4/1 10:24:43 rewrite 394 * @see 395 * http://www.w3schools.com/CSS/pr_class_visibility.asp 396 * http://www.w3schools.com/css/pr_class_display.asp 397 * http://www.javaeye.com/topic/140784 398 * 通過element.style對象只能取得內聯的樣式,也就是說只能取得html標籤裡寫的屬性。 399 * @requires [_.get_element],[_.get_style] 400 * @memberOf CeL.interact.DOM 401 */ 402 toggle_display = function(element, type){ 403 // showObj(div); 404 if (typeof element === 'string') 405 element = typeof _.get_element === 'function' ? _.get_element(element) 406 : document.getElementById(element); 407 408 if (!element) 409 return; 410 411 // Opera 7.5 意外的沒有 tagName (-_-) 而 Firefox 也可能沒有此 property 412 var tagName = ('' + element.tagName).toLowerCase(), style = element.style, 413 v_value = {'visible':1, 'hidden': 2, 'collapse': 3}; 414 415 if (typeof type === 'undefined' || type == 2) 416 type = style ? 417 (_.get_style ? _.get_style(element, 'display') : 418 // style.display === '' 時預設為顯示 419 style.display) === 'none' 420 : element.visibility !== 'visible'; 421 422 if (typeof type === 'boolean') 423 type = type ? 1 : 0; 424 425 if (!isNaN(type)) 426 type = type == 0 ? style ? 'none' : tagName === 'tr' ? 'collapse' : 'hidden' 427 : type == 1 ? style ? (tagName in {'div':1, 'iframe':1}) ? 'block' : 'inline' : 'visible' 428 : null; 429 430 // test .innerHTML 431 432 //library_namespace.debug('set display style to [' + type + ']'); 433 if (style) 434 style[type in v_value? 'visibility' : 'display'] = type; 435 else if(type in v_value)// &&!(tagName in {'iframe':1,'input':1}) 436 element.visibility = type; 437 else return; 438 439 return type; 440 }; 441 //simpleWrite('a.txt',reduceCode([f,toggle,setObjValue])); 442 //for(var i in style)tt+=i+'='+document.getElementById("others").style[i]+"<br/>";document.write(tt); 443 444 445 446 CeL.interact.DOM 447 . 448 /* http://blog.stevenlevithan.com/archives/faster-than-innerhtml 449 You can use the above as el = replace_HTML(el, newHtml) instead of el.innerHTML = newHtml. 450 451 .innerHTML=,document.createElement(→XML_node() 452 .innerHTML='' → remove_all_child 453 454 455 http://forum.moztw.org/viewtopic.php?t=17984&postdays=0&postorder=asc&start=15 456 adoptNode() 會把現有的節點拿去用,ownerDocument 會被變更,被 adopt 的節點會從原來的 document 消失。 457 importNode() 比較像是 cloneNode() 加上變更 ownerDocument。 458 以前因為 Gecko 沒有太嚴格,所以可以用 Ajax 取回一個 XML 文件並直接透過 responseXML 把裡面的節點當 HTML 節點一樣的插入現有的網頁。 459 */ 460 /** 461 * replace HTML 462 * @param o 463 * @param html 464 * @return 465 * @memberOf CeL.interact.DOM 466 */ 467 replace_HTML = function(o, html){ 468 if (typeof o === 'string') 469 o = document.getElementById(o); 470 if (!o || typeof o !== 'object') 471 return; 472 try{ 473 /*@cc_on // Pure innerHTML is slightly faster in IE 474 o.innerHTML=html||''; 475 return o; 476 @*/ 477 var n = o.cloneNode(false); 478 n.innerHTML = html || ''; 479 o.parentNode.replaceChild(n, o); 480 }catch (e) { 481 library_namespace.err(e); 482 } 483 // Since we just removed the old element from the DOM, return a reference to the new element, which can be used to restore variable references. 484 return n; 485 }; 486 487 /* 488 使用.firstChild或.lastChild須注意此node可能是text node,不能appendChild。須以.nodeType判別。 489 490 http://msdn2.microsoft.com/zh-tw/library/system.xml.xmlnode.removechild(VS.80).aspx 491 繼承者注意事項 在衍生類別中覆寫 RemoveChild 時,為了要正確引發事件,您必須呼叫基底類別的 RemoveChild 方法。 492 493 removeAllChild[generateCode.dLK]='replace_HTML'; 494 function removeAllChild(o){ 495 //return removeNode(o,1); 496 497 // http://blog.stevenlevithan.com/archives/faster-than-innerhtml 498 if(typeof o=='string')o=document.getElementById(o); 499 if(!o||typeof o!='object')return; 500 o.parentNode.replaceChild(o.cloneNode(false),o); 501 return o; 502 } 503 504 http://www.webreference.com/js/column43/replace.html 505 The replaceNode method is much more intuitive than the removeNode method. While the removeNode method just removes the specified element and makes its descendents children of their grandfather, the replaceNode method deletes the whole subtree that is rooted at the specified element, and substitutes it with a new element. 506 node_want_to_replace.removeNode(new_node) 507 */ 508 CeL.interact.DOM 509 . 510 /** 511 * 移除 node. 512 * TODO: 513 * also remove event handlers 514 * @param o 515 * @param tag tag===1: only child, undefined: remove only self, others: only <tag> child 516 * @return 517 * @memberOf CeL.interact.DOM 518 */ 519 remove_node = function remove_node(o, tag) { 520 var _f = remove_node, i; 521 if (typeof o === 'string') 522 o = document.getElementById(o); 523 if (!o || typeof o !== 'object') 524 return; 525 526 // remove child 527 if (tag) { 528 if (typeof tag === 'string') 529 tag = tag.toLowerCase(); 530 531 // safer: if you have any asynchronous events going. But node.hasChildNodes() will always do an evaluation. 532 //while(o.hasChildNodes()&&(i=o.firstChild))o.removeChild(i); 533 534 // don't use for() 535 // http://weblogs.macromedia.com/mesh/archives/2006/01/removing_html_e.html 536 // TODO: 直接用 replaceNode 就不用 recursion 537 i = o.childNodes.length; 538 while (i--) 539 if (tag === 1 || tag == o.childNodes[i].tagName.toLowerCase()) 540 // _f(o.childNodes[i],tag), // TODO: 會有問題 541 o.removeChild(o.childNodes[i]); 542 } 543 544 // remove self 545 // 測試 o.parentNode: 預防輸入的o為create出來的 546 return tag || !(i = o.parentNode) ? o : i.removeChild(o); 547 }; 548 549 CeL.interact.DOM 550 . 551 remove_all_child = _.replace_HTML; 552 553 554 555 556 557 CeL.interact.DOM 558 . 559 /** 560 * set/get/remove attribute of a element<br/> 561 * in IE: setAttribute does not work when used with the style attribute (or with event handlers, for that matter). 562 * @param _e element 563 * @param propertyO attributes object (array if you just want to get) 564 * @return 565 * @requires split_String_to_Object 566 * @see 567 * setAttribute,getAttribute,removeAttribute 568 * http://www.quirksmode.org/blog/archives/2006/04/ie_7_and_javasc.html 569 * @since 2006/12/10 21:25 分離 separate from XML_node() 570 * @memberOf CeL.interact.DOM 571 */ 572 set_attribute = function(_e, propertyO, ns) { 573 if (typeof _e === 'string') 574 _e = typeof _.get_element === 'function' ? _.get_element(_e) 575 : document.getElementById(_e); 576 if (!_e || !propertyO/* ||_e.nodeType==3/* TEXT_NODE */) 577 return; 578 579 var _l,_m,_g, 580 // Namespaces:SVG,MathML,XHTML,XLink 581 _N=_.new_node.ns; 582 if (typeof propertyO == 'string') 583 propertyO = /[=:]/.test(propertyO) ? split_String_to_Object(propertyO) 584 : propertyO.split(','); 585 if (propertyO instanceof Array) 586 _g = propertyO.length == 1 ? propertyO[0] : 1, 587 propertyO = split_String_to_Object(propertyO.join(',')); 588 589 for (_l in propertyO) { 590 if (_l == 'class' && !propertyO['className']) 591 propertyO[_l = 'className'] = propertyO['class']; 592 if (_g || (_l in propertyO) && propertyO[_l] != null) 593 if(_l=='className'||typeof propertyO[_l]=='function')if(_g)propertyO[_l]=_e[_l];else _e[_l]=propertyO[_l];//_l=='id'|| 594 /* 595 XML 中id不能以setAttribute設定。 596 class不能以setAttribute設定@IE。 597 http://www.quirksmode.org/bugreports/archives/2005/03/setAttribute_does_not_work_in_IE_when_used_with_th.html 598 IE ignores the "class" setting, and Mozilla will have both a "class" and "className" attribute defined 599 */ 600 else if (_e.setAttributeNS 601 && (_m = _l.match(/^(.+):([^:]+)$/))) { 602 _m = _m[1]; 603 if (_m.indexOf('://') == -1 && _N[_m.toLowerCase()]) 604 _m = 'http://www.w3.org/' + _N[_m.toLowerCase()]; 605 if (_g) 606 propertyO[_l] = _e.getAttributeNS(_m, _l); 607 else 608 _e.setAttributeNS(_m, _l, propertyO[_l]);// try{_e.setAttributeNS(_m,_l,propertyO[_l]);}catch(e){alert('set_attribute: 609 // Error!');} 610 } else if (_g) 611 propertyO[_l] = _e.getAttribute(_l); 612 else 613 _e.setAttribute(_l, propertyO[_l]);// _e.setAttributeNS?_e.setAttributeNS(null,_l,propertyO[_l]):_e.setAttribute(_l,propertyO[_l]); 614 } 615 616 return typeof _g == 'string' ? propertyO[_g] : propertyO; 617 }; 618 619 620 CeL.interact.DOM 621 . 622 /** 623 * append children node to specified element 624 * @param node node / node id 625 * @param child_list children node array 626 * @return 627 * @since 2007/1/20 14:12 628 * @memberOf CeL.interact.DOM 629 */ 630 add_node = function add_node(node, child_list) { 631 var _s = add_node; 632 if (typeof node === 'string') 633 node = typeof _.get_element === 'function' ? _.get_element(node) 634 : document.getElementById(node); 635 636 if (node && arguments.length > 2) { 637 for ( var _j = 1, l = arguments.length; _j < l; _j++) 638 _s(node, arguments[_j]); 639 return; 640 } 641 642 if (!node || !child_list 643 // || node.nodeType == 3/* TEXT_NODE */ 644 ) 645 return; 646 647 // 預防 RegExp 等,需要 toString() 648 if (child_list instanceof RegExp) 649 child_list = ''; 650 651 if (typeof child_list === 'object') { 652 if (child_list) 653 if (child_list instanceof Array 654 // && child_list.length 655 ) 656 for ( var _j = 0, l = child_list.length; _j < l; _j++) 657 _s(node, child_list[_j]); 658 else 659 node.appendChild(child_list); 660 return; 661 } 662 if (typeof child_list === 'number' && !isNaN(child_list)) 663 // child_list=child_list.toString(); 664 child_list += ''; 665 if (typeof child_list === 'string') { 666 var tag_name = node.tagName.toLowerCase(); 667 if (tag_name === 'textarea' || tag_name === 'select' || tag_name === 'option' 668 || (tag_name === 'input' && node.type === 'text')) 669 node.value = child_list; 670 else if (tag_name === 'option') { 671 if (!node.value) 672 node.value = child_list; 673 node.innerHTML = child_list; 674 } else if (child_list.indexOf('<') != -1) 675 // may cause error: -2146827687 未知的執行階段錯誤 e.g., XML_node('a',0,0,[XML_node('a'),'<br/>']); 676 //try{ 677 node.innerHTML += child_list; 678 //}catch(e){node.appendChild(XML_node('span',0,0,child_list));} 679 680 else 681 //try{ 682 node.appendChild(document.createTextNode(child_list)); 683 //}catch(e){alert(e.description);} 684 685 // else alert('add_node: Error insert contents:\n['+child_list+']'); 686 } 687 }; 688 689 690 /* 691 692 var alias={ 693 // 'child' || 'c' || '$' || '0' || .. 694 $:'childNode', 695 // class: 'className' || 'c' .. 696 c:'className' 697 s:'style' 698 }; 699 700 輸入 ( [{tag1:{attb:attb_val,child:[inner objects]}}, {tag2:{}}, 'br'], insertBeforeO) 701 e.g., 702 ([ 703 { 704 p:[span:'>>test<<'], 705 id:'a', 706 c:'cls', 707 s:{color:'#123'} 708 }, 709 // width:12 === width:'12px' 710 { 711 span:['<<test2>>','text'], 712 s:{color:'',width:12} 713 }, 714 '<<test3>>', 715 {'hr':0}, 716 {'br':0}, 717 { 718 $:tag_name, 719 tag_name:[] 720 }, 721 { 722 tag_ns:0, 723 ns:'http://~' 724 } 725 ], insertSetting) 726 727 insertSetting: 728 (null) just create & return the node 729 以下:===0 則設成 document.body 730 parent/id appendChild 731 [refO,0-4] 0:appendChild (add as lastChild), 1: add as firstChild, 2: add as nextSibling, 3: add as priviusSibling, 4: add as parent 732 733 734 */ 735 //[{tag1:{attb:attb_val,child:[inner objects]}}, {tag2:{}}, 'br']; 736 737 738 739 CeL.interact.DOM 740 . 741 /** 742 * 創建新的 DOM 節點(node)。 743 * createNode() 的功能補充加強版。 744 * TODO: 分割功能(set_attrib, add_child, ..), 簡化 745 * @param {Object|Array} nodes node structure 746 * @param {String|Array|HTMLElement} [layer] where to layer this node. e.g., parent node 747 * @return {HTMLElement} new node created 748 * @since 2010/6/21 13:45:02 749 */ 750 new_node = function(nodes, layer) { 751 var _s = _.new_node, node, for_each, 752 // parent: parent node of layer or layer.firstChild 753 parent, 754 children, 755 handle = _s.handle; 756 757 if (!is_DOM('document') 758 || !document.createElement 759 //&& !document.createElementNS 760 ) { 761 library_namespace.warn('new_node: DOM error? Cannot create node [' + nodes + '].'); 762 return; 763 } 764 765 if (typeof nodes === 'number') 766 //.toString(); 767 nodes += ''; 768 769 if (library_namespace.is_Object(nodes)) { 770 var tag = nodes.$, n = 'className', ns, s, ignore = { 771 // tag 772 $ : null, 773 // attrib 774 A : null 775 /* 776 // namespace 777 NS : null, 778 // class 779 C : null, 780 // style 781 S : null 782 */ 783 }; 784 785 if (typeof tag === 'undefined') 786 for (node in nodes) 787 if(!(node in ignore)){ 788 tag = node; 789 break; 790 } 791 else if (tag === 0) { 792 // 0: just set attributes 793 if (!_.is_element_node(layer)) { 794 library_namespace.warn('new_node: There is no tag and the layer is NOT a HTML Element!'); 795 return; 796 } 797 tag = layer; 798 }else if (typeof tag !== 'undefined') 799 node = tag; 800 801 // set/create node 802 if (_.is_HTML_element(tag)) 803 node = tag; 804 805 else if (typeof tag !== 'string'){ 806 library_namespace.err('new_node: Error create tag: ['+(typeof tag)+'][' + tag + ']'); 807 return; 808 809 } else { 810 if ('NS' in nodes) 811 ignore.NS = null, 812 ns = nodes.NS; 813 else if (s = tag.match(/^(.+):([^:]+)$/)) 814 tag = s[2], ns = s[1]; 815 816 try { 817 if (ns && document.createElementNS) { 818 if (ns in (s = _s.ns)) 819 ns = 'http://www.w3.org/' + s[ns]; 820 node = document.createElementNS(ns, tag); 821 } else 822 node = tag ? document.createElement(ns ? ns + ':' + tag : tag) 823 //: document.createTextNode(); 824 // 由後面判定。 825 : nodes[tag]; 826 } catch (_e) { 827 library_namespace.err('new_node: Error create tag: [' + tag + ']'); 828 node = null; 829 return; 830 } 831 } 832 833 if (_.is_element_node(node)) { 834 s = node.setAttributeNS ? function(n, v) { 835 if (library_namespace.is_Function(v)) { 836 node[n] = v; 837 // TODO: _.add_listener(); 838 return; 839 } 840 var _n = n.match(/^(.+):([^:]+)$/); 841 if (_n) 842 n = _n[2], _n = _n[1]; 843 if (_n) 844 node.setAttributeNS( 845 _n in _s.ns ? 'http://www.w3.org/' 846 + _s.ns[_n] : ns, n, v); 847 else 848 node.setAttribute(n, v); 849 } : function(n, v) { 850 if (library_namespace.is_Function(v)) 851 node[n] = v; 852 else 853 node.setAttribute(n, v); 854 }; 855 856 // 對常用的特別處理 857 // class name 858 /* 859 XML 中id不能以setAttribute設定。 860 class不能以setAttribute設定@IE。 861 http://www.quirksmode.org/bugreports/archives/2005/03/setAttribute_does_not_work_in_IE_when_used_with_th.html 862 IE ignores the "class" setting, and Mozilla will have both a "class" and "className" attribute defined 863 */ 864 if ((n in nodes) || ((n = 'class') in nodes) || ((n = 'C') in nodes)) 865 ignore[n] = null, 866 node.className = nodes[n]; 867 868 // IE 需要先 appendChild 才能操作 style,moz不用..?? 869 // http://www.peterbe.com/plog/setAttribute-style-IE 870 // 或需要將 font-size -> fontSize 之類? 871 // IE6 (no firefox or IE7~) 可設定: 872 // oNewDiv.style.setAttribute('border', '1px solid #000'); 873 // oNewDiv.style.setAttribute('backgroundColor', '#fff'); 874 if (((n = 'style') in nodes) || ((n = 'S') in nodes)) { 875 ignore[n] = null; 876 n = nodes[n]; 877 var i, style = node.style; 878 if (typeof n === 'string') 879 style.cssText = n; 880 else if (library_namespace.is_Object(n)) 881 for (i in n) 882 // is_IE?"styleFloat":"cssFloat" 883 style[i === 'float' ? 'cssFloat' in style ? 'cssFloat' : 'styleFloat' : i] = n[i]; 884 else 885 library_namespace.warn('new_node: Error set style: [' + styleO + ']'); 886 } 887 888 // children nodes 889 ignore[tag] = null; 890 children = nodes[tag]; 891 892 // 自動作 list 的轉換 893 if (tag in { 894 ol : 1, 895 ul : 1 896 } && library_namespace.is_Array(children)) 897 { 898 var i = 0, o = [], l = children.length, t, c, change = false; 899 for (; i < l; i++) 900 if (c = children[i]) { 901 t = typeof c === 'string' 902 || typeof c === 'number'; 903 if (!t && library_namespace.is_Object(t)) { 904 t = c.$; 905 if (!t) 906 for (t in c) 907 break; 908 t = t.toLowerCase() !== 'li'; 909 } 910 911 if(t) 912 change = true; 913 o.push(t ? { 914 li : c 915 } : c); 916 } 917 918 // 盡量別動到原來的 919 if (change) 920 children = o; 921 922 }else if(tag === 'select' && library_namespace.is_Object(children)){ 923 var i; 924 for (i in children) 925 break; 926 927 if (i !== 'option') { 928 var o = []; 929 for (i in children) 930 o.push( { 931 option : children[i], 932 value : i 933 }); 934 935 // 盡量別動到原來的 936 children = o; 937 } 938 } 939 940 941 // attributes 942 if('A' in nodes){ 943 var a = nodes.A; 944 if (typeof a === 'string') 945 a = split_String_to_Object(a); 946 947 for (n in a) 948 s(n, a[n]); 949 } 950 951 for (n in nodes) 952 if (!(n in ignore)){ 953 //library_namespace.debug('new_node: set attribute ['+n+'] = ['+nodes[n]+']'), 954 s(n, nodes[n]); 955 //library_namespace.debug('new_node: get attribute ['+n+'] = ['+node.getAttribute(n)+']'); 956 } 957 } else if(tag && !_.is_HTML_element(node)) 958 show_node(node), 959 library_namespace.warn('new_node: node is not a HTML Element!'); 960 961 } else if (typeof nodes !== 'string' && !library_namespace.is_Array(nodes) 962 && isNaN(nodes.nodeType)) { 963 // for Safari: library_namespace.is_Array(nodes) 964 if(nodes) 965 library_namespace.warn('new_node: Unknown nodes [' + nodes + ']'); 966 967 node = null; 968 return; 969 } else 970 node = nodes; 971 972 973 // layer 處理: 插入document中。 974 if (typeof layer !== 'undefined' && layer !== null) { 975 // 正規化 layer 976 // for_each: type→deal function 977 if (library_namespace.is_Function(layer)) 978 for_each = layer; 979 else { 980 if (library_namespace.is_Array(layer)) 981 for_each = layer[1], layer = layer[0]; 982 983 if (layer === 0) 984 layer = document.body; 985 else if (typeof layer === 'string') 986 layer = _.get_element(layer); 987 // [object HTMLLIElement] 988 if (!_.is_element_node(layer)) 989 //library_namespace.warn('is_element_node: ' + _.is_element_node), 990 show_node(layer), 991 library_namespace.warn('new_node: layer is not a HTML Element!'); 992 993 if (for_each == 1 && (parent = layer.firstChild)) 994 // add as firstChild of layer 995 for_each = handle[1]; 996 997 else if (for_each > 1 && for_each < 5) { 998 if (parent = layer.parentNode) { 999 if (for_each == 2) 1000 // add as nextSibling of layer 1001 for_each = handle[2]; 1002 else if (for_each == 3) 1003 // add as priviusSibling of layer 1004 for_each = handle[3]; 1005 else 1006 // if (f == 4) 1007 // add as parent of layer 1008 for_each = handle[4]; 1009 } else 1010 // 輸入的 layer 為create出來的? 1011 library_namespace.warn('new_node: No parent node found!'); 1012 1013 } else if (_.is_element_node(layer)){ 1014 // 若輸入 [id, null] 則先清空,相當於 replace 1015 if (for_each === null) 1016 layer = _.remove_all_child(layer); 1017 // appendChild (add as lastChild) 1018 for_each = handle[0]; 1019 } 1020 } 1021 1022 } 1023 1024 if (!library_namespace.is_Function(for_each)) 1025 for_each = false; 1026 1027 if (library_namespace.is_Array(node)) { 1028 node = []; 1029 // 不宜個個重新呼叫是為了效能 1030 for ( var i = 0, l = nodes.length, n, _l = layer, _p = parent; i < l; i++) { 1031 node.push(n = _s(nodes[i], for_each && function(n) { 1032 for_each(n, _l, _p); 1033 } || null)); 1034 /* 1035 node.push(n = _s(nodes[i], for_each)); 1036 if (for_each) 1037 try { 1038 for_each(n, layer, parent); 1039 } catch (e) { 1040 library_namespace.err(e); 1041 library_namespace.err('new_node: handle function execution error for node Array['+i+'/'+l+']!<br/>' + for_each); 1042 } 1043 */ 1044 } 1045 1046 } else{ 1047 if (typeof node === 'string' && for_each !== handle[0]) 1048 node = document.createTextNode(nodes); 1049 1050 if (for_each) 1051 try { 1052 for_each(node, layer, parent); 1053 } catch (e) { 1054 library_namespace.err(e); 1055 library_namespace.err('new_node: handle function execution error!<br/>' + for_each); 1056 } 1057 1058 // 設定 childNodes 1059 // 先插入document而後設定childNodes是因為IE有Cross-Page Leaks. 1060 // http://www.blogjava.net/tim-wu/archive/2006/05/29/48729.html 1061 // http://www-128.ibm.com/developerworks/tw/library/x-matters41.html 1062 // Try to use createDocumentFragment() 1063 // http://wiki.forum.nokia.com/index.php/JavaScript_Performance_Best_Practices 1064 if (children !== null && typeof children !== 'undefined') 1065 _s(children, node); 1066 } 1067 1068 1069 // This helps to fix the memory leak issue. 1070 // http://www.hedgerwow.com/360/dhtml/ie6_memory_leak_fix/ 1071 // http://jacky.seezone.net/2008/09/05/2114/ 1072 try { 1073 return typeof node === 'string' ? document.createTextNode(node) : node; 1074 } finally { 1075 node = null; 1076 } 1077 }; 1078 1079 _.new_node.handle = [ 1080 function(n, l) { 1081 var is_e = _.is_element_node(l), t = is_e ? l.tagName.toLowerCase() : null; 1082 if (typeof n === 'number') 1083 n += ''; 1084 1085 if (t in { 1086 // no <select>! 1087 textarea : 1, 1088 input : 1, 1089 text : 1 1090 }) 1091 l.value = (l.value || '') + (is_e ? n.innerHTML : n); 1092 1093 else { 1094 if (typeof n === 'string' && n.indexOf('<') === -1){ 1095 if (t === 'option' && !l.value) 1096 l.value = n; 1097 n = document.createTextNode(n); 1098 } 1099 1100 if (typeof n === 'string') 1101 // this may throw error: -2146827687 未知的執行階段錯誤 1102 l.innerHTML += n; 1103 else{ 1104 t = l.innerHTML; 1105 l.appendChild(n); 1106 if (t === l.innerHTML) 1107 ;//library_namespace.warn('new_node.handle[0]: The addition does not change the layer!'); 1108 } 1109 } 1110 n = null; 1111 }, function(n, l, p) { 1112 l.insertBefore(n, p); 1113 }, function(n, l, p) { 1114 // 將 node 插入作為 layer 之 nextSibling. 1115 // p: parent node of layer 1116 // TODO: 輸入多 node 時 cache next 1117 var next = l.nextSibling; 1118 if (next) 1119 p.insertBefore(n, next); 1120 else 1121 p.appendChild(n); 1122 }, function(n, l, p) { 1123 p.insertBefore(n, l); 1124 }, function(n, l, p) { 1125 n.appendChild(p.replaceChild(n, l)); 1126 } 1127 ]; 1128 1129 // Namespaces: SVG,MathML,XHTML,XLink,.. 1130 _.new_node.ns = { 1131 svg : '2000/svg', 1132 mathml : '1998/Math/MathML', 1133 xhtml : '1999/xhtml', 1134 xlink : '1999/xlink', 1135 // 亦可用'1999/xhtml' 1136 html : 'TR/REC-html40', 1137 html4:'TR/REC-html40', 1138 html5:'TR/html5' 1139 }; 1140 1141 1142 1143 /* 1144 XML_node('div','id:idName'); doesn't insert, just return the object 1145 XML_node('div',{'id':null}); won't set id 1146 XML_node('div',{'id':undefined}); won't set id 1147 1148 XML_node('div','id:idName',1); insert at last of document 1149 XML_node('div',{id:'idName'},refO); insert before(prepend) obj refO: refO.parentNode.insertBefore(_newNode_,refO) 1150 XML_node('div','id:idName',document.body); insert at top of document 1151 XML_node('div','id:idName',[parent]); append as a child of obj parent: parent.appendChild(_newNode_) 1152 XML_node('div','id:idName',[parent,0]); append as a child of obj parent: parent.appendChild(_newNode_) 1153 XML_node('div','id:idName',[parent,refNode]); insert before refNode: parent.insertBefore(_newNode_,refNode) 1154 XML_node('div','id:idName',[parent,refNode,1]); insert after refNode: UNDO 1155 XML_node('div','id:idName',[parent,1]); insert as the first child of parent: parent.insertBefore(_newNode_,parent.firstChild) 1156 XML_node('div','id:idName',[0,refNode]); insert before refNode: document.body.insertBefore(_newNode_,refNode) 1157 XML_node('div','id:idName',[0]); append after all: document.body.appendChild(_newNode_,refNode) 1158 1159 XML_node('div','id:idName',0,'asas'); insert 'asas' as innerText 1160 new_node({div:'asas',id:'idName'},0); 1161 XML_node('div','id:idName',0,'<a>sas</a>'); insert 'asas' as innerHTML 1162 new_node({div:{a:'sas'},id:'idName'},0); 1163 XML_node('div','id:idName',0,obj); insert obj as childNode 1164 new_node({div:obj,id:'idName'},0); 1165 XML_node('div','id:idName',0,[o1,o2]); insert o1,o2 as childNodes 1166 new_node({div:[o1,o2],id:'idName'},0); 1167 1168 1169 有用到新建 HTML element 的函數執行完畢應該將所有變數,尤其是 object 重設; 1170 這是因為 HTML element 的存在會使函數裡的 object 變數不能被釋放。 1171 設成 null 是因為 null 不能設定 method,而 string, number 可以。 1172 1173 http://www.blogjava.net/tim-wu/archive/2006/05/29/48729.html 1174 為預防IE Cross-Page Leaks, 1175 use: 1176 XML_node(++, ++, [XML_node(.., .., [meta])]); 1177 instead of: 1178 XML_node(.., .., [meta], XML_node(++, ++)); 1179 P.S. 2007/11/11 似乎已修正? 1180 1181 1182 buggy 瑕疵: 1183 XML_node(0,0,[parent],'innerText'); return a textNode append as a child of obj parent 1184 1185 TODO: 1186 XML 中 insertBefore(),appendChild()似乎無反應? http://developer.mozilla.org/en/docs/SVG:Namespaces_Crash_Course 1187 insertAfter 1188 1189 */ 1190 CeL.interact.DOM 1191 . 1192 /** 1193 * create new HTML/XML <a href="https://developer.mozilla.org/en/DOM/node">node</a>(<a href="https://developer.mozilla.org/en/DOM/element">element</a>) 1194 * @param tag tag name 1195 * @param propertyO attributes object 1196 * @param insertBeforeO object that we wnat to insert before it 1197 * @param innerObj inner object(s) 1198 * @param styleO style object 1199 * @return node object created 1200 * @requires set_attribute,add_node 1201 * @since 2006/9/6 20:29,11/12 22:13 1202 * @memberOf CeL.interact.DOM 1203 */ 1204 XML_node = function(tag, propertyO, insertBeforeO, innerObj, styleO) { 1205 // XML 中沒有document.body! 1206 //if(typeof document.body=='undefined')document.body=document.getElementsByTagName('body')[0]; 1207 1208 if (typeof document !== 'object' 1209 || (!document.createElement && !document.createElementNS) 1210 || !document.body) { 1211 library_namespace.warn('XML_node: Cannot create tag [' + tag + '].'); 1212 return; 1213 } 1214 1215 var _NS, 1216 // Namespaces: SVG,MathML,XHTML,XLink 1217 _i = _.new_node.ns, 1218 // use Namespaces or not 1219 // buggy now. 1220 _DOM2 = document.createElementNS ? 1 : 0, 1221 // Namespaces base 1222 _e = 'http://www.w3.org/'; 1223 1224 /* 1225 // 依styleO指定 Namespace 1226 if (typeof styleO === 'string') { 1227 if (styleO.indexOf('://') != -1) 1228 _NS = styleO, styleO = 0; 1229 else if (_i[styleO]) 1230 _NS = _e + _i[styleO], styleO = 0; 1231 } else 1232 // buggy now. 1233 _DOM2 = 0;//_NS = styleO === null ? null : _e + _i['XHTML'];//undefined==null 1234 */ 1235 1236 // 指定 Namespace 1237 if (tag) 1238 if (_NS = tag.match(/^(.+):([^:]+)$/)) { 1239 tag = _NS[2]; 1240 _NS = _NS[1]; 1241 if (_NS.indexOf('://') === -1 && (_i = _i[_NS.toLowerCase()])) 1242 _NS = _e + _i; 1243 // library_namespace.warn('XML_node: Add ['+tag+'] of\n'+_NS); 1244 } 1245 1246 /* 1247 for MathML: 1248 IE: document.createElement('m:'+tag) 1249 (surely 'mml:', but 'm:' is default of MathPlayer, so now <html> works without the xmlns attribute) 1250 NS: document.createElementNS('http://www.w3.org/1998/Math/MathML', tag) 1251 */ 1252 try { 1253 _e = tag ? _DOM2 && _NS ? document.createElementNS(_NS, tag) 1254 : document.createElement(tag/* .replace(/[<>\/]/g,'') */) 1255 : document.createTextNode(innerObj || ''); 1256 } catch (_e) { 1257 library_namespace.warn('XML_node: Error create tag:\n' + tag/* + '\n' + _e.description */); 1258 return; 1259 } 1260 if (tag) 1261 _.set_attribute(_e, propertyO); 1262 1263 // IE需要先appendChild才能操作style,moz不用..?? 1264 if (tag && styleO && _e.style) 1265 if (typeof styleO === 'string') 1266 _e.style.cssText = styleO; 1267 else if (typeof styleO === 'object') 1268 for (_i in styleO) 1269 // is_IE?"styleFloat":"cssFloat" 1270 _e.style[_i === 'float' ? 'cssFloat' in _e.style ? 'cssFloat' : 'styleFloat' : _i] = styleO[_i]; 1271 //else library_namespace.warn('XML_node: Error set style:\n[' + styleO + ']'); 1272 1273 1274 // 插入document中。先插入document而後設定childNodes是因為IE有Cross-Page Leaks 1275 // http://www.blogjava.net/tim-wu/archive/2006/05/29/48729.html 1276 // http://www-128.ibm.com/developerworks/tw/library/x-matters41.html 1277 if (insertBeforeO) { 1278 var rO = undefined/* [][1] */, tO = function(_o) { 1279 return typeof _o == 'string' && (_i = document.getElementById(_o)) ? _i 1280 : _o; 1281 }, iO = tO(insertBeforeO); 1282 // Opera9 need .constructor===Array 1283 if (library_namespace.is_Array(iO) && iO.length) 1284 // 在disable CSS時可能會 Warning: reference to undefined property iO[1] 1285 // rO: referrer object, 1286 // 以此決定以appendChild()或insertBefore()的形式插入 1287 rO = iO.length > 1 && tO(iO[1]) || 0, iO = tO(iO[0]); 1288 1289 //if(typeof iO !== 'object' && (iO = document.body, typeof rO === 'undefined')) rO = 0; 1290 if (typeof iO !== 'object') { 1291 iO = document.body; 1292 if (typeof rO === 'undefined') 1293 rO = 0; 1294 } 1295 1296 if (typeof rO === 'undefined') 1297 iO = (rO = iO).parentNode; 1298 if (iO) 1299 // 預防輸入的rO為create出來的 1300 if (rO) 1301 try { 1302 // .firstChild == .childNodes[0] 1303 iO.insertBefore(_e, rO === 1 ? iO.firstChild : rO); 1304 } catch (e) { 1305 library_namespace.warn('XML_node: ' + e.message + '\niO:' 1306 + iO + '\nrO:' + rO); 1307 } 1308 else 1309 //document.body.insertBefore(_e, iO); 1310 iO.appendChild(_e); 1311 } 1312 1313 1314 // 設定 childNodes 1315 if (tag) 1316 _.add_node(_e, innerObj); 1317 /* 1318 if (tag && innerObj) 1319 (_i = function(_o) { 1320 if (typeof _o == 'object') { 1321 if (_o) 1322 if (_o instanceof Array)// &&_o.length 1323 for ( var _j = 0; _j < _o.length; _j++) 1324 _i(_o[_j]); 1325 else 1326 _e.appendChild(_o); 1327 return; 1328 } 1329 if (typeof _o == 'number' && !isNaN(_o)) 1330 // _o+=''; 1331 _o = _o.toString(); 1332 if (typeof _o == 'string') 1333 if (_o.indexOf('<') != -1) 1334 _e.innerHTML += _o; 1335 else 1336 _e.appendChild(document.createTextNode(_o)); 1337 //else library_namespace.warn('XML_node: Error insert contents:\n[' + _o + ']'); 1338 })(innerObj); 1339 */ 1340 1341 // this helps to fix the memory leak issue 1342 // http://www.hedgerwow.com/360/dhtml/ie6_memory_leak_fix/ 1343 // http://jacky.seezone.net/2008/09/05/2114/ 1344 try { 1345 return _e; 1346 } finally { 1347 _e = null; 1348 } 1349 }; 1350 1351 1352 1353 1354 1355 CeL.interact.DOM 1356 . 1357 /** 1358 * 設定 HTML element 的 text。 1359 * 對付IE與Moz不同的text取得方法。現階段不應用innerText,應該用此函數來取得或設定內部text。 1360 * TODO: DOM: 用.nodeValue 1361 * @param element HTML element 1362 * @param {String} text the text to be set 1363 * @return 1364 * @see 1365 * http://www.klstudio.com/post/94.html 1366 * @memberOf CeL.interact.DOM 1367 */ 1368 set_text=function (element, text) { 1369 if (!element || typeof window !== 'object' || typeof window.document !== 'object' 1370 || typeof o === 'string' && !(element = _.get_element(element))) 1371 return; 1372 1373 var text_p=_.set_text.p; 1374 if (typeof text_p !== 'string' || !text_p) 1375 _.set_text.p = text_p = 1376 typeof document.body.textContent === 'string' ? 'textContent' 1377 : typeof document.body.innerText === 'string' ? 'innerText' 1378 : 'innerHTML'; 1379 1380 var p = typeof element.value === 'string' ? 'value' : text_p; 1381 if (typeof text !== 'undefined') 1382 element[p] = text; 1383 1384 // http://www-128.ibm.com/developerworks/tw/library/x-matters41.html 1385 if (element.nodeType === 3 || element.nodeType === 4) 1386 return element.data; 1387 1388 /* 1389 var i = 0, t = []; 1390 for (; i < element.childNodes.length; i++) 1391 t.push(set_text(element.childNodes[i])); 1392 return t.join(''); 1393 */ 1394 1395 return element[p]; 1396 }; 1397 1398 1399 /* 用在top的index.htm中,當setTopP()後指定特殊頁面 2005/1/26 21:46 1400 set: window.onload=setFrame; 1401 var setFrameTarget='MAIN',setFrameTargetSet={'menu.htm':'MENU','all.htm':'MENU','midi.htm':'MIDI'}; 1402 1403 ** xhtml1-frameset.dtd中<script>只能放在<head> 1404 */ 1405 var setFrameTarget,setFrameTargetSet; // 預設target, 轉頁的target lists 1406 //setFrame[generateCode.dLK]='setFrameTarget,setFrameTargetSet'; 1407 function setFrame(){ 1408 //alert(window.name); 1409 //for(var i=0;i<window.frames.length;i++)alert(window.frames[i].name); 1410 //alert(top.location.href+'\n'+location.href+'\n'+(top.location.href!=location.href)+'\n'+(window.top!=window.window)); 1411 if(window.top!=window.window){//top.location.href!=location.href 1412 window.top.location.replace(location.href); 1413 return; 1414 } 1415 var l,f; 1416 try{l=location.hash.slice(1);}catch(e){return;} // IE在about:blank的情況下呼叫網頁,網頁完全載入前location無法呼叫。例如從FireFox拉進IE時使用location.*有可能'沒有使用權限',reload即可。 1417 if(typeof setFrameTargetSet!='object')setFrameTargetSet={}; 1418 if(l)try{l=decodeURIComponent(l);}catch(e){l=unescape(l);} 1419 //location.hash=''; // 這一項會reload 1420 if( l && (f=(f=l.match(/([^\/]+)$/)?RegExp.$1:l)&&(f=f.match(/^([^?#]+)/)?RegExp.$1:f)&&(l in setFrameTargetSet)?setFrameTargetSet[f]:setFrameTarget) && f!=window.name && window.frames[f] && window.frames[f].location.href!=l ) 1421 //alert(l+'\n==>\n'+f), 1422 window.open(l,f);//if((l=window.open(l,f).top).focus(),alert(l!=self.top),l!=self.top)self.top.close();//alert(l+'\n'+f), // moz需要等到frame load之後才能得到window.frames[f].location.href==l的結果,所以可以考慮作setTimeout的延遲。但是假如真的不是預設的page,這樣會造成多load一遍。 1423 //setTimeout('alert(window.frames["'+f+'"].location.href);',900); 1424 } 1425 /* 1426 set window.top page to certain location 1427 setTopP(location,search) 1428 search===setTopP_doTest: do a test, return window.top不為指定頁?1:0 1429 */ 1430 var setTopPDTopP,setTopP_doTest=.234372464; // default top page(file) path 1431 //setTopP[generateCode.dLK]='dBasePath,getFN,setTopPDTopP,setTopP_doTest'; 1432 function setTopP(l, s) { 1433 if (!setTopPDTopP) 1434 return 2; 1435 if (!l) 1436 l = dBasePath(setTopPDTopP) + getFN(setTopPDTopP); 1437 // alert(l); 1438 if (typeof s == 'undefined') 1439 try { 1440 // IE在about:blank的情況下呼叫網頁,網頁完全載入前location無法呼叫。 1441 // 例如從FireFox拉進IE時使用location.*有可能'沒有使用權限',reload即可。 1442 s = window/* self */.location.search; 1443 } catch (e) { 1444 return; 1445 } 1446 var t, r = /[\/\\]$/i, ri = /[\/\\](index.s?html?)?$/i; 1447 try { 1448 // top.location.pathname在遇到local file時可能出問題。 1449 // 若不同domain時top.location也不能取用,應改成window.top!=window.window 1450 t = window.top.location.href.replace(/[?#](.*)$/, ''); 1451 } catch (e) { 1452 t = ''; 1453 } 1454 // alert(t+'\n'+l+'\n'+(t!=l)); 1455 if (t != l && !(r.test(l) && ri.test(t)) && !(ri.test(l) && r.test(t))) 1456 if (s === setTopP_doTest) 1457 return 1; 1458 // replace() 方法可以開啟檔案,但是卻不會更動瀏覽器的瀏覽歷程(history)內容. 1459 // IE6若location.href長度超過2KB,光是'location.search'這項敘述就會導致異常. 1460 else 1461 // 預設page:xx/和xx/index.htm相同 1462 window.top.location.replace(l + s + '#' 1463 + encodeURIComponent(location.href)); 1464 }; 1465 1466 1467 // 設在body.onload,改變IE中所有<a>在滑鼠移入移出時的 window.status 1468 var setAstatusOS; // old status,也可設定event.srcElement.ostatus等等,但考慮到將造成記憶體浪費… 1469 //setAstatus[generateCode.dLK]='setAstatusOver,setAstatusOut'; 1470 function setAstatus() { 1471 if (typeof window !== 'object' || typeof window.event === 'undefined' || typeof window.status === 'undefined' 1472 //||typeof event.srcElement=='undefined' 1473 ) 1474 // 預防版本過低(4以下)的瀏覽器出現錯誤:event至IE4才出現 1475 return; 1476 var i, o, l; 1477 if (o = document.getElementsByTagName('a')) 1478 for (i = 0, l = o.length; i < l; i++) 1479 if (o[i].title && !o[i].onmouseover && !o[i].onmouseout) 1480 o[i].onmouseover = setAstatusOver, 1481 o[i].onmouseout = setAstatusOut; 1482 }; 1483 //setAstatusOver[generateCode.dLK]=setAstatusOut[generateCode.dLK]='setAstatusOS'; 1484 function setAstatusOver() { 1485 var o = window.event.srcElement; 1486 if (o.title) { 1487 setAstatusOS = window.status, window.status = o.title; 1488 return true; 1489 } 1490 }; 1491 function setAstatusOut() { 1492 //var o=event.srcElement;if(typeof o.ostatus!='undefined'){window.status=o.ostatus;return true;} 1493 window.status = setAstatusOS; 1494 return true; 1495 }; 1496 1497 1498 1499 1500 1501 CeL.interact.DOM 1502 . 1503 /** 1504 * fill data to table. 1505 * 增加 table 的列(row) 1506 * @param {Array|Object} data data list 1507 * @param table table element 1508 * @param {Array} header header list 1509 * @return 1510 * @example 1511 * table_list([list1],[list2],..) 1512 * e.g., table_list([1,2,3,4],[4,5,3,4]); 1513 * table_list([[list1],[list2],..]) 1514 * e.g., table_list( [ [1,2,3,4],[4,5,3,4] ] ); 1515 * @since 2010/05/03 14:13:18 1516 * @memberOf CeL.interact.DOM 1517 * @see 1518 * http://www.datatables.net/ 1519 */ 1520 table_list = function(data, table, header, do_clean) { 1521 var i = 0, l, add_list = function(array, d) { 1522 if (!library_namespace.is_Array(array)) 1523 return; 1524 1525 var j = 0, tr = document.createElement('tr'), td, array, L = array.length; 1526 for (; j < L; j++) { 1527 td = document.createElement(d || 'td'); 1528 td.appendChild(document.createTextNode(array[j])); 1529 tr.appendChild(td); 1530 } 1531 table.appendChild(tr); 1532 }; 1533 1534 if (typeof table === 'string') 1535 table = document.getElementById(table); 1536 1537 /* 1538 // in Chrome/5.0.342.9 @ Ubuntu, 加了會出問題。 1539 try{ 1540 if(l=table.getElementsByTagName('tbody')) 1541 table=l[0]; 1542 }catch(e){} 1543 */ 1544 1545 if (do_clean) 1546 table.innerHTML = ''; 1547 /* 1548 try { 1549 // moz 1550 table.innerHTML = ''; 1551 } catch (e) { 1552 try { 1553 // alert(table.rows.length); 1554 // IE 1555 for ( var i = table.rows.length; i > 0;) 1556 table.deleteRow(--i); 1557 } catch (e) { 1558 } 1559 } 1560 */ 1561 1562 if (header) 1563 add_list(header, 'th'); 1564 1565 if (data.length === 1 && typeof (l=data[0]) === 'object' 1566 && library_namespace.is_Array(l[0])) 1567 data = l; 1568 1569 if (library_namespace.is_Array(data)) 1570 for (l = data.length; i < l; i++) { 1571 add_list(data[i]); 1572 } 1573 else if (library_namespace.is_Object(data)) { 1574 for (i in data) { 1575 add_list( [ i, data[i] ]); 1576 } 1577 } else 1578 library_namespace.debug('Error input: not legal data!'); 1579 }; 1580 1581 1582 1583 /* 1584 1585 test: 1586 /fsghj.sdf 1587 a.htm 1588 http://www.whatwg.org/specs/web-apps/current-work/#attr-input-pattern 1589 file:///D:/USB/cgi-bin/lib/JS/_test_suit/test.htm 1590 //www.whatwg.org/specs/web-apps/current-work/#attr-input-pattern 1591 1592 TODO: 1593 .fileName: 1594 file:///D:/USB/cgi-bin/lib/JS/_test_suit/test.htm 1595 -> 1596 D:\USB\cgi-bin\lib\JS\_test_suit\test.htm 1597 1598 eURI : /^((file|telnet|ftp|https?)\:\/\/|~?\/)?(\w+(:\w+)?@)?(([-\w]+\.)+([a-z]{2}|com|org|net))?(:\d{1,5})?(\/([-\w~!$+|.,=]|%[a-f\d]{2})*)?(\?(([-\w~!$+|.,*:]|%[a-f\d{2}])+(=([-\w~!$+|.,*:=]|%[a-f\d]{2})*)?&?)*)?(#([-\w~!$+|.,*:=]|%[a-f\d]{2})*)?$/i, 1599 1600 */ 1601 CeL.interact.DOM 1602 . 1603 /** 1604 * Parses URI 1605 * @param {String} URI URI to parse 1606 * @return parsed object 1607 * @example 1608 * alert(parse_URI('ftp://user:cgh@dr.fxgv.sfdg:4231/3452/dgh.rar?fg=23#hhh').hostname); 1609 * @since 2010/4/13 23:53:14 from parseURI+parseURL 1610 * @memberOf CeL.interact.DOM 1611 * @see 1612 * RFC 1738, RFC 2396, RFC 3986, 1613 * Uniform Resource Identifier (URI): Generic Syntax, 1614 * http://tools.ietf.org/html/rfc3987, 1615 * http://flanders.co.nz/2009/11/08/a-good-url-regular-expression-repost/, 1616 * http://www.mattfarina.com/2009/01/08/rfc-3986-url-validation, 1617 * also see batURL.htm 1618 */ 1619 parse_URI = function(URI) { 1620 var m, n, h = URI, p; 1621 if (!h 1622 || 1623 // 不能用 instanceof String! 1624 typeof h !== 'string' 1625 || !(m = h.match(/^([\w\d\-]{2,}:)?(\/\/)?(\/[A-Za-z]:|[^\/#?&\s:]+)([^\s:]*)$/))) 1626 return; 1627 //library_namespace.debug('parse [' + URI + ']: '+m); 1628 1629 URI = is_DOM('location') ? { 1630 // protocol包含最後的':',search包含'?',hash包含'#' 1631 // file|telnet|ftp|https 1632 protocol : location.protocol, 1633 hostname : location.hostname, 1634 port : location.port, 1635 host : location.host, 1636 // local file @ IE: C:\xx\xx\ff, others: /C:/xx/xx/ff 1637 pathname : location.pathname 1638 } : {}; 1639 URI.URI = h; 1640 1641 if (n = m[1]) 1642 URI.protocol = n; 1643 URI._protocol = URI.protocol.slice(0,-1); 1644 //library_namespace.debug('protocol [' + URI._protocol + ']'); 1645 1646 /* ** filename 可能歸至m[4]! 1647 * 判斷準則: 1648 * gsh.sdf.df#dhfjk filename|hostname 1649 * gsh.sdf.df/dhfjk hostname 1650 * gsh.sdf.df?dhfjk filename 1651 * gsh.sdf.df filename 1652 */ 1653 h = m[3], p = m[4]; 1654 if (h && !/^\/[A-Za-z]:$/.test(h) && (p.charAt(0) === '/' || /[@:]/.test(h))) { 1655 // 處理 username:password 1656 if (m = h.match(/^([^@]*)@(.+)$/)) { 1657 n = m[1].match(/^([^:]+)(:(.*))?$/); 1658 if (!n) 1659 return; 1660 URI.username = n[1]; 1661 if (n[3]) 1662 URI.password = n[3]; 1663 h = m[2]; 1664 } 1665 1666 // 處理 host 1667 if (m = h.match(/^([^\/#?&\s:]+)(:(\d{1,5}))?$/)) { 1668 // host=hostname:port 1669 URI.host = URI.hostname = m[1]; 1670 if (m[3]) 1671 URI.port = parseInt(m[3], 10); 1672 else if (n = { 1673 http : 80, 1674 ftp : 21 1675 }[URI._protocol]) 1676 URI.host += ':' + (URI.port = n); 1677 } else 1678 return; 1679 1680 } else// test URI.protocol === 'file:' 1681 p = h + p, h = ''; 1682 //if (!h) library_namespace.warn('將[' + p + ']當作 pathname!'); 1683 //library_namespace.debug('local file: [' + location.pathname + ']'), 1684 1685 if(!/^([^%]+|%[a-f\d]{2})+$/.test(p)) 1686 library_namespace.warn('encoding error: [' + p + ']'); 1687 1688 if (p && (m = p.match(/^(((\/.*)\/)?([^\/#?]*))?(\?([^#]*))?(#(.*))?$/))) 1689 // pathname={path}filename 1690 //library_namespace.warn('pathname: [' + m + ']'), 1691 // .path 會隨不同 OS 之 local file 表示法作變動! 1692 URI.path = /^\/[A-Za-z]:/.test(URI.pathname = m[1]) ? m[2].slice(1).replace(/\//g,'\\') : m[2], 1693 URI.filename = m[4], 1694 URI.search = m[5], URI._search = m[6], 1695 URI.hash = m[7], URI._hash = m[8]; 1696 else { 1697 if (!h) 1698 return; 1699 URI.path = URI.pathname.replace(/[^\/]+$/, ''); 1700 } 1701 //library_namespace.debug('path: [' + URI.path + ']'), 1702 1703 1704 // href=protocol:(//)?username:password@hostname:port/path/filename?search#hash 1705 URI.href = (URI.protocol ? URI.protocol + '//' : '') 1706 + (URI.username ? URI.username 1707 + (URI.password ? ':' + URI.password : '') + '@' : '') 1708 + URI.host + URI.pathname + (URI.search || '') + (URI.hash || ''); 1709 1710 //library_namespace.debug('href: [' + URI.href + ']'); 1711 return URI; 1712 }; 1713 1714 1715 1716 1717 1718 1719 /* Copy id(or object) to user's clipboard or Paste clipboard to id(or object). 1720 1721 return the value set to clipboard 1722 http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/obj_textrange.asp 1723 http://msdn.microsoft.com/workshop/author/dhtml/reference/collections/textrange.asp 1724 http://msdn.microsoft.com/workshop/author/dhtml/reference/methods/execcommand.asp 1725 way 2:use window.clipboardData http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/clipboarddata.asp 1726 1727 clipboardFunction() paste/get clipboard 1728 clipboardFunction(0,divObj) paste/get clipboard to divObj 1729 clipboardFunction(1,'divObj name') Copy divObj to clipboard/set clipboard 1730 clipboardFunction(2,'dcfvdf') set clipboard by string 1731 clipboardFunction(3,divObj) Copies divObj to the clipboard/set clipboard and then deletes it. *return the value set to clipboard 1732 */ 1733 var clipboardFunctionObj = 'clipboardFunctionDiv'; 1734 //clipboardFunction[generateCode.dLK]='clipboardFunctionObj'; 1735 function clipboardFunction(m,o){ // method,object/(string)set value 1736 if(window.navigator.appName=="Microsoft Internet Explorer"){ 1737 var t,O,tN; 1738 if(m==2)t=o,o='';else if(typeof o=='string')o=document.getElementById(o); 1739 // try .nodeName instead of .tagName http://twpug.net/modules/smartsection/item.php?itemid=35 1740 if((typeof o!='object'||!o||(tN=(o.tagName||'').toLowerCase())!='textarea'&&tN!='select'&&tN!='option'&&(tN!='input'||o.type!='text')&&(O=o))&&!(o=document.getElementById(clipboardFunctionObj))) // textarea,select,option,input需使用.value! o.type!='INPUT'||o.type!='text':這樣大概也沒copy的價值了吧,應該會出現錯誤。 1741 try{document.body.appendChild(o=document.createElement('textarea')),o.id=clipboardFunctionObj;}catch(e){return;} // 只對IE5.5之後有用 1742 //var t=document.body.createTextRange();t.moveToElementText(o); 1743 if(m==2)o.value=t;else{if(O)o.value=O.innerText;if(m==3)t=o.value;} 1744 if(o.id==clipboardFunctionObj)o.style.display='block'; // 得出現才能execCommand() 1745 o.createTextRange()//TextRange Object 1746 .execCommand(m?m==3?"Cut":"Copy":"Paste"); 1747 if(o.id==clipboardFunctionObj)o.style.display='none'; 1748 //t.execCommand("ForeColor","false","plum"),t.execCommand("BackColor","false","glay"); 1749 //alert(o.tagName+'\n'+o.id+'\n['+o.innerText+']\n'+(m?m==3?"Cut":"Copy":"Paste")); 1750 if(m!=3)t=o.value; 1751 if(O)O.innerText=o.value; 1752 return t; 1753 } 1754 1755 // http://www.mozilla.org/xpfe/xptoolkit/clipboard.html 1756 // http://mozilla.org/editor/midasdemo/securityprefs.html 1757 // http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/06/21/4850.aspx 1758 // http://www.webdeveloper.com/forum/archive/index.php/t-170520.html 1759 // http://forum.moztw.org/viewtopic.php?p=131407 1760 /* 1761 if(window.navigator.appName=="Netscape"){ // …不能用! 1762 if(typeof o=='string')o=document.getElementById(o); 1763 if(m==2||!o||o.tagName!='TEXTAREA'&&o.tagName!='SELECT'&&o.tagName!='OPTION'&&(o.tagName!='INPUT'||o.type!='text'))return; // 無法設定 1764 1765 if(!Zwischenablage){ // 初始設定 1766 netscape.security.PrivilegeManager.enablePrivilege("UniversalSystemClipboardAccess"); 1767 //var fr=new java.awt.Frame(); 1768 Zwischenablage=new java.awt.Frame().getToolkit().getSystemClipboard(); 1769 } 1770 1771 if(m==0){ 1772 var Inhalt=Zwischenablage.getContents(null); 1773 if(Inhalt!=null)o.value=Inhalt.getTransferData(java.awt.datatransfer.DataFlavor.stringFlavor); 1774 } 1775 else{ // m=1,3 1776 o.select(); 1777 Zwischenablage.setContents(new java.awt.datatransfer.StringSelection(o.value),null); 1778 } 1779 1780 return o.value; 1781 } 1782 */ 1783 } // clipboardFunction() 1784 1785 1786 1787 1788 Clipboard = function() { 1789 }; 1790 1791 1792 CeL.interact.DOM 1793 . 1794 // 2010/1/15 00:17:38 1795 // IE, FF only 1796 // http://www.jeffothy.com/weblog/clipboard-copy/ 1797 // http://bravo9.com/journal/copying-into-the-clipboard-with-javascript-in-firefox-safari-ie-opera-292559a2-cc6c-4ebf-9724-d23e8bc5ad8a/ 1798 // http://code.google.com/p/zeroclipboard/ 1799 copy_to_clipboard = function(text) { 1800 var clip; 1801 if (clip = window.clipboardData) { 1802 clip.clearData(); 1803 clip.setData('Text', text); 1804 } else if (is_DOM('Components')){ 1805 library_namespace.require_netscape_privilege( 1806 // 在您的機器上執行或安裝軟體 1807 'UniversalXPConnect', function() { 1808 // https://developer.mozilla.org/en/Using_the_Clipboard 1809 // [xpconnect wrapped nsIClipboardHelper] 1810 return Components.classes["@mozilla.org/widget/clipboardhelper;1"] 1811 .getService(Components.interfaces.nsIClipboardHelper) 1812 // 跳出函數即無效,因此不能 cache。 1813 .copyString(text); 1814 }); 1815 } 1816 //else if (navigator.userAgent.indexOf("Opera") != -1) 1817 // window.location = text; 1818 }; 1819 1820 1821 1822 /* 2009/5/13 21:21:49 1823 unfinished 1824 */ 1825 function clipB() { 1826 } 1827 clipB.start_op = function() { 1828 var o = this.temp_obj; 1829 if (!o) { 1830 document.body.appendChild(o = document.createElement('div')); 1831 // for modify 1832 o.contentEditable = true; 1833 // o.style.height=0;o.style.width=0; 1834 this.temp_obj = o; 1835 } 1836 1837 document.selection.empty(); 1838 // initial 1839 o.innerHTML = ''; 1840 // 得出現才能 focus(), execCommand() 1841 o.style.display = 'block'; 1842 o.focus(); 1843 return o; 1844 }; 1845 clipB.end_op = function() { 1846 var o = this.temp_obj; 1847 document.selection.empty(); 1848 if (o) 1849 o.style.display = 'none'; 1850 }; 1851 // return [text, obj] 1852 clipB.get_obj = function(t) { 1853 var o; 1854 if (typeof t == 'object' && 'innerHTML' in t 1855 || (o = document.getElementById('' + t)) && (t = o)) 1856 return [ t.innerHTML, t ]; 1857 return [ t ]; 1858 }; 1859 clipB.paste_to = function(o) { 1860 o = this.get_obj(o); 1861 if (o = o[1]) 1862 o.innerHTML = this.get(1); 1863 }; 1864 clipB.set = function(o) { 1865 o = this.get_obj(o); 1866 }; 1867 // get HTML 1868 clipB.get = function(h) { 1869 var o = this.start_op(), r = document.selection.createRange(), t; 1870 r.select(); 1871 r.execCommand('Paste'); 1872 t = h ? r.htmlText : r.text; 1873 this.end_op(); 1874 return h ? o.innerHTML : o.innerText; 1875 }; 1876 clipB.cut_from = function(o) { 1877 o = this.get_obj(o); 1878 }; 1879 1880 1881 //從後面調過來的 1882 var disabledKM=0,scrollToXY,scrollToInterval,scrollToOK,doAlertDivName,doAlertOldScrollLocation; 1883 1884 1885 CeL.interact.DOM 1886 . 1887 /** 1888 * 設定document.cookie. 1889 * You can store up to 20 name=value pairs in a cookie, and the cookie is always returned as a string of all the cookies that apply to the page. 1890 * TODO: 1891 * HTML5 localStorage (name/value item pairs). 1892 * test various values. 1893 * document.cookie.setPath("/"); 1894 1895 * @example 1896 範例: 1897 // delete domain 1898 set_cookie('domain',0); 1899 // 一個月(30 days) 1900 set_cookie('expires',30); 1901 // 設定name之值為jj 1902 set_cookie(name,'jj'); 1903 // 設定name之值為56 1904 set_cookie(name,56); 1905 // 除去name 1906 set_cookie(name); 1907 // 設給本host全部使用 1908 set_cookie(_.set_cookie.f.set_root); 1909 // 設給本domain使用 1910 set_cookie(_.set_cookie.f.set_domain); 1911 // 依現有設定除去所有值 1912 set_cookie(_.set_cookie.f.delete_all); 1913 // 除去所有值 1914 set_cookie(_.set_cookie.f.delete_all_root); 1915 // 永久儲存(千年) 1916 set_cookie(_.set_cookie.f.forever); 1917 // 準確設定這之後只在這次瀏覽使用這些cookie,也可用set_cookie('expires',-1); 1918 set_cookie(_.set_cookie.f.moment); 1919 // 將expires設定成forever或moment後再改回來(不加expires設定) 1920 set_cookie('expires',0); 1921 1922 * @param {String|Object|_module_.set_cookie.f} name set_cookie.f flag | varoius name 1923 * @param value varoius value 1924 * @param {Boolean|Object} config 若對於特殊設定僅暫時設定時,設定此項。 1925 * @returns 1926 * @see 1927 * Chrome doesn't support cookies for local files unless you start it with the --enable-file-cookies flag. 1928 * chrome.exe --allow-file-access-from-files --enable-extension-timeline-api --enable-file-cookies 1929 * http://stackoverflow.com/questions/335244/why-does-chrome-ignore-local-jquery-cookies 1930 * http://code.google.com/p/chromium/issues/detail?id=535 1931 * @memberOf CeL.interact.DOM 1932 */ 1933 set_cookie = function (name, value, config) { 1934 if (!is_DOM('document') || typeof document.cookie !== 'string' 1935 || typeof name === 'undefined') 1936 return; 1937 1938 var _s = _.set_cookie, flag = _s.f, m; 1939 if (!config) 1940 // 預設傳到 default 1941 config = _s.c; 1942 else if (!library_namespace.is_Object(config)) 1943 // document.cookie 不須每次詳細設定,但這樣可以選擇 {} / {..} / true 1944 config = library_namespace.extend(_s.c, {}); 1945 1946 if (library_namespace.is_Object(name)) { 1947 for ( var i in name) 1948 _s(i, name[i], config); 1949 return config; 1950 } 1951 1952 try { 1953 // This will cause error in Phoenix 0.1: 1954 // Error: uncaught exception: [Exception... "Component returned failure code: 0x8000ffff (NS_ERROR_UNEXPECTED) [nsIDOMNavigator.cookieEnabled]" nsresult: "0x8000ffff (NS_ERROR_UNEXPECTED)" location: "JS frame :: http://lyrics.meicho.com.tw/game/game.js :: set_cookie :: line 737" data: no] 1955 if (window.navigator && !window.navigator.cookieEnabled) 1956 throw 1; 1957 } catch (e) { 1958 CeL.warn('set_cookie: We cannot use cookie!'); 1959 return; 1960 } 1961 1962 //library_namespace.debug('set_cookie: ' + name + ' = [' + value + ']', 1); 1963 if (name === flag.set_root) 1964 // 設給本 host 全部使用 1965 name = 'path', value = '/'; 1966 else if (name === flag.set_domain) 1967 // 設給本 domain 使用,尚不是很好的判別法。 1968 name = 'domain', value = location.hostname.replace(/^[^.]+\./, '.'); 1969 else if (name === flag.forever) 1970 // 永久儲存,date之time值不能>1e16 1971 name = 'expires', value = 1e14; 1972 else if (name === flag.moment) 1973 // 準確設定這之後只在這次瀏覽使用這些cookie 1974 name = 'expires', value = -1; 1975 1976 // detect special config / 特殊設定 1977 if (typeof name === 'string' 1978 && (m = name.match(/^(expires|path|domain|secure)$/i))) { 1979 name = m[1]; 1980 if (name === 'expires' && typeof value === 'number' && value) { 1981 //if(value<8000)value*=86400000;//幾日,86400000=1000*60*60*24 1982 //value=(new Date(value<3e13?(new Date).getTime()+value:1e14)).toUTCString(); // 3e13~千年 1983 value = (new Date(value < 1e14 ? value < 0 ? 0 : (new Date).getTime() 1984 + (value < 8e3 ? value * 86400000 : value) : 1e14)).toUTCString(); 1985 } 1986 config[name] = value; 1987 //library_namespace.debug('set_cookie: ' + name + ' = [' + value + ']', 1); 1988 return name + '=' + value + ';'; 1989 1990 } else { 1991 var set = name === flag.delete_all_root ? 'expires=' + (new Date(0)).toUTCString() + ';path=/;' 1992 : (typeof value === 'undefined' ? 'expires=' + (new Date(0)).toUTCString() + ';' 1993 : config.expires ? 'expires=' + config.expires + ';' : '') 1994 + (config.path ? 'path=' + config.path + ';' : '') 1995 + (config.domain ? 'domain=' + config.domain + ';' : '') 1996 + (config.secure ? 'secure;' : ''); 1997 1998 if (name === flag.delete_all || name === flag.delete_all_root) { 1999 /* 2000 var c=document.cookie; 2001 while(c.match(/([^=;]+)(=[^;]{0,})?/)){ 2002 c=c.substr(RegExp.lastIndex); 2003 if(!/expires/i.test(RegExp.$1))document.cookie=RegExp.$1+'=;'+set; 2004 } 2005 */ 2006 for ( var p = document.cookie.split(';'), n, l = p.length, i = 0; i < l; i++) 2007 if (!/^\s*expires\s*$/i.test(n = c[i].split('=')[0])) 2008 document.cookie = n + '=;' + set; 2009 return document.cookie; 2010 2011 } else { 2012 // 可用escape(value)/unescape()來設定,速度會比較快,但佔空間。 2013 //value=name+'='+(typeof value=='undefined'?'':dQuote(''+value).replace(/([\01-\11\13-\14\16-\40=;])/g,function($0,$1){var c=$1.charCodeAt(0),d=c.toString(16);return'\\x'+(c<16?'0':'')+d;}))+';'+set; 2014 // 2004/11/23 21:11 因為cookie儲存成中文時會fault,所以只好還是使用escape() 2015 value = escape(name) + '=' 2016 + (typeof value == 'undefined' ? '' : escape(value)) + ';' 2017 + set; 2018 //library_namespace.debug('set_cookie: [' + value + ']', 1); 2019 //library_namespace.debug('set_cookie: [' + document.cookie + ']', 1); 2020 // 長度過長時(約4KB)會清空,連原先的值都不復存在! 2021 return value.length < 4096 && (document.cookie = value) ? value 2022 : -1; 2023 } 2024 2025 } 2026 }; 2027 2028 CeL.interact.DOM 2029 . 2030 set_cookie.f = { 2031 moment : -1, 2032 delete_all : 2, 2033 delete_all_root : 3, 2034 set_root : 4, 2035 set_domain : 5, 2036 forever : 6 2037 }; 2038 2039 CeL.interact.DOM 2040 . 2041 // 特殊設定 2042 set_cookie.c = { 2043 expires : 0, 2044 path : 0, 2045 domain : 0, 2046 secure : 0 2047 }; 2048 2049 /* 取得document.cookie中所需之值 看起來只能取得相同domain,有設定的path之cookie 2050 2051 flag=0: only get the lastest matched value; 2052 flag=1: only get all matched in a array; 2053 other flag: auto detect by name 2054 2055 get_cookie(name); // 取得name之值,亦可用RegExp:if(c=get_cookie())c['name1']==value1; 2056 get_cookie('nn[^=]*'); // 取得所有nn開頭之組合 2057 get_cookie(); // 取得所有name=value組 2058 2059 因為 cookie 較容易遭到竄改或是出問題,建議設定 verify。 2060 */ 2061 CeL.interact.DOM 2062 . 2063 //get_cookie[generateCode.dLK]='renew_RegExp_flag'; 2064 get_cookie=function (name,flag,verify){ 2065 if(!is_DOM('document')||!document.cookie)return; 2066 if(!name)name='[^;=\\s]+';//\w+ 2067 var c,R=name instanceof RegExp?name:new RegExp('('+escape(name)+')\\s*=\\s*([^;=\\s]*)','g') 2068 ,m=document.cookie.match(R); 2069 //library_namespace.debug('get_cookie: [' + R + '] = ['+m+']', 1); 2070 //library_namespace.debug('get_cookie: [' + document.cookie + ']', 1); 2071 if(!m)return; 2072 if(R.global)R=library_namespace.renew_RegExp_flag(R,'-g'); 2073 if(m.length>1) 2074 // 取最後一個 2075 if(flag==0 || typeof flag=='undefined'&&typeof name=='string') 2076 m=m.slice(-1); 2077 // 表示不是因name為RegExp而得出之值. 2078 // TODO: bug: 找 "count" 可能找到 "data_count"!! 2079 if(m.length===1&&typeof m[0]==='string'&&(c=m[0].match(R))[1]===escape(name)){ 2080 /* 2081 if((m=c[2])&&((c=m.charAt(0))=='"'||c=="'")&&c==m.slice(-1)) // 將值為".."或'..'轉為引號中表示之值 2082 try{ 2083 //alert('get 1:\n'+m+'\n'+unescape(m)); 2084 window.eval('c='+m);return c; 2085 }catch(e){} 2086 return m; 2087 */ 2088 return unescape(c[2]); 2089 } 2090 2091 var r={},v,M,i=0; 2092 //alert(document.cookie+'\n'+R+'\n'+m.length+'\n'+m); 2093 2094 for(;i<m.length;i++) 2095 if(typeof m[i]==='string'&&(M=m[i].match(R))) 2096 r[unescape(M[1])]=unescape(M[2]); 2097 /* 2098 for(;i<m.length;i++){ 2099 M=m[i].match(R),v=unescape(M[2]); 2100 if(v&&((c=v.charAt(0))=='"'||c=="'")&&c==v.slice(-1)) 2101 try{ 2102 //alert('get 2:\n'+v+'\n'+unescape(v)); 2103 window.eval('c='+v);v=c; 2104 }catch(e){} 2105 r[M[1]]=v; // 有必要可用unescape(),畢竟那是模範做法。 2106 } 2107 */ 2108 2109 return r; 2110 }; 2111 2112 2113 /* 取得註解部份資料:這個值會連 NewLine 都保存下來 2114 其實IE用document.getElementsByTagName('!')就可以了,不管幾層都能到。 2115 註解中[!-]需要escape!IE6之div內不能沒東西,所以得加個 (並且得在前面)之後加<!-- -->才有用。 2116 2117 div 從哪裡開始找 2118 level 最多往下找幾層 2119 retType 回傳0:node本身,1:註解值 2120 */ 2121 function get_comments(div, level, retType) { 2122 if (!div) div = window.document; 2123 var i = 0, d, _f = get_comments; 2124 if (isNaN(_f.endLevel)) _f.endLevel = 2; 2125 if (isNaN(level) || level === -1) _f.a = [], level = _f.endLevel; 2126 else if (typeof _f.a != 'object') _f.a = []; 2127 div = div.childNodes; 2128 for (; i < div.length; i++) { 2129 d = div[i]; //if(d.nodeType==8)alert(d.tagName+'\n'+d.nodeName+'\n'+d.nodeType+(d.nodeValue?'\n'+d.nodeValue.slice(0,30):'')); 2130 if (d.tagName && d.tagName == '!') _f.a.push(retType ? d : d.text.replace(/^<!(--)?/, '').replace(/(--)?>$/, '')); //,alert(d.tagName+'\n'+d.text.slice(0,30)); 2131 else if (d.nodeType == 8) _f.a.push(retType ? d : d.nodeValue); //alert('* '+_f.a.length+'\n'+d.nodeValue.slice(0,30)); // NS http://allabout.co.jp/career/javascript/closeup/CU20040307/index.htm?FM=cukj&GS=javascript 2132 // http://www.w3.org/TR/DOM-Level-2-Core/core.html 2133 // ELEMENT_NODE,ATTRIBUTE_NODE,TEXT_NODE,CDATA_SECTION_NODE,ENTITY_REFERENCE_NODE,ENTITY_NODE,PROCESSING_INSTRUCTION_NODE,COMMENT_NODE,DOCUMENT_NODE,DOCUMENT_TYPE_NODE,DOCUMENT_FRAGMENT_NODE,NOTATION_NODE 2134 if (level && d.childNodes) _f(d, level - 1, retType); 2135 } 2136 return _f.a; 2137 } 2138 //window.onload=function(){get_comments();alert(get_comments.a.length);for(var i=0;i<get_comments.a.length;i++)alert('['+get_comments.a[i]+']');}; 2139 2140 2141 2142 2143 2144 2145 /* background image load 2146 ** 本函數會倒著load!請將優先度高的排後面! 2147 2148 new Image看起來不是個好方法… 2149 http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/img.asp 2150 2151 var img=new Image(width,heighr);img.onload=function(){docImageElement.src=this.src;}img.src=__SRC__; // onload應在前面,預防設定onload前就已被load? 2152 2153 var bgLoadImgA,bgLoadImgLA; 2154 function bgLoadImg(){ 2155 if(location.protocol=='file:')return; 2156 if(typeof bgLoadImgA=='string'){ 2157 var s=[1]; 2158 try{s.pop();bgLoadImgA=bgLoadImgA.split(',');setTimeout('bgLoadImg();',5000);}catch(e){} // 測試舊版可能沒有pop()功能,會出現error 2159 return; 2160 } 2161 if(bgLoadImgA.length){var i=new Image(1,1);i.function(){setTimeout('bgLoadImg();',0);},i.src=typeof getObjURL=='function'?getObjURL(bgLoadImgA.pop()):bgLoadImgA.pop();bgLoadImgLA.push(i);} 2162 } 2163 2164 2165 TODO: 2166 Javascript uses automatic garbage collection. Set to [null] as well. http://www.thescripts.com/forum/thread95206.html 2167 須注意 JavaScript closure and IE 4-6 memory leak! IE 7 seems to have solved the memory leaks. http://anotherblog.spaces.live.com/blog/cns!E9C5235EBD2C699D!458.entry?ppud=0&wa=wsignin1.0 2168 http://laurens.vd.oever.nl/weblog/items2005/closures/ http://www.blogjava.net/tim-wu/archive/2006/05/29/48729.html 2169 IE 6對於純粹的Script Objects間的Circular References是可以正確處理的,可惜它處理不了的是JScript與Native Object(例如Dom、ActiveX Object)之間的Circular References。 2170 P.S. 2007/11/11 似乎已修正? 2171 */ 2172 2173 /* bgLoadImg() Cookie版 2006/3/3 20:08 2174 ** 本函數正著load!請將優先度高的排前面! 2175 2176 To use: 2177 ,set_cookie,get_cookie,bgLoadImgId,bgLoadImgI,bgLoadImg 2178 bgLoadImgId='id_of_this_session',bgLoadImgA='img_url1,img_url2,..'; // ** MUST string! 2179 function getObjURL(bgLoadImgA_element){return the real URL of bgLoadImgA_element;} 2180 window.onload="bgLoadImg();" 2181 2182 var bgLoadImgId='bg',bgLoadImgI; // loaded index 2183 */ 2184 //bgLoadImg[generateCode.dLK]='bgLoadImgId,bgLoadImgI'; 2185 function bgLoadImg(i) { 2186 var bgLoadImgM = 'bgLoadImgOK_' + bgLoadImgId; 2187 // alert('_'+bgLoadImgM+','+bgLoadImgI) 2188 if (typeof bgLoadImgA != 'object') { 2189 // needless 2190 if (!bgLoadImgA || location.protocol === 'file:') 2191 return; 2192 // http://msdn.microsoft.com/workshop/author/dhtml/reference/properties/readystate_1.asp 2193 var r = document.readyState; 2194 if (typeof r === 'string' && r !== 'complete') { 2195 setTimeout(bgLoadImg, 500); 2196 return; 2197 } 2198 // initialization 2199 bgLoadImgA = bgLoadImgA.replace(/,\s*,/g, ',').split(','); 2200 if (typeof get_cookie != 'function' 2201 || get_cookie(bgLoadImgM) != bgLoadImgA.length) { // 全部OK後就別再來了。 2202 if (isNaN(bgLoadImgI)) 2203 bgLoadImgI = 0; 2204 if (typeof r != 'string') { 2205 setTimeout(bgLoadImg, 5e3); 2206 return; 2207 } 2208 } else 2209 return; 2210 } 2211 2212 //if(!isNaN(i)&&!bgLoadImgA[i].complete); // timeout 2213 if(!isNaN(i)&&i<bgLoadImgI-1)return; // 防止timeout的備援 2214 2215 // 標記已load counter 2216 // 假如一個圖一個圖標記,set_cookie在超過二十個之後好像就沒效了…被限制? 2217 _.set_cookie(bgLoadImgM,bgLoadImgI); 2218 2219 if(bgLoadImgI==bgLoadImgA.length)bgLoadImgI++,setTimeout('bgLoadImg();',500); // 馬上進入判別,最後一個尚未complete 2220 else if(bgLoadImgI<bgLoadImgA.length){ 2221 var bgLoadImgURL=typeof getObjURL=='function'?getObjURL(bgLoadImgA[bgLoadImgI]):bgLoadImgA[bgLoadImgI]; 2222 //setTimeout('bgLoadImg('+bgLoadImgI+')',5e3); // set timeout 2223 with(bgLoadImgA[bgLoadImgI++]=new Image(1,1)) 2224 // 這是個多執行緒技巧:假如使用onload=bgLoadImg,有可能在下一指令碼前就已onload,這樣會造成Stack overflow 2225 onload=function(){setTimeout('bgLoadImg();',0);}, 2226 src=bgLoadImgURL; 2227 window.status='bgLoadImg ['+bgLoadImgURL+']: '+bgLoadImgI+' / '+bgLoadImgA.length+'..'; 2228 }else{ 2229 /* 2230 var f=[]; 2231 for(i=0;i<bgLoadImgA.length;i++)if(!bgLoadImgA[i].complete)f.push(bgLoadImgA[i].src); 2232 if(f.length)_.set_cookie(bgLoadImgM,0); 2233 window.status='bgLoadImg '+(f.length?'end: failed '+f.length+' / '+bgLoadImgA.length+' ('+f+')':'complete!'),bgLoadImgA=0; 2234 */ 2235 var f = 0; 2236 for (i = 0; i < bgLoadImgA.length; i++) 2237 if (!bgLoadImgA[i].complete) 2238 f++; 2239 if (f) 2240 _.set_cookie(bgLoadImgM, 0); 2241 window.status = 'bgLoadImg ' 2242 + (f ? 'end: failed ' + f + ' / ' + bgLoadImgA.length 2243 : 'complete!'), bgLoadImgA = 0; 2244 } 2245 }; 2246 2247 2248 2249 /* 儲存/回存使用者輸入之form資料用。 2004/11/23 21:38 2250 *已測試過text(select-one,textarea,password,hidden)/radio/checkbox/select-multiple 2251 formIdA: form id or id array.不輸入或輸入'',0等表示所有的form 2252 expires: 不輸入或輸入''表示回存,輸入0會以預設days代替,輸入<0會刪除掉cookie中這項設定。 2253 targetItemA: 要處理的name。例如'name,tel,email'。假如包括unselect,會處理除了targetItemA之外所有的。 2254 2255 input type="checkbox" value不能包含';'! 2256 password也會被儲存,得自己排除! 2257 e.g., 2258 cookieForm() recall all items of all forms 2259 cookieForm(0,1,'email'); save all items named 'email' of all forms 2260 cookieForm(0,'','email'); recall all items named 'email' of all forms 2261 cookieForm(0,-1); 消除所有*版面上現有form*之紀錄 2262 2263 TODO: 2264 排除名單 2265 對於較多的entries,也許需要使用到Object[key]來代替String.indexOf(key) 2266 */ 2267 //cookieForm[generateCode.dLK]='get_cookie,set_cookie'; 2268 function cookieForm(formIdA,expires,targetItemA){ 2269 if (typeof document != 'object') 2270 return; 2271 if(!formIdA)formIdA=document.getElementsByTagName('FORM');else if(typeof formIdA=='string')formIdA=[formIdA]; 2272 var i,n,o,dealO=function(o){ // メソッドをプロトタイプではなく、オブジェクト自身にセットしていることです。これでは継承できませんし、ECMAScript のプロトタイプベースのセマンティクスから外れてしまいます。 2273 for(var j=0,c=o.childNodes,sp=';',e,cn,cv,tp;j<c.length;j++){ 2274 if((e=c[j]).hasChildNodes)dealO(e); 2275 if(e.name&&typeof e.value!='undefined'){//cv=e.tagName=='TEXTAREA'?e.innerHTML:e.value // TEXTAREA,SELECT,OPTION,INPUT需使用.value! 2276 //if(!e.value&&e.text)e.value=e.text; // 假如沒有.value,利用.text代替 2277 if(targetItemA)if(targetItemA.unselect&&targetItemA[e.name]||!targetItemA.unselect&&!targetItemA[e.name])continue; 2278 //alert((isNaN(expires)?'load':'save')+'\n'+n+'::'+e.name+'['+e.type+']='+e.value); 2279 cn='cookieForm_'+n+'_'+e.name;cv=e.value; 2280 tp=e.type.toLowerCase();//e.tagName=='INPUT'?e.type.toLowerCase():''; 2281 if(isNaN(expires)){if(typeof(cn=get_cookie(cn))!='undefined'){ 2282 if(tp=='radio'){ 2283 if(cv==cn)e.checked=true; 2284 }else if(tp=='checkbox'){ 2285 if(cn.indexOf(sp+cv+sp+sp)!=-1)e.checked=true; 2286 }else if(tp=='select-multiple') 2287 for(var i=0;i<e.options.length;i++) 2288 e.options[i].selected=cn.indexOf(sp+e.options[i].value+sp)!=-1; 2289 else e.value=cn; 2290 }}else{ 2291 if(tp=='radio'){if(!e.checked)continue;} 2292 else if(tp=='checkbox') 2293 if(cv.indexOf(sp)!=-1)continue; // value不能包含sp checkbox之cookie形式:[;value1;;value2;value3;;value4;]:value1,3:checked 2294 else cv=((tp=get_cookie(cn))&&tp.indexOf(sp+cv+sp)==-1?tp:sp)+cv+sp+(e.checked?sp:''); 2295 //else if(tp=='select-one')cv=e.options[e.selectedIndex].value; // 可省略! 用.selectedIndex會比較快,但更改原文件可能會造成index錯誤 2296 else if(tp=='select-multiple'){ 2297 cv=sp+cv+sp; 2298 for(var i=e.selectedIndex+1;i<e.options.length;i++) 2299 if(e.options[i].selected)cv+=e.options[i].value+sp; 2300 } 2301 if(expires)_.set_cookie(cn,cv); 2302 else _.set_cookie(cn); 2303 } 2304 } 2305 } 2306 }; 2307 2308 if(targetItemA){ 2309 o=targetItemA;targetItemA={};if(typeof o=='string')o=o.split(','); 2310 for(i in o)targetItemA[o[i]]=1; 2311 } 2312 if(expires==='')expires=NaN; 2313 if(!isNaN(expires)){ 2314 if(expires)expires=7; // 預設days 2315 _.set_cookie(_.set_cookie.f.set_root); // Gecko need this 2316 _.set_cookie('expires',expires); 2317 } 2318 for(i=0;i<formIdA.length;i++)if(o=formIdA[i]){ 2319 if(typeof o=='string')o=document.getElementById(n=o);else if(!(n=o.id))n=o.name; 2320 if(o&&(o.tagName||'').toLowerCase()=='form'&&n&&typeof n=='string')dealO(o); 2321 } 2322 if(!isNaN(expires))_.set_cookie('expires',0); 2323 2324 } 2325 2326 2327 // 登入FTP IE使用者若要上傳,請開啟FTP 站台的資料夾檢視功能。 2328 // <input type="text" autocomplete="off"/> 2329 function loginFTP(n,p,path,hostname){ // name,password 2330 if(!hostname&&!(hostname=location.hostname))return; 2331 if(n=='ftp'||n=='anonymous')n=''; 2332 if(!p&&n)p=window.prompt('請輸入['+n+']之密碼:'); 2333 if(p==null)return; // 取消輸入 2334 p='ftp://'+(n?n+(p?':'+p:'')+'@':'')+(hostname+'/'+(path||'')).replace(/\/{2,}/g,'/'); 2335 window.open(p,'ftpW');//location.href=p; // 用location.href不能進入資料夾檢視功能 2336 } 2337 2338 2339 // reference page set ================== 2340 2341 CeL.interact.DOM 2342 . 2343 /** 2344 * 簡化 document.getElementById 並配合 loadReference() 2345 * @since 2004/6/25 19:33 2346 * @param id 所欲找尋之 element id 2347 * @param flag 2348 * {HTML Object} object: 參考此 document object 2349 * {Number} flag: 參見 code 2350 * @return {HTML Object} Object 2351 * @requires referenceDoc,loadReferenceDone,`get_element();` 2352 * @memberOf CeL.interact.DOM 2353 */ 2354 get_element = function get_element(id, flag) { 2355 var _s = get_element, _f = _s.f; 2356 if (!_f) 2357 // 在 Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.6) Gecko/20040510 中會出問題,所以改到函數中執行。但得先執行過一次。 2358 //alert('get_element: set flags get_element.f'), 2359 _s.f = _f = { 2360 // 僅參考自身頁面,default 2361 'self' : 0, 2362 // 可參考 reference page 2363 'ref' : 1, 2364 // 僅參考 reference page 2365 'refOnly' : 2 2366 }; 2367 2368 if (!id || typeof window !== 'object' || typeof document !== 'object' 2369 || document !== window.document) 2370 return null; 2371 // if(flag)alert('get_element: '+id+','+flag); 2372 2373 // 後面暫時沒用到 2374 // if(!flag)flag=_f.self; 2375 2376 if ( 2377 //typeof document !== 'object' || 2378 !document.body) 2379 // document 尚未 load 2380 return; 2381 2382 if(_.is_HTML_element(id)) 2383 return id; 2384 2385 var o; 2386 if (flag !== _f.refOnly) 2387 // 僅參考 reference page 時不設定 2388 o = document.getElementById ? document.getElementById(id) 2389 : document.all ? document.all[id] 2390 : document.layers ? document.layers[id] 2391 : window[id]; 2392 //if(flag)alert('get_element: '+id+','+flag+'\nloadReferenceDone='+loadReferenceDone+'\nreferenceDoc: '+referenceDoc+'\no: '+o+'\nreferenceDoc.get: '+referenceDoc.getElementById(id)+'\n'+referenceDoc.body.innerHTML.slice(0,200)); 2393 try { 2394 // 偶爾還是有可能'沒有使用權限' 2395 typeof flag === 'object' && typeof flag.getElementById === 'function' && (o = flag.getElementById(id)) 2396 || o 2397 || flag && loadReferenceDone === 1 && (o = referenceDoc.getElementById(id)); 2398 } catch (e) { 2399 } 2400 return o || null; 2401 }; 2402 2403 2404 2405 /* 以外掛的reference page配置data object 2004/6/25 21:01 2406 2407 toUse: 2408 準備好reference.htm 2409 在需要的文件加入 window.onload="loadReference()"; 2410 在需要的文件body加入 <iframe id="reference"></iframe> 2411 function setupPageR() initial after load of reference page 2412 2413 如上,再使用 get_element() 即可得到 reference.htm 中的 obj 2414 */ 2415 var referenceDoc,loadReferenceDone;//,loadReferenceCount; 2416 //loadReference[generateCode.dLK]='get_element,referenceDoc,loadReferenceDone,parseFunction'; 2417 function loadReference(referenceURL,iframeId){ 2418 if(loadReferenceDone||typeof location!='object'||!location.protocol||location.protocol=='https:')return; // https會拒絕存取,所以直接放棄。 2419 //if(loadReferenceDone)return; // https會拒絕存取,所以直接放棄。 2420 var o=_.get_element(iframeId||'reference'),thisFuncName=parseFunction().funcName; 2421 if(typeof referenceDoc=='object' && typeof referenceDoc.document=='object' && referenceDoc.document){ // referenceDoc is still contentWindow here. typeof referenceDoc.document:預防使用https時產生不能讀取的權限問題。 2422 referenceDoc=o.contentWindow.document;//referenceDoc.document; // 遺憾:在舊版IE不能用後者。也許是因為舊版IE連contentWindow都會重造。 2423 o=referenceDoc.body;//alert(o.innerHTML.length+'\n'+o.innerHTML); 2424 if(o/*&&referenceDoc.body.innerHTML=='string'*/&&o.innerHTML.length){ 2425 //alert(typeof o+','+(o?typeof o.innerHTML+'('+o.innerHTML.length+')\n'+o.innerHTML.slice(0,200):'(null)')); 2426 // before IE5, the first argument must be a string. 2427 // setTimeout(function_handle,..) 不一定代表setTimeout('function_handle();',..),可能會傳入奇異的引數! 2428 if(typeof setupPageR=='function')setTimeout(setupPageR,9); 2429 loadReferenceDone=1;//window.status='reference page load OK!';alert(window.status); 2430 }else{ 2431 //try{window.status='Wait while reference page loading..3',alert(window.status+'\nURL:'+o.contentWindow.document.src+'\ncontent('+o.contentWindow.document.body.innerHTML.length+'):\n'+o.contentWindow.document.body.innerHTML);}catch(e){} 2432 //if(!--loadReferenceCount)history.go(0); 2433 setTimeout(thisFuncName+'();',200); 2434 } 2435 return; 2436 } 2437 if(typeof document!='object'||!document.body){ // document尚未load 2438 setTimeout(thisFuncName+'();',90); 2439 return 1; 2440 } 2441 //o=_.get_element(iframeId||'reference'); // 原來把設定放在這,不過反正都要在前面用到… 2442 if(!o||(o.tagName||'').toLowerCase()!='iframe'){loadReferenceDone=2;return;} // iframe不存在 2443 if(!o.src)o.style.display='none',//'block',// 2444 o.src=referenceURL; // for game.js: typeof relatePath=='function'?relatePath(0,'cgi-bin/game/data/reference.htm'):'data/reference.htm' 2445 2446 if(typeof o.contentWindow=='object'&&typeof o.contentWindow.document=='object'){ // typeof o.contentWindow=='object'&&: for JS5 應該不能用o.contentWindow吧?怕o.contentWindow就算沒能載入文件,也會被定義 2447 // Martin Honnen wrote: If you load a new document then certainly the browser has to create a new document object. 2448 referenceDoc=o.contentWindow;//.document; o.contentWindow.document still index to a blank window here, when new document load, this point to document won't work. 2449 2450 //window.status='Wait while reference page loading..2';alert(window.status+'\nURL:'+o.src); 2451 setTimeout(thisFuncName+'();',20);//loadReferenceCount=9; 2452 }else{ 2453 //if(location.protocol=='https:')return; // https會拒絕存取,所以直接放棄。最晚在這就得判別 2454 if(!referenceDoc)referenceDoc=40; // 尚未load完成時作倒數計時..假如加上if(o.contentWindow),這方法正確嗎? 2455 //else if(isNaN(referenceDoc))return 3; // 異常(for https):不能用else if(isNaN(referenceDoc)) 2456 try{ 2457 if(referenceDoc--){ 2458 //window.status='Wait while reference page loading..';alert(window.status); 2459 setTimeout(thisFuncName+'();',300);return 2; 2460 }else{ 2461 //window.status='reference page load FAILED!';alert(window.status); 2462 return 4; 2463 } 2464 }catch(e){ 2465 return 5; // Error: uncaught exception: Permission denied to get property HTMLDocument.document 2466 } 2467 } 2468 } 2469 // translate object(innerHTML) from reference page to document 2470 //transRefObj[generateCode.dLK]='get_element'; 2471 function transRefObj(id,id2,force){ 2472 if(typeof id2!='string'&&typeof id2!='object')force=id2,id2=typeof id=='object'?id.id:id; 2473 var o=typeof id=='object'?id:_.get_element(id,_.get_element.f.self),p; 2474 //alert('transRefObj: '+id2+' -> '+id+'('+(force?'':'not ')+'force)\n'+o+'\ntarget:'+(o.innerHTML?'\n'+o.innerHTML.slice(0,200):' (null)')); 2475 if( o && (force||!o.innerHTML) 2476 && (p=typeof id2=='object'?id2:_.get_element(id2,_.get_element.f.refOnly)) && (force||p.innerHTML) ) 2477 try{ 2478 //alert('transRefObj: DO '+id2+' -> '+id+'('+(force?'':'not ')+'force)\n'); 2479 o.appendChild(p.cloneNode(true)); 2480 }catch(e){ 2481 /* 2482 try{ 2483 //alert('transRefObj: try2'); 2484 var i=0;while(i<p.childNodes.length)o.appendChild(p.childNodes[i++].cloneNode(true)); 2485 }catch(e){ 2486 */ 2487 //alert('transRefObj: try3'); 2488 o.innerHTML=p.innerHTML;//p.cloneNode(true); //serialize(p) serialize方法把一个node串行化成字符串。在ie环境的具体实现上,对于XmlDocument,使用node.xml,对于HtmlDocument,使用node.outerHTML。 http://my.opera.com/gisor/blog/index.dml/tag/SVG 2489 /* 2490 } 2491 */ 2492 } 2493 return o; 2494 } 2495 2496 // ↑reference page set ================== 2497 2498 2499 2500 2501 2502 // 設定自動捲動 2503 var setAutoScrollTimer,setAutoScrollInterval; 2504 //setAutoScroll[generateCode.dLK]='setAutoScrollTimer,setAutoScrollInterval'; 2505 function setAutoScroll(interval,force){ 2506 if(!force)if(typeof document!='object'||setAutoScrollTimer||document.onmousedown||document.ondblclick)return; 2507 if(interval)setAutoScrollInterval=interval;else if(!setAutoScrollInterval&&!(setAutoScrollInterval=get_cookie('setAutoScrollInterval')))setAutoScrollInterval=200;//5,50,100,200,500 2508 clearInterval(setAutoScrollTimer),setAutoScrollTimer=0; // 無論如何,先把執行中的幹掉。 2509 if(setAutoScrollInterval<0){document.onmousedown=document.ondblclick=null;return;} 2510 document.onmousedown=function(){if(setAutoScrollTimer)window.clearInterval(setAutoScrollTimer),setAutoScrollTimer=0;}; 2511 document.ondblclick=function(){if(setAutoScrollTimer)return;setAutoScrollTimer=window.setInterval('window.scrollBy(0,1);',setAutoScrollInterval);};//window.scrollTo(0,document.body.scrollTop+1); 2512 } 2513 2514 2515 /* 捲到設定的定點,因為某些多工慢速環境中只設定一次沒有用,所以… 2516 下面一行調到檔案頭 2517 var scrollToXY,scrollToInterval,scrollToOK; 2518 */ 2519 //scrollTo[generateCode.dLK]='scrollToXY,scrollToInterval,scrollToOK,get_window_status'; 2520 function scrollTo(y,x){ 2521 // initial 2522 if(typeof scrollToXY!='object')scrollToXY={}; 2523 2524 if(typeof y=='object'&&(!isNaN(y.x)||!isNaN(y.y))){if(!isNaN(y.x))scrollToXY.x=y.x;if(!isNaN(y.y))scrollToXY.y=y.y;} 2525 else if(y instanceof Array)scrollToXY.x=y[0],scrollToXY.y=y[1]; 2526 else{if(typeof x!='undefined')scrollToXY.x=x;if(typeof y!='undefined')scrollToXY.y=y;} 2527 if(isNaN(scrollToXY.x))scrollToXY.x=0;if(isNaN(scrollToXY.y))scrollToXY.y=0; 2528 2529 setTimeout('window.scrollTo(scrollToXY.x,scrollToXY.y);',9); // main function 2530 var _w=get_window_status(); 2531 //status=scrollToInterval+','+scrollToOK+';'+_w.scrollX+','+scrollToXY.x+';'+_w.scrollY+','+scrollToXY.y; 2532 if(_w.scrollX==scrollToXY.x&&_w.scrollY==scrollToXY.y){ 2533 if(!--scrollToOK&&scrollToInterval)window.clearInterval(scrollToInterval),scrollToInterval=0; 2534 }else if(!scrollToInterval)scrollToInterval=window.setInterval(scrollTo,90),scrollToOK=3; // 預防萬一:總會跳回原處 2535 } 2536 2537 /* doAlert() & doAlertAccess:彈出使用注意事項視窗 2538 下面一行調到檔案頭 2539 var doAlertDivName,doAlertOldScrollLocation; 2540 2541 TODO 2542 設定其不可作用之 background object 2543 2544 使用方法: 2545 <head> 2546 <script type="text/javascript" src="function.js"></script> 2547 <script type="text/javascript"> 2548 window.onload=init;window.onscroll=window.onresize=doAlertScroll; 2549 function init(){doAlertInit('kousi');} 2550 </script> 2551 2552 <style type="text/css"><!-- 2553 2554 /* kousi用 加上filter:alpha(opacity=10);:因為IE5.5不吃DXImageTransform.Microsoft.Alpha,這樣用不能以.filters.alpha.opacity控制。 * / 2555 #kousi{color:blue;background:#e2e0f8;border:double 3px red;padding:.5em;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80,Style=0);filter:Alpha(Opacity=80,Style=0);z-index:2;overflow:auto;} 2556 #kousiBg{background:blue;filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=30,Style=0);filter:Alpha(Opacity=30,Style=0);z-index:1;} 2557 #kousiI{color:brown;background-color:#e6e6ff;cursor:pointer;border:1 solid red;white-space:nowrap;padding:2px;margin:2px;filter:Alpha(Opacity=80,Style=0);} 2558 2559 #kousi h2{color:brown;margin-left:2em;} 2560 #kousi input{color:#114f12;background-color:#fddbfb;border:1 brown solid;} 2561 2562 --></style> 2563 </head> 2564 2565 <body> 2566 <!--div id="kousiBg"></div--><div id="kousi"> 2567 <h2>使用注意事項</h2> 2568 2569 注意事項 2570 2571 <hr style="color:#928cd9"/> 2572 <table style="width:90%;text-align:center;"><tr><td><input type="button" onclick="top.location.href='http://www.hinet.net';" value="誰管你!"/></td> 2573 <td><input type="button" onclick="doAlertAccess();//this.parentNode.parentNode.parentNode.parentNode.parentNode.id" value="我願意遵守上述規定"/></td> 2574 <td><input type="button" onclick="set_cookie(set_cookie.f.forever),set_cookie('doAlert',doAlertDivName),doAlertAccess();" value="我往後皆會遵守上述規定"/></td></tr></table> 2575 </div> 2576 2577 <a href="#" onclick="doAlert();">注意事項</a> 2578 2579 正文 2580 2581 </body> 2582 */ 2583 function doAlertResize(){ // 確保置中 2584 if(typeof doAlertDivName!='string'||!doAlertDivName||!(o=document.getElementById(doAlertDivName)))return; 2585 with(o.style){ 2586 position='absolute',display='block',width='70%'; 2587 /* 因為'%'是以整體長寬為主,故不適用。 2588 var t=Math.round(50*(1-o.offsetHeight/document.body.clientHeight)); 2589 if(t<0)width='99%',top='0';else top=t+'%'; 2590 t=Math.round(50*(1-o.offsetWidth/document.body.clientWidth)); 2591 left=t<0?'0':t+'%'; 2592 */ 2593 //alert(offsetHeight+','+window.offsetHeight+','+window.innerHeight+','+window.outerHeight); 2594 if(typeof window.innerHeight=='undefined')window.innerHeight=document.body.clientHeight; 2595 if(typeof window.innerWidth=='undefined')window.innerWidth=document.body.clientWidth; 2596 var t=(window.innerHeight-o.offsetHeight)/2; 2597 if(t<0)width=height='99%',top=0;else top=t+'px'; 2598 t=(window.innerWidth-o.offsetWidth)/2; 2599 left=t<0?0:t+'px'; // 不用marginTop與marginLeft,因為這裡要放置div 2600 } 2601 } 2602 // 初始化 2603 //doAlertInit[generateCode.dLK]='set_cookie,doAlert'; 2604 function doAlertInit(n){ // n:div name 2605 //if(typeof doAlertDone!='undefined'&&doAlertDone)return; // 防止重複執行 2606 if(!n){ // doAlertInit()重設 2607 _.set_cookie(_.set_cookie.f.set_root); // Gecko need this 2608 _.set_cookie('doAlert'); 2609 return; 2610 } 2611 var d=document.getElementById(n); 2612 if(d){ 2613 if(typeof doAlertDivName=='undefined')doAlertDivName=n; 2614 doAlert(); 2615 } 2616 } 2617 // 出現警告 2618 //doAlert[generateCode.dLK]='doAlertInit,doAlertResize,doAlertAccess,doAlertScroll,doAlertDivName,doAlertOldScrollLocation,get_cookie,get_window_status'; 2619 function doAlert(n,m,iconContent){ // n:name,m:mode=1:use alert(),icon div的文字內容 2620 if(!n&&typeof doAlertDivName=='string'&&doAlertDivName)n=doAlertDivName; 2621 var o=document.getElementById(n),oBg=document.getElementById(n+'Bg'),oI=document.getElementById(n+'I'); 2622 if(!document.body||!o||m&&!alert(o.innerHTML))return; // alert()會return undefined 2623 if(!oI)try{ 2624 o.parentNode.insertBefore(oI=document.createElement('div'),o);//document.body.insertBefore(); 2625 oI.id=n+'I';oI.onclick=function(){doAlertInit();doAlert();};oI.title="注意事項"; 2626 oI.innerHTML=iconContent||'別忘了';oI.doAlertScrollT=oI.doAlertScrollL=0; 2627 }catch(e){return;} // 只對IE5.5之後有用 2628 if(!oBg)try{o.parentNode.insertBefore(oBg=document.createElement('div'),o);oBg.id=n+'Bg';}catch(e){return;} // 只對IE5.5之後有用 2629 //if(!oI||!oBg)alert('No index or bg div!'); 2630 disableKM(2);doAlertResize();window.Oonresize=window.onresize,window.onresize=doAlertResize; 2631 with(oI.style)display='none',position='absolute',right='.1em',top='.1em'; 2632 with(oBg.style)position='absolute',left=-parseInt(document.body.leftMargin),top=-parseInt(document.body.topMargin),width=height='110%',display='inline'; // offset*:唯讀 2633 if(o.filters)o.filters.alpha.opacity=85;//try{o.filters.alpha.opacity=85;}catch(e){} 2634 if(oBg.filters)try{oBg.filters.alpha.opacity=30;}catch(e){} 2635 else{ // for Moz 2636 o.style.position='fixed'; 2637 with(oBg.style)position='fixed',opacity=oBg.style['-moz-opacity']=.3,left=top=0,width=height='100%'; 2638 } 2639 if(get_cookie('doAlert')==n)doAlertAccess(n); 2640 else o=get_window_status(),doAlertOldScrollLocation=[o.scrollX,o.scrollY],setTimeout('scrollTo(0,0);',0); // 奇怪的是,直接執行scrollTo(0,0)沒啥用。 2641 } 2642 // pass 2643 function doAlertAccess(n){ 2644 if(!n&&typeof doAlertDivName=='string'&&doAlertDivName)n=doAlertDivName; 2645 var o=document.getElementById(n),oBg=document.getElementById(n+'Bg'); 2646 if(oBg)oBg.style.display='none';o.style.display='none'; 2647 disableKM(0); 2648 window.onresize=window.Oonresize||null; 2649 if(doAlertOldScrollLocation)scrollTo(doAlertOldScrollLocation,0,1); 2650 doAlertScroll(1); 2651 } 2652 // icon div的捲動:置於右上角 2653 //doAlertScroll[generateCode.dLK]='get_window_status'; 2654 function doAlertScroll(m){var oI; 2655 if(typeof doAlertDivName!='string'||!doAlertDivName||!(oI=document.getElementById(doAlertDivName+'I')))return; 2656 if(typeof m!='undefined'){ 2657 oI.style.display=m?'block':'none'; 2658 oI.doAlertScrollL=oI.offsetWidth+(m||0); 2659 if(oI.currentStyle){ // IE 2660 if(m=parseInt(oI.currentStyle.paddingTop))oI.doAlertScrollT=m; 2661 m=parseInt(oI.currentStyle.paddingLeft); 2662 if(m=parseInt(oI.currentStyle.paddingRight))oI.doAlertScrollL+=m; 2663 }else{ 2664 oI.style.position='fixed'; 2665 /* // Moz..but no use 2666 if(m=oI.offsetTop)oI.doAlertScrollT=m; 2667 m=oI.offsetLeft; 2668 if(m=oI.offsetRight)oI.doAlertScrollL+=m; 2669 */ 2670 } 2671 } 2672 //window.status=m=window.scrollX+','+window.scrollY+','+window.innerWidth+','+window.innerHeight+';'+document.body.scrollLeft+','+document.body.scrollTop+','+document.body.offsetWidth+','+document.body.clientWidth+','+oI.offsetWidth+','+document.body.scrollWidth;alert(m); 2673 m=get_window_status(); 2674 oI.style.left=m.scrollX+m.windowW-oI.doAlertScrollL+'px';//-document.body.leftMargin-document.body.rightMargin 2675 oI.style.top=m.scrollY-oI.doAlertScrollT+'px'; // 只有在padding用px時有效! 2676 } 2677 2678 2679 CeL.interact.DOM 2680 . 2681 /** 2682 * Sets / adds class of specified element.<br/> 2683 * TODO:<br/> 2684 * 1. 一次處理多個 className。<br/> 2685 * 2. 以字串處理可能較快。<br/> 2686 * 3. 用 +/- 設定。<br/> 2687 * 4. https://developer.mozilla.org/en/DOM/element.classList 2688 * @param element HTML elements 2689 * @param class_name class name || {class name 1:, class name 2:, ..} 2690 * @param flag 2691 * default: just add the specified className 2692 * (flag&1)==1: reset className (else just add) 2693 * (flag&2)==1: return {className1:, className2:, ..} 2694 * (flag&4)==1: remove className 2695 * @return 2696 * @see 2697 * <a href="http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-95362176" accessdate="2009/12/14 22:26">className of type DOMString</a>, 2698 * <a href="https://developer.mozilla.org/En/DOM/Element.className" accessdate="2009/12/14 22:27">element.className - MDC</a> 2699 * @memberOf CeL.interact.DOM 2700 */ 2701 set_class = function(element, class_name, flag) { 2702 if (typeof element === 'string') 2703 element = document.getElementById(element); 2704 2705 if (typeof element !== 'object' || !element || typeof element.className !== 'string') 2706 return; 2707 // if(!flag)flag=0; 2708 var c, remove = (flag & 4) == 4; 2709 2710 if (class_name && !remove) { 2711 c = class_name instanceof Array ? class_name.join(' ') : class_name; 2712 if (flag & 1) 2713 element.className = c; 2714 else 2715 // add 時不 detect 是為了速度 2716 element.className += ' ' + c; 2717 2718 if ((flag & 2) != 2) 2719 return; 2720 } 2721 2722 //sl('set_class: remove [' + class_name + '] from [' + o.className + ']'); 2723 c = element.className.split(/\s+/); 2724 var r = {}, i; 2725 2726 for (i in c) 2727 r[c[i]] = 1; 2728 2729 if (remove && class_name) { 2730 if (!(class_name instanceof Array)) 2731 class_name = [ class_name ]; 2732 for (i in class_name) { 2733 c = class_name[i]; 2734 if (c in r) { 2735 // has removed 2736 remove = 0; 2737 delete r[c]; 2738 } 2739 } 2740 if (!remove) { 2741 c = []; 2742 for (i in r) 2743 c.push(i); 2744 element.className = c.join(' '); 2745 } 2746 } 2747 2748 //sl('set_class: → ['+o.className+']'); 2749 return r; 2750 }; 2751 2752 // if cN instanceof RegExp, cN should has NO global flag. 2753 CeL.interact.DOM 2754 . 2755 /** 2756 * If HTML element has specified class 2757 * @param {HTMLElement} element HTML elements 2758 * @param {String} class_name class_name_1[ class_name_2 ..] 2759 * @return {Boolean} 2760 */ 2761 has_class = function(element, class_name) { 2762 var _s = _.has_class, n = element.className, i; 2763 //class_name = class_name.replace(/\s+$|^\s+/g, ''); 2764 if (!n || !class_name) 2765 return; 2766 2767 if (class_name instanceof Array) { 2768 for (i = n = 0; i < class_name.length; i++) 2769 if (_s(element, class_name[i])) 2770 n++; 2771 return n; 2772 } 2773 2774 if (class_name instanceof RegExp) 2775 return class_name.test(n); 2776 2777 if (n === class_name) 2778 return true; 2779 2780 //return (new RegExp('(^|\\s)' + class_name + '(\\s|$)'/* ,i */)).test(n); 2781 return (' '+n+' ').indexOf(' ' + class_name + ' ')!==-1; 2782 }; 2783 2784 2785 CeL.interact.DOM 2786 . 2787 /** 2788 * @param {String} class_name class_name_1[ class_name_2 ..] 2789 * @param {HTMLElement} element HTML elements 2790 * @param {HTMLElement} parent_node parent node 2791 * @param {String} tag_name tag name 2792 * @return {[HTMLElement]} nodes 2793 * @see 2794 * document.getElementsByClassName in prototype.js, 2795 * jquery('.class') 2796 * 2797 * document.querySelector() 2798 * http://www.w3.org/TR/selectors-api/ 2799 * http://blog.darkthread.net/blogs/darkthreadtw/archive/2008/04/17/document-queryselector-in-ie8.aspx 2800 */ 2801 find_class = function(class_name, parent_node, tag_name, call_function, 2802 flag) { 2803 var elements = class_name 2804 && (parent_node || document).getElementsByTagName(tag_name || '*'), l = elements 2805 && elements.length; 2806 2807 if (l) { 2808 var i = 0, c = [], r = new RegExp('(^|\\s)' + class_name + '(\\s|$)'/* ,i */); 2809 for (; i < l; i++) 2810 if (r.test(elements[i].className)/* has_class(elements, r) */ 2811 && (!call_function || call_function.call(elements[i]))) 2812 c.push(elements[i]); 2813 return c; 2814 } 2815 2816 return null; 2817 }; 2818 2819 2820 2821 2822 2823 /* 處理 popup 用 2824 對className的tag作popup處理 2825 window.onload="dealPopup()"; 2826 <b title="注釋">正文</b> 2827 */ 2828 //dealPopup[generateCode.dLK]='sPop,has_class'; 2829 function dealPopup(tag,classN,func){ 2830 if (!tag) 2831 tag = 'b'; 2832 2833 /* 2834 http://enable.nat.gov.tw/document/4_2.jsp 2835 http://ccca.nctu.edu.tw/~hlb/tavi/ABBRorACRONYM 2836 應該用abbr(abbreviation/abbrevitated form/簡稱) 2837 abbr包含acronym(頭文字/首字母縮寫,通常這個字的發音像一個字) 2838 根據W3C的規範說,中日文的縮寫格式要套用的是abbr標籤。 2839 XHTML2.0把acronym移掉了,只剩下abbr標籤。 2840 http://www.sovavsiti.cz/css/abbr.html 2841 if(!!document.all)document.body.innerHTML=document.body.innerHTML.replace(/<\s*(\/?)\s*abbr([>\s])/gi,'<$1span$2'); 2842 */ 2843 2844 var i, j, o = document.getElementsByTagName(tag), tp; 2845 dealPopup.list=[]; 2846 if(o.length)for(i=0;i<o.length;i++){ 2847 if (classN && !has_class(o[i], classN) || func 2848 && func(o[i])) 2849 continue; 2850 // 測試是否有特定標籤 2851 for (j = 0, tp = ''; j < sPopP.allTypes.length; j++) 2852 if (o[i][sPopP.allTypes[j]]) { 2853 tp = sPopP.allTypes[j]; 2854 break; 2855 } 2856 // 有的話設定event 2857 if( tp && (tp=sPop(o[i],sPopF[tp]|sPopF.nopop)) ){ 2858 //o[i].innerHTML+='<b style="color:peru">['+sPopP.types[tp]+']<\/b>'; 2859 2860 dealPopup.list.push(o[i]); 2861 if(tp==sPopF.window){ 2862 if(!o[i].onclick)o[i].onclick=new Function('sPop(this,'+tp+');'),o[i].style.cursor='pointer'; 2863 }else if(tp==sPopF.popup){ 2864 if(!o[i].onmouseover){//o[i].ruby=o[i].popup='', 2865 o[i].onmouseover=new Function('sPop(this,'+tp+');'); 2866 if(!o[i].onmouseout)o[i].onmouseout=new Function('sPop(this,sPopF.clearPop);'); 2867 if(!o[i].onclick)o[i].onclick=new Function('this.onmouseout=null;sPop(this,'+tp+');'),o[i].style.cursor='pointer'; 2868 } 2869 //else alert(tp+'\n'+sPopF[tp]+'\n'+typeof o[i].onmouseover+'\n'+o[i].onmouseover); 2870 } 2871 } 2872 } 2873 } 2874 /* 注釋(reference) / show popup-window or ruby 2004/4/3 17:20 2875 http://www.comsharp.com/GetKnowledge/zh-CN/TeamBlogTimothyPage_K742.aspx 2876 2877 example: 2878 <b onmouseover="sPop(this,sPopF._type_,'注釋')">txt</b> 2879 <b onmouseover="sPop(this,sPopF._type_)" title="注釋">txt</b> 2880 window.onload="dealPopup()"; + <b title="注釋">txt</b>,<b sPop="注釋">txt</b> 2881 <b onmouseover="sPop('.',this)">txt</b> 在每個字旁邊加上[.]或[。] 2882 sPop('txt') popup txt(自動設成sPopF.popup) 2883 sPop('txt',sPopF.window) popup txt by window 2884 2885 flag & type: 2886 sPopF.title/sPopF.auto (依字數)自動選取 2887 sPopF.ruby 採用<ruby> 2888 sPopF.popup 採用popup window 2889 sPopF.window 將資料開在新視窗 2890 2891 sPopF.nopop just test, don't popup(for ruby) 2892 sPopF.repeat repeat ruby 2893 sPopF.clearPop clear popup window 2894 sPopF.force 若是不能使用此種表示方法,則放棄顯示。(for popup @ Mozilla) 2895 2896 style class application(應用): 2897 sPopP.DclassName中所定之className為觸發事件時會設定的class 2898 2899 執行環境environment: 2900 JScript @ HTML 2901 2902 include function: 2903 String.x() 2904 parseFunction() 2905 setObjValue() 2906 2907 TODO: 2908 submenu 2909 http://dynamicdrive.com/dynamicindex1/popupmenu.htm 2910 Tipped - The Javascript Tooltip Framework 2911 http://projects.nickstakenburg.com/tipped 2912 2913 How to Create a Valid Non-Javascript Lightbox | Carsonified 2914 http://carsonified.com/blog/design/css/how-to-create-a-valid-non-javascript-lightbox/ 2915 2916 move/resize/最小化: popup dialog 2917 http://deluxepopupwindow.com/html-popup-dialog-vista-graphite.html 2918 2919 獨佔 window, 訊息列, 多功能(HTML+Script)內容 2920 http://vision-media.ca/resources/jquery/jquery-popup-plugin-review 2921 2922 key (Esc) 2923 time limit 2924 2925 */ 2926 var sPopP={} // sPop properties object 2927 ,sPopF // flag 2928 ,sPopError// for error 2929 ; 2930 2931 // 初始值設定 & 設定flag 2932 //if(sPopP)alert('sPopP 已被佔用!');else 2933 function sPopInit(){ 2934 2935 // 預設style class name:(null:used last time),ruby,popup,window 2936 sPopP.DclassName=',popupedTxt_ruby,popupedTxt,popupedTxt'.split(','); 2937 // 已登記的背景style,請在CSS中加入[sPopC]_[body class name] 2938 sPopP.bgS='bgb,bgn'; 2939 { 2940 var i=0,t=sPopP.bgS.split(',');sPopP.bgS={}; 2941 for(;i<t.length;i++)sPopP.bgS[t[i]]=i+1; 2942 } 2943 // popup window style 2944 sPopP.popupS="color:blue;padding:.5em;overflow:auto;position:absolute;top:0;left:0;width:100%;height:100%;scrollbar-face-color:khaki;scrollbar-arrow-color:teal;border:1px solid green;font:normal 10pt tahoma;filter:progid:DXImageTransform.Microsoft.Gradient(GradientType=0, StartColorStr=#ffd700, EndColorStr=#ffffff);"; 2945 // chars to repeat(for ruby) 2946 sPopP.RepeatC='‧.。ヽ○●◎☆★※*#▽▼△▲◆◇□■↓↑';//.turnU(); 2947 // types:auto,這些attribute可被處理,且將被視為自動選取type。 2948 sPopP.autoTypes='title,_sPop';//+',_'+sPopP.functionName 2949 // types,最多七種 2950 sPopP.types='ruby,popup,window'; // +div(參考dealLinkPopup()) 2951 // 所有可用的types,可用來detect是否能為sPop()所接受。但Mozilla中無法使用title之外的attribute。 2952 sPopP.allTypes=(sPopP.autoTypes+','+sPopP.types).split(','); 2953 // function name 2954 sPopP.functionName='';//;parseFunction().funcName; 2955 // popup window(for popup) 2956 if(typeof window.createPopup!='undefined')sPopP.window=window.createPopup(); 2957 { 2958 var i=0,t=sPopP.types.split(','),T=''; 2959 for(;i<t.length;)T+=t[i]+'='+ ++i+',';//alert(T); 2960 setObjValue('sPopF','title=0,auto=0,' 2961 //+'_'+sPopP.functionName+'=0,' 2962 +T+'nopop=8,repeat=16,clearPop=32,force=64','int'); 2963 } 2964 // sPopP.types[index]=type name 2965 sPopP.types=( 2966 //'_'+sPopP.functionName+ 2967 ','+sPopP.types).split(','); 2968 sPopP.commentTitle='Comment'; // 註解 2969 sPopP.commentTitlePattern=sPopP.commentTitle+' of %s'; 2970 sPopP.closeM='Close'; // close message: 關閉視窗或popup 2971 sPopP.biggerM='Bigger'; // bigger message: 放大 2972 sPopP.resetM='Reset size'; // reset size message: 回復原大小 2973 } 2974 2975 // 主object(正文或主object,會從之取得正文與注釋)[, flag, text string or object(注釋,會蓋過從主object取得之text), 使用的class name] 2976 //sPop[generateCode.dLK]='sPopP,sPopF,sPopInit,*sPopInit();'; 2977 function sPop(oPos,flag,oTxt,classN){ 2978 //if(flag&sPopF.clearPop){if(sPopP.window)sPopP.window.hide();return;} 2979 2980 // input value test & 修正 2981 if(!oPos&&!oTxt)return; 2982 2983 var limitW=screen.width-50,limitH=screen.height>>1; 2984 if(!sPopP.width)sPopP.width=250;if(sPopP.width>limitW)sPopP.width=limitW; 2985 if(!sPopP.height)sPopP.height=100;if(sPopP.height>limitH)sPopP.height=limitH; 2986 2987 // 初始值設定 2988 if(!sPopP.functionName) 2989 sPopF[ sPopP.types[0]='_'+(sPopP.functionName=parseFunction().funcName) ]=0; 2990 2991 var repopMark='repop',repop=oPos===repopMark,nopop=flag&sPopF.nopop,tp=flag&7 2992 ,useAttbTxt=false,brReg=/\r*\n/g,brT='<br/>\n'; // 轉成br用 2993 2994 if(repop){ 2995 if( !sPopP.popObj || typeof sPopP.popObj!='object' || typeof sPopP.popObj.innerHTML!='string' || !sPopP.popObj.innerHTML )return; 2996 oPos=sPopP.popObj,tp=sPopF.popup; // 重pop時不作其他判別處置 2997 }else{ 2998 2999 // 處理object 3000 if( typeof oPos=='string' && oPos ) 3001 if( oPos.length<32 && document.getElementById(oPos) ) 3002 oPos=document.getElementById(oPos); // 輸入object name時轉成object 3003 else if(!oTxt)oTxt=oPos // 若只輸入oPos,將之當作注釋(oTxt)。 3004 //,oPos=typeof null=='object'?0:null; 3005 ,oPos=0; // 若是typeof null=='object',請設成false 3006 3007 // 設定oTxt 1/4 3008 if( typeof oTxt=='object' && oTxt.innerHTML )oTxt=oTxt.innerHTML; 3009 else if(oTxt)oTxt+=''; // 轉成string 3010 3011 // (自動)判別使用的type 3012 var useAutoTxt; 3013 if(tp==sPopF.auto){ 3014 // 設定oTxt 2/4 : 知道是自動判別後先設定 3015 if( typeof oPos=='object' && (!oTxt||oTxt==0) ) 3016 if(oPos[sPopP.types[0]])oTxt=oPos[sPopP.types[0]],useAutoTxt=true; 3017 else if(oPos.title)oTxt=oPos.title,useAutoTxt=true; // 以<b title="~">的用法來說,這是最常經過的path 3018 3019 // 假如沒有oTxt.gText(),改成oTxt.replace(/<[^>]*>/g,'')之即可。這是為了預防HTML的情形。 3020 var len=typeof oTxt=='string'?oTxt.length:0;//typeof oTxt=='string'?oTxt.length:typeof oTxt=='object'&&oTxt.innerHTML?oTxt.innerHTML.length:0; 3021 //alert(len+','+(len*.7)+','+oPos.innerHTML.length); 3022 if( typeof oPos=='object' && ( oPos.doneRuby || !oPos.innerHTML.match(/<\s*ruby/i) && (len<60&&len*.7-9<(typeof oPos.innerText=='string'?oPos.innerText:oPos.innerHTML).length) ) ) 3023 tp='ruby'; // ruby的條件 3024 else if(sPopP.window&&len<300){ 3025 tp='popup'; 3026 if(typeof oPos=='object'&&oPos.title===oTxt)oPos[sPopP.types[0]]=oTxt,oPos.title=''; 3027 }else tp='window'; 3028 3029 // 設定oTxt 3/4 & type 3030 if( typeof oPos=='object' && (!oTxt||oTxt==0) ) 3031 if(oPos[tp])oTxt=oPos[tp],useAutoTxt=true; 3032 3033 tp=sPopF[tp]; 3034 } 3035 3036 // 設定oTxt 4/4 3037 if( !oTxt||oTxt==0 && typeof oPos!='object') 3038 if( (oTxt=oPos[sPopP.types[tp]]) || (oTxt=oPos[sPopP.types[0]]) || (oTxt=oPos.title) )useAutoTxt=true;else return; 3039 3040 // 設定className與position 3041 sPopP.left=0,sPopP.top=20; // popup left,popup top初始值 3042 if( !oPos || typeof oPos!='object') 3043 // popup 在滑鼠指標處 3044 // see: add_listener() 3045 try{sPopP.left+=event.offsetX,sPopP.top+=event.offsetY;}catch(e){} 3046 else if( !oPos.className && sPopP.DclassName[tp] ){ 3047 if(!classN&&(classN=document.body.className)&&!sPopP.bgS[classN])classN=0; 3048 oPos.className=sPopP.DclassName[tp]+(classN?'_'+classN:''); 3049 var w,s=oPos.style;if(!s.fontWeight&&(w=oPos.parentNode.style.fontWeight))s.fontWeight=w; // 除非有明確設定font-weight,否則通常不會有效 3050 } 3051 } 3052 3053 // 修正 3054 if( tp==sPopF.popup && !sPopP.window && !(flag&sPopF.force) ) 3055 tp=sPopF.window; // Mozilla中無法顯示popup 3056 3057 3058 //alert(sPopP.types[tp]+','+( sPopP.window || flag&sPopF.force )+','+oTxt); 3059 // 處理pop 3060 if(tp==sPopF.ruby){ 3061 if(typeof oPos!='object'||!oPos.innerHTML)return; // oPop非HTML element就return 3062 if(oPos.doneRuby)return tp; // 已經處理過<ruby>就pass 3063 // 處理repeat 3064 if( flag&sPopF.repeat || sPopP.RepeatC.indexOf(oTxt)!=-1 ) 3065 oPos.title='',oTxt=window.navigator.userAgent.indexOf("MSIE")<0?'':oTxt.x(oPos.innerHTML.length/oTxt.length); // 只有IE提供ruby,所以這時候不宜加入旁點功能。 3066 3067 try{ 3068 oPos.innerHTML='<ruby><rb>'+oPos.innerHTML+'<\/rb><rp>' 3069 // 半形與全形的括弧 3070 +(oTxt?window.navigator.userAgent.indexOf("Opera")>=0||/^[a-z\d\s_,.;"'\[\]{}+\-*\/]*$/i.test(oTxt)?'(<\/rp><rt>'+oTxt+'<\/rt><rp>)':'(<\/rp><rt>'+oTxt+'<\/rt><rp>)':'<\/rp><rt><\/rt><rp>') 3071 +'<\/rp><\/ruby>'; 3072 }catch(e){ 3073 var n=e.number&0xFFFF; 3074 if(n==601&&(typeof sPopError=='undefined'||sPopError!=n))alert('Error: '+e.description+' at\n'+oPos.outerHTML+'\n\n★也許是在這之前的tag出錯,例如有<b>卻沒有<\/b>。'); 3075 sPopError=n; 3076 } 3077 oPos.doneRuby=true; 3078 3079 }else if(tp==sPopF.popup){ 3080 if(nopop||!sPopP.window)return tp; 3081 if(!repop){ 3082 if(useAutoTxt)oTxt=oTxt.replace(brReg,brT); 3083 // 這是一種註解功能,在mouseout後,假定讀者繼續讀下去,所以就讓popup object消失。想要多看一點的,會去按他,這時才讓popup object繼續存在。 3084 sPopP.window.document.body.innerHTML=//oTxt= 3085 '<div style="'+sPopP.popupS+'" onblur="parent.sPopP.window.hide();" title="reference">[<b style="color:peru;cursor:pointer;" onclick="parent.sPopP.window.hide();">'+sPopP.closeMessage+'<\/b>] [<b style="color:green;cursor:pointer;" onclick="with(parent)sPopP.width+=100,sPopP.height+=50,' 3086 +sPopP.functionName+'(\''+repopMark+'\');">'+sPopP.biggerM+'<\/b>] [<b style="color:orange;cursor:pointer;" onclick="with(parent)sPopP.width=sPopP.height=0,'+sPopP.functionName+'(\''+repopMark+'\');">'+sPopP.resetM+'<\/b>]<hr style="color:purple;height:1px"/>'+oTxt.replace(/'/g,''')+'<\/div>'; 3087 sPopP.popObj=oPos||document.body; // object deal now(for popup:repop) 3088 //if(typeof oPos.onmouseout!='undefined')oPos.onmouseout=function(){sPopP.window.hide();}; 3089 } 3090 //alert(sPopP.width+','+sPopP.height); 3091 if(flag&sPopF.clearPop)sPopP.window.hide(); 3092 else sPopP.window.show(sPopP.left,sPopP.top,sPopP.width,sPopP.height,oPos||document.body); 3093 3094 }else if(tp==sPopF.window){ 3095 if(nopop)return tp; 3096 //if(typeof netscape=='object')netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserWrite"); // 創造無邊框視窗:titlebar=no dependent:ns only 全螢幕:channelmode 带有收藏链接工具栏的窗口:directories 网页对话框:'dialogWidth:400px;dialogHeight:300px;dialogLeft:200px;dialogTop:150px;center:yes;help:yes;resizable:yes;status:yes' 3097 /* 3098 dialogHeight: iHeight 设置对话框窗口的高度。 3099 dialogWidth: iWidth 设置对话框窗口的宽度。 3100 dialogLeft: iXPos 设置对话框窗口相对于桌面左上角的left位置。 3101 dialogTop: iYPos 设置对话框窗口相对于桌面左上角的top位置。 3102 center: {yes | no | 1 | 0 } 指定是否将对话框在桌面上居中,默认值是“yes”。 3103 help: {yes | no | 1 | 0 } 指定对话框窗口中是否显示上下文敏感的帮助图标。默认值是“yes”。 3104 resizable: {yes | no | 1 | 0 } 指定是否对话框窗口大小可变。默认值是“no”。 3105 status: {yes | no | 1 | 0 } 指定对话框窗口是否显示状态栏。对于非模式对话框窗口,默认值是“yes”;对于模式对话框窗口,默认值是 “no”。 3106 3107 window.showModalDialog(), window.showModelessDialog(): IE only. 不如用Ajax 3108 */ 3109 var w=window.open('','comment','titlebar=no,dependent,resizable=1,menubar=0,toolbar=0,location=0,scrollbars=1,width=550,height=400'/*,fullscreen*/,false) 3110 ,t=sPopP.commentTitle,_t=oPos.innerHTML&&oPos.innerHTML.length<9?sPopP.commentTitlePattern.replace(/%s/,oPos.innerHTML):t; // head, document.title 3111 //if(typeof netscape=='object')netscape.security.PrivilegeManager.disablePrivilege("UniversalBrowserWrite"); 3112 if(document.title)t+=' @ ['+document.title+']',_t+=' @ '+document.title; 3113 //else t+=' @ [<a href="'+location.href+'">'+location.pathname+'<\/a>]'; 3114 with(w.document)open(), 3115 write( 3116 //'<?xml version="1.1" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="content-type" content="text/html;charset=utf-8"/><title>' 3117 //+_t+'<\/title><script type="text/javascript">window.onblur=function(){window.close();};<\/script><\/head><body><b style="color:#11f;">'+t+':<\/b>' 3118 '<script type="text/javascript">window.onblur=function(){window.close();};<\/script><b style="color:#11f;">'+t+':<\/b>' 3119 +(oPos.innerHTML?'<div id="s" style="color:#488;background-color:#FF8;">\n'+oPos.innerHTML.replace(/\n/g,'<br/>').replace(/ /g,' ')+'\n<\/div><hr/>':'') //;white-space:normal;width:500px:useless ** 這邊會對<b title="..等造成影響! 3120 +'<div id="c" style="color:#404;background-color:#8FF;">\n'+oTxt.replace(/\n/g,'<br/>').replace(/ /g,' ') // 以不換行(pre)的方式顯示.patch 3121 +'\n<\/div><hr/>[ <b style="cursor:pointer;color:#40f;" onclick="javascript:opener.focus();self.close();">'+sPopP.closeMessage+'<\/b> ]')//+'</body></html>' 3122 ,close(),title=_t; 3123 w.focus(); 3124 w=0; // open出來的窗口即使close了,它的window對象還是存在的,要記得刪除引用 http://www.blogjava.net/tim-wu/archive/2006/05/29/48729.html 3125 }//else alert('type error: '+tp+'!'); 3126 3127 return tp; // 回傳決定的type 3128 } 3129 3130 3131 /* 開啟連結於 target 3132 ** 最好將openAtInit();設在onload 3133 JScript solution for attribute 'target' @ XHTML1.1 <a target="tag">之取代策略 3134 way 1: ,captureE,openAtInit,"openAtInit();",openAt 3135 onload: + openAtInit() ,captureE,openAtInit,"openAtInit();",openAt 3136 target="tag" → onclick="return openAt('tag')" 3137 target="_blank" → onclick="return openAt()" 3138 target="_self" → onclick="return openAt(1)" 3139 way 2: ,openAt 3140 target="_blank" → onclick="return openAt(0,this.href)" 3141 target="_self" → onclick="return openAt(1,this.href)" 3142 http://tohoho.wakusei.ne.jp/js/event.htm 3143 3144 TODO: 3145 http://hi.baidu.com/monyer/blog/item/56f1c88095fc96d79023d931.html 3146 a{text:expr/*XSS* /ession(target="_blank");} 3147 3148 http://blog.fanstown.net/blogs/jerry/archive/2007/04/04/HTML_8476_rel_5E5C2760E68BE3890230_.aspx 3149 原來這樣寫的代碼: 3150 <a href="document.html" target="_blank"> 打開一個新窗口</a> 3151 現在要寫成這樣: 3152 <a href="document.html" rel="external">打開一個新窗口</a> 3153 這是符合strict標準的方法。當然還必須配合一個javascript才有效。 3154 ** 應該 binding a.onclick 或 a.keypress 3155 rel是relationship的英文縮寫.rel與rev具有互補的作用,rel指定了向前鏈接的關係,rev指定了反向鏈接的關係. 3156 3157 */ 3158 var captureE; 3159 // 初始化設定 3160 //openAtInit[generateCode.dLK]='captureE'; 3161 function openAtInit(){ 3162 if(typeof captureE!='object'&&(typeof Event=='object'||typeof Event=='function')){ // for moz 3163 // http://developer.mozilla.org/en/docs/DOM:element.addEventListener http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event 3164 if(Event.mousedown)window.captureEvents(Event.mousedown); 3165 if(Event.keydown)window.captureEvents(Event.keydown); 3166 window.onmousedown=window.onkeydown=function(e){ 3167 captureE=e;//alert('openAtInit: '+e.target.tagName); 3168 }; 3169 } 3170 for(var i,a=document.getElementsByTagName('a');i<a.length;i++) 3171 if(a[i].onclick&&!a[i].onkeypress&&(''+a[i].onclick).indexOf('openAt')!=-1)a[i].onkeypress=a[i].onclick; 3172 } 3173 // open h(ref) in tag(et) 3174 //openAt[generateCode.dLK]='captureE,openAtInit'; 3175 function openAt(tag,h){ 3176 if(!tag)tag='_blank';//typeof tag=='undefined'|| 3177 else if(tag===1)tag='_self'; 3178 var t; 3179 if(!h&&typeof event=='object')h=event.srcElement.href; 3180 3181 // 對Gecko等使用標準(?)Document Object Model的 3182 // http://www.w3.org/TR/REC-DOM-Level-1/ecma-script-language-binding.html 3183 if(!h&&typeof captureE=='object'&&typeof captureE.target=='object'){ 3184 t=captureE.target; 3185 while(!(h=t.href)&&(t=t.parentNode)); 3186 } 3187 3188 //alert(h+','+tag+'\n'+captureE.target.parentNode.tagName+":");//+captureE.target.parentElement().tagName 3189 if(h)window.open(h,tag).focus(); 3190 return false; 3191 } 3192 3193 /* display mark to valid document 3194 <div id="valid"> </div> 3195 window.onload="addValid()"; 3196 搞定之後把自己網站提交到W3C Sites收錄。 http://www.w3csites.com/ 3197 3198 for RSS: 3199 http://rss.scripting.com/?url=http%3A%2F%2Flyrics.meicho.com.tw%2Fgame%2Frss.xml 3200 http://feedvalidator.org/check.cgi?url=http%3A%2F%2Flyrics.meicho.com.tw%2Fgame%2Frss.xml 3201 */ 3202 function addValid(v,tf){ // object to insert valid, target window/frame 3203 if(location.protocol=='file:')return; 3204 if(!v)v='valid';if(typeof v!='object')v=document.getElementById(v); 3205 if(!v)return 1;if(v.innerHTML.replace(/ /g,'').replace(/\s+/g,''))return 2; 3206 3207 if(typeof tf==='undefined')tf='valid_window';//tf=dQuote(tf);//tf?' target="'+tf+'"':''; 3208 var i=0,t='',d,addValidData=[ 3209 'Valid XHTML 1.1! by W3C http://validator.w3.org/check?uri=referer http://www.w3.org/Icons/valid-xhtml11' 3210 //,'Valid XML 1.0! by W3C ' 3211 ,'Valid CSS! by W3C http://jigsaw.w3.org/css-validator/check/referer http://jigsaw.w3.org/css-validator/images/vcss' // http://jigsaw.w3.org/css-validator/validator?uri=~ 3212 ,'Validome Validation Services http://www.validome.org/referer http://www.validome.org/images/valid/set2/valid_xhtml_1_1.png' 3213 ,'Another HTML-lint check http://openlab.ring.gr.jp/k16/htmllint/htmllint.cgi?ViewSource=o http://openlab.ring.gr.jp/k16/images/ahl-blue.gif' 3214 ,'Bobby WAI-AAA Approved by bobby@watchfire.com http://bobby.watchfire.com/bobby/bobbyServlet?URL=~&output=Submit&gl=wcag1-aaa http://bobby.watchfire.com/bobby/html/en/images/approved_aaa.gif' 3215 ,'Bobby 508 Approved by bobby@watchfire.com http://bobby.watchfire.com/bobby/bobbyServlet?URL=~&output=Submit&gl=sec508 http://bobby.watchfire.com/bobby/html/en/images/approved_508.gif' 3216 // http://webxact.watchfire.com/ 3217 ]; 3218 for(;i<addValidData.length;i++) 3219 if(d=addValidData[i].split(' '),d[1])t+=' <a title="'+d[0]+'" href="'+d[1].replace(/~/g,encodeURI(location.href)) 3220 +'" target="'+tf+'">' 3221 +(d[2]?'<img style="display:inline;width:88px;" alt="'//'" onclick="return openAt(\''+tf+'\');"><img style="display:inline;" alt="' IE不通 3222 +d[0]+'" src="'+d[2]+'"/>':d[0]) 3223 +'<\/a>'; // tf.focus() 3224 else alert('Validate data defined error!'); 3225 v.innerHTML='Validate this document:<br/>'+t; 3226 v.style.display='block'; 3227 return t; 3228 } 3229 3230 3231 /* 延遲執行: 加強版的 setTimeout? 3232 3233 id=delayRun(function[,ms=0]) 3234 3235 id=delayRun([function,[args],this] [,ms=0]) 3236 3237 */ 3238 function delayRun(f,ms){ 3239 var _f=delayRun,i; 3240 if(!_f.fL)_f.fL=[]; 3241 i=_f.fL.length; 3242 _f.fL.push(f); 3243 setTimeout('delayRun.run('+i+');',ms||0); 3244 return i; 3245 } 3246 delayRun.clear=function(i){ 3247 // clearTimeout(): 為求簡單省略 3248 delete this.fL[i]; 3249 }; 3250 delayRun.run=function(i){ 3251 var _t=this,f=_t.fL[i]; 3252 if(f){ 3253 if(typeof f=='function')f(); 3254 else if(f instanceof Array)f[0].apply(f[2]||null,f[1]); 3255 else eval(f); 3256 delete _t.fL[i]; 3257 } 3258 }; 3259 3260 3261 3262 3263 3264 3265 3266 /* MsgBox, InputBox Titlebars Prefixed with 'VBScript' http://support.microsoft.com/default.aspx?scid=kb;en-us;234742 3267 http://asp.programmershelp.co.uk/vbscriptmsgbox.php 3268 http://17.webmasters.com/caspdoc/html/vbscript_msgbox_function.htm 3269 請加入下面一段中介function 3270 <script type="text/vbscript"> 3271 Function VBalert_vbf() 3272 VBalert_f.ret=MsgBox(VBalert_f.prompt,VBalert_f.buttons,VBalert_f.title,VBalert_f.helpfile,VBalert_f.context) 3273 End Function 3274 </script> 3275 3276 or use: 3277 window.execScript( sExpression, sLanguage ); 3278 */ 3279 //var VBalert_f;VBalert(); // init 3280 function VBalert(prompt,buttons,title,helpfile,context){ 3281 if(typeof VBalert_f!='object')VBalert_f={},setObjValue('VBalert_f','ret=0,' 3282 // http://msdn.microsoft.com/library/en-us/script56/html/vsfctmsgbox.asp 3283 +'vbOK=1,vbCancel=2,vbAbort=3,vbRetry=4,vbIgnore=5,vbYes=6,vbNo=7,' 3284 +'vbOKOnly=0,vbOKCancel=1,vbAbortRetryIgnore=2,vbYesNoCancel=3,vbYesNo=4,vbRetryCancel=5,' 3285 +'vbCritical=16,' // Critical Message icon (x) 3286 +'vbQuestion=32,' // Warning Query icon (?) 3287 +'vbExclamation=48,' // Warning Message icon (!) 3288 +'vbInformation=64,' // Information Message icon(i) 3289 +'vbDefaultButton1=0,vbDefaultButton2=256,vbDefaultButton3=512,vbDefaultButton4=768,vbApplicationModal=0,vbSystemModal=4096','int'); 3290 if(typeof prompt=='undefined')return; 3291 VBalert_f.prompt=prompt||'',VBalert_f.buttons=buttons||0,VBalert_f.title=title||''; 3292 // Not available on 16-bit platforms. http://msdn.microsoft.com/library/en-us/script56/html/vsfctmsgbox.asp 3293 VBalert_f.helpfile=helpfile||'',VBalert_f.context=context||0; 3294 try{ 3295 VBScript:VBalert_vbf(); 3296 return VBalert_f.ret; 3297 }catch(e){ 3298 //alert('VBalert error:'+e.message); 3299 alert(VBalert_f.prompt); 3300 } 3301 } 3302 //alert(VBalert('12',VBalert_f.vbInformation+VBalert_f.vbDefaultButton3)); 3303 3304 3305 3306 /* get window status 取得視窗可利用的size。現在還得用種方法,真是羞恥。 2005/1/13 20:0 3307 get_window_status(event object) 3308 http://www.mozilla.org/docs/dom/domref/dom_window_ref.html 3309 http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/body.asp 3310 http://www.howtocreate.co.uk/tutorials/index.php?tut=0&part=16 3311 http://www.webdevtips.com/webdevtips/faq/javascript/index.shtml 3312 http://www.quirksmode.org/viewport/compatibility.html 3313 http://cgi.din.or.jp/~hagi3/JavaScript/JSTips/Mozilla/eventhandle.htm 3314 3315 ** untested !! 3316 3317 */ 3318 3319 //var eventObj; 3320 CeL.interact.DOM 3321 . 3322 /** 3323 * 取得當前 window status 3324 * @param node HTML element or Event object 3325 * @returns {Object} status 3326 */ 3327 get_window_status = function (node) { 3328 var _s = get_window_status, t = _s.scroll, r = { 3329 scrollLeft : t[0], 3330 scrollTop : t[1] 3331 }; 3332 3333 // 能scroll的範圍:不準,yet test The height of the total page (usually the body element) 3334 // t:test, true:all but Explorer Mac, false:Explorer Mac, would also work in Explorer 6 Strict, Mozilla and Safari 3335 var t = typeof document.body.scrollHeight != 'undefined' 3336 && typeof document.body.offsetHeight != 'undefined' 3337 && document.body.scrollHeight > document.body.offsetHeight; 3338 3339 r.scrollW = t ? document.body.scrollWidth 3340 : typeof document.body.offsetWidth != 'undefined' ? document.body.offsetWidth 3341 : null; 3342 r.scrollH = t ? document.body.scrollHeight 3343 : typeof document.body.offsetHeight != 'undefined' ? document.body.offsetHeight 3344 : null; 3345 3346 // window大小 3347 // 2009/3/23 1:15:29 3348 var NewIE = navigator.appVersion.indexOf("MSIE") != -1 3349 && parseInt(navigator.appVersion.split("MSIE")[1]) > 6; 3350 r.windowW = typeof window.innerWidth != 'undefined' ? window.innerWidth 3351 : /* typeof offsetWidth!='undefined'?offsetWidth: */!NewIE 3352 && typeof document.body.clientWidth != 'undefined' ? document.body.clientWidth 3353 : document.documentElement 3354 && !isNaN(document.documentElement.clientWidth) ? document.documentElement.clientWidth 3355 : null;// +offsetLeft 3356 r.windowH = typeof window.innerHeight != 'undefined' ? window.innerHeight 3357 : /* typeof offsetHeight!='undefined'?offsetHeight: */!NewIE 3358 && typeof document.body.clientHeight != 'undefined' ? document.body.clientHeight 3359 : document.documentElement 3360 && !isNaN(document.documentElement.clientHeight) ? document.documentElement.clientHeight 3361 : null;// +offsetTop 3362 3363 var noEmu; 3364 if (!node) 3365 if (typeof window.event === 'object') 3366 node = window.event; 3367 else if (typeof e === 'object') 3368 node = e; 3369 else if (typeof eventObj === 'object') 3370 noEmu = true, node = eventObj; 3371 3372 if (node) { 3373 // Safari: yet test 3374 var isSafari = /Safari/i.test(window.navigator.appName); 3375 3376 // window相對於screen位置:不準, yet test 3377 r.windowX = node.clientX - ((isSafari) ? r.scrollX : 0); 3378 r.windowY = node.clientY - ((isSafari) ? r.scrollY : 0); 3379 // mouse位置 3380 // http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/obj_event.asp 3381 // http://www.mozilla.org/docs/dom/domref/dom_event_ref.html 3382 r.mouseX = node.clientX + ((!isSafari) ? r.scrollX : 0); 3383 r.mouseY = node.clientY + ((!isSafari) ? r.scrollY : 0); 3384 if (!noEmu) 3385 // 模擬event obj,因為event obj不能在event發生時之function執行完後再取得 3386 eventObj = { 3387 'clientX' : node.clientX, 3388 'clientY' : node.clientY 3389 }; 3390 // alert(r.scrollX+','+r.scrollY+'\n'+o.clientX+','+o.clientY); 3391 } 3392 3393 return r; 3394 }; 3395 3396 CeL.interact.DOM 3397 . 3398 // IE7遵照標準,不用 document.body.scrollLeft 而用 document.documentElement.scrollLeft 3399 // http://hkom.blog1.fc2.com/blog-entry-423.html 3400 // http://diaspar.jp/node/47 3401 get_window_status.scroll = function (node) { 3402 var box_model, od = node && node.ownerDocument; 3403 3404 try{ 3405 // from jQuery 3406 var div = document.createElement('div'); 3407 div.style.width = div.style.paddingLeft = '1px'; 3408 3409 document.body.appendChild(div); 3410 _.get_window_status.box_model = box_model = div.offsetWidth === 2; 3411 if(!node) 3412 od = div.ownerDocument; 3413 document.body.removeChild(div).style.display = 'none'; 3414 3415 div = null; 3416 3417 }catch (e) { 3418 // TODO: handle exception 3419 } 3420 3421 // 到這邊,若是 od 未設定,則所有取值與 node 無關。 3422 // 因為大多有 ownerDocument,所以預設編入。 3423 // 新的 browser,od 與 dv 皆應有設定。 3424 3425 /* 3426 3427 Firefox/3.6.6: ownerDocument: [object HTMLDocument], defaultView: [object Window], box_model: true, pageXOffset: 0, body.scrollLeft: 0, documentElement.scrollLeft: 0, scrollX: 0 3428 Chrome/6.0.453.1 Safari/534.2: ownerDocument: [object HTMLDocument], defaultView: [object DOMWindow], box_model: true, pageXOffset: 0, body.scrollLeft: 0, documentElement.scrollLeft: 0, scrollX: 0 3429 Safari/533.16: ownerDocument: [object HTMLDocument], defaultView: [object DOMWindow], box_model: true, pageXOffset: 0, body.scrollLeft: 0, documentElement.scrollLeft: 0, scrollX: 0 3430 Opera/9.80 Presto/2.6.30: ownerDocument: [object HTMLDocument], defaultView: [object Window], box_model: true, pageXOffset: 0, body.scrollLeft: 0, documentElement.scrollLeft: 0, scrollX: 0 3431 3432 3433 MSIE 5.0 @ MSIE 9.0 test: ownerDocument: [object], defaultView: undefined, box_model: false, pageXOffset: undefined, body.scrollLeft: 0, documentElement.scrollLeft: 0, scrollX: undefined 3434 MSIE 7.0 @ MSIE 9.0 test: ownerDocument: [object], defaultView: undefined, box_model: true, pageXOffset: undefined, body.scrollLeft: 0, documentElement.scrollLeft: 0, scrollX: undefined 3435 3436 MSIE 8.0: ownerDocument: [object HTMLDocument], defaultView: undefined, box_model: true, pageXOffset: undefined, body.scrollLeft: 0, documentElement.scrollLeft: 0, scrollX: undefined 3437 MSIE 9.0 test: ownerDocument: [object HTMLDocument], defaultView: [object Window], box_model: true, pageXOffset: 0, body.scrollLeft: 0, documentElement.scrollLeft: 0, scrollX: undefined 3438 3439 */ 3440 // IE5-8: od: true, dv: false 3441 3442 var doc = node && od || window.document, 3443 body = doc.body, dv = doc.defaultView, win = dv || doc.parentWindow; 3444 library_namespace.debug('ownerDocument: ' + od + ', defaultView: ' + dv + ', box_model: ' + box_model + ', pageXOffset: ' + win.pageXOffset + ', body.scrollLeft: ' + body.scrollLeft + ', documentElement.scrollLeft: ' + doc.documentElement.scrollLeft + ', scrollX: ' + win.scrollX, 2, 'get_window_status.scroll'); 3445 3446 // ** 順序有關係! 但在未設置 box_model 前,body.scrollLeft 排在 documentElement.scrollLeft 前面。現在已按照 jQuery 改過。 3447 // TODO: do test 3448 // [scrollLeft, scrollTop, clientLeft, clientTop] 3449 return (_.get_window_status.scroll = 3450 !isNaN(win.pageXOffset) ? 3451 // 預設 box_model === true 3452 function (n) { 3453 // '|| window.document': for Range (see get_selection()) 3454 var d = n && n.ownerDocument || window.document, 3455 w = d.defaultView; 3456 d = d.documentElement; 3457 return [ w.pageXOffset, w.pageYOffset, d.clientLeft, d.clientTop ]; 3458 } : 3459 3460 // IE7(6?)~8 3461 box_model && !isNaN(doc.documentElement.scrollLeft) ? 3462 function (n) { 3463 var d = (n && n.ownerDocument || window.document).documentElement; 3464 return [ d.scrollLeft, d.scrollTop, d.clientLeft, d.clientTop ]; 3465 } : 3466 3467 // IE5(6?) 3468 !isNaN(body.scrollLeft) ? 3469 function (n) { 3470 var b = (n && n.ownerDocument || window.document).body; 3471 return [ b.scrollLeft, b.scrollTop, b.clientLeft, b.clientTop ]; 3472 } : 3473 3474 !isNaN(win.scrollX) ? 3475 // untested 3476 function() { 3477 var b = document.body; 3478 return [ window.scrollX, window.scrollY, b.clientLeft, b.clientTop ]; 3479 } : 3480 3481 function() { 3482 return [ 0, 0, 0, 0 ]; 3483 } 3484 )(node); 3485 3486 }; 3487 3488 3489 3490 3491 3492 CeL.interact.DOM 3493 . 3494 /** 3495 * get current computed style property of specified HTML element. 3496 * TODO: 整合 get_node_offset, _.set_style 3497 * @param element HTML element 3498 * @param name W3C style property name (e.g., no '-webkit-background-clip') 3499 * @return 3500 * @see 3501 * http://en.wikipedia.org/wiki/Internet_Explorer_box_model_bug, http://www.comsharp.com/GetKnowledge/zh-CN/TeamBlogTimothyPage_K983.aspx, 3502 * curCSS @ jQuery, http://api.jquery.com/category/css/, 3503 * <a href="http://www.quirksmode.org/dom/getstyles.html" accessdate="2010/4/1 15:44">JavaScript - Get Styles</a>, 3504 * <a href="http://www.javaeye.com/topic/140784?page=2" accessdate="2010/4/1 15:41">style.display取值不对,难道是浏览器bug?讨论第2页: - JavaScript - web - JavaEye论坛</a> 3505 * 大體上,currentStyle 相當於 getComputedStyle,而 runtimeStyle 相當於 getOverrideStyle。但是它們還是有很重要的區別。那就是,IE的CSS計算步驟其實是不合標準的。 3506 * document.defaultView在mozilla中是指向window obj的,但是很有可能在其他broswer中就不指向window obj...因為w3c中沒有強行規定document.defaultView一定是一個global obj. 3507 * 3508 * 返回頁內樣式表定義的類,那麼可以使用DOM樣式表對象來訪問: 3509 * var oCssRulers = document.styleSheets[0].cssRulers || document.styleSheets[0].rulers; 3510 * (前者是DOM方法,後者是IE私有方法) 3511 * alert(oCssRulers[0].style.display); 3512 * @since 2010/4/2 00:14:09 rewrite 3513 * @memberOf CeL.interact.DOM 3514 */ 3515 get_style = function(element, name, not_computed) { 3516 if (typeof element === 'string') 3517 element = document.getElementById(element); 3518 3519 // opacity 3520 3521 if (!element || !name) 3522 return; 3523 3524 var value, style_interface, e; 3525 name = name.toLowerCase(); 3526 // IE: element.style.styleFloat, firefox, chorme, safari: element.style.cssFloat 3527 //if (name === 'float') name = 'cssFloat' in element.style ? 'cssFloat' : 'styleFloat'; 3528 3529 if (style_interface = document.defaultView) // window.getComputedStyle 3530 try { 3531 if ((value = element.ownerDocument) && (value = value.defaultView)) 3532 style_interface = value; 3533 else 3534 library_namespace.debug('Can not get .ownerDocument.defaultView of ' 3535 + library_namespace.node_description(element) + ' !'); 3536 3537 //if (/[A-Z]/.test(name)) name = name.replace(/([A-Z])/g, '-$1').toLowerCase(); 3538 // width 之類可能 === "auto"!! 3539 value = style_interface.getComputedStyle(element, null) 3540 // [name] 3541 .getPropertyValue(name); 3542 3543 // from curCSS @ jQuery: return a number for opacity 3544 if(name === 'opacity' && value === '') 3545 value = 1; 3546 } catch (e) { 3547 library_namespace.err(e); 3548 } 3549 3550 // IE 5-8 3551 else if (style_interface = element.currentStyle) 3552 // IE: \w+\W\w+ (e.g., margin-bottom), firefox, chorme, safari: \w+-\w+ 3553 // IE8 中 width 之類可能 === "auto"!! 3554 value = style_interface[name === 'float' ? 'styleFloat' : name.replace(/-([a-z])/g, function($0, $1) { return $1.toUpperCase(); })]; 3555 // Dean Edwards(Base2類庫的作者)的hack http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 3556 3557 else if((style_interface = element.style) && (name in style_interface)) 3558 value = style_interface[name]; 3559 3560 // we should directly get it from element itself 3561 //else if (!(value = element['offset' + name.charAt(0).toUpperCase() + name.slice(1).toLowerCase()])) value = ''; 3562 3563 // 處理 px, pt, em, .. 3564 3565 //library_namespace.debug(library_namespace.node_description(element) + '.style[' + name + '] = [' + value + ']' +(style_interface === document.defaultView ? ' (use W3C .getComputedStyle)' : style_interface === element.currentStyle ? ' (use IE .currentStyle)' : '')); 3566 3567 return value; 3568 }; 3569 3570 3571 3572 CeL.interact.DOM 3573 . 3574 /** 3575 * get the actual position [left,top,width,height] of an HTML node object 3576 * @param node HTML node object 3577 * @return 3578 * @memberOf CeL.interact.DOM 3579 * @deprecated use get_style(), jQuery.offset(), jQuery.position() 3580 * @see 3581 * http://en.wikipedia.org/wiki/Internet_Explorer_box_model_bug, http://www.comsharp.com/GetKnowledge/zh-CN/TeamBlogTimothyPage_K983.aspx, 3582 * http://msdn.microsoft.com/library/en-us/dndude/html/dude04032000.asp, 3583 * http://www.mail-archive.com/mochikit@googlegroups.com/msg00584.html, 3584 * http://hartshorne.ca/2006/01/20/javascript_positioning/, 3585 * http://www.jb51.net/article/18340.htm, 3586 * http://blog.csdn.net/wangjj_016/archive/2010/04/09/5467507.aspx 3587 */ 3588 get_node_offset = function(node) { 3589 if (typeof node === 'string') 3590 // 若 node 為 id 3591 node = _.get_element(node); 3592 if(!_.is_element_node(node)) 3593 return {}; 3594 3595 var _s = _.get_node_offset, 3596 offset = 'offsetWidth' in node ? { 3597 width : node.offsetWidth, 3598 height : node.offsetHeight 3599 } : {}; 3600 3601 3602 if(node.getBoundingClientRect){ 3603 3604 // also see: getClientRects() 3605 3606 var s = _.get_window_status.scroll(node), 3607 box = node.getBoundingClientRect(); 3608 3609 offset = { 3610 left : box.left + s[0] - s[2], 3611 top : box.top + s[1] - s[3], 3612 width : box.right - box.left, 3613 height : box.bottom - box.top 3614 }; 3615 3616 } else if (_.is_HTML_element(node)) { 3617 //alert(node.id+':'+node.offsetLeft+','+node.offsetTop+';'+node.offsetWidth+','+node.offsetHeight); 3618 var l = 0, t = 0, p; 3619 // n,countH=window.navigator.userAgent.indexOf("MSIE")>=0,add=1,outsideBLOCK=1, 3620 if(0) 3621 if (typeof node.offsetWidth !== 'undefined') { 3622 var _w = node.offsetWidth, _h = node.offsetHeight 3623 // ,_o=window.getComputedStyle?document.defaultView.getComputedStyle(node,null):null 3624 ; 3625 // http://www.quirksmode.org/dom/getstyles.html 3626 /* 3627 if(_o) // moz未包含margin+border+padding 這些值可能會有'em'等等的出現,不一定都是px! 3628 //alert(_o.getPropertyValue('border-left-width')+','+_o.getPropertyValue('border-right-width')), 3629 _w+=parseInt(_o.getPropertyValue('border-left-width'))+parseInt(_o.getPropertyValue('border-right-width')), 3630 _h+=parseInt(_o.getPropertyValue('border-top-width'))+parseInt(_o.getPropertyValue('border-bottom-width')); 3631 else if(_o=node.currentStyle) // IE 3632 // IE的offset已經包含margin+border+padding的部份??另,這些值可能會有'em'等等的出現,不一定都是px。 3633 _w+=parseInt(_o['borderLeftWidth'])+parseInt(_o['borderRightWidth']), 3634 _h+=parseInt(_o['borderTopWidth'])+parseInt(_o['borderBottomWidt都是px; 3635 */ 3636 r.width = _w, 3637 r.height = _h; 3638 } 3639 3640 // 下面這段依瀏覽器而有不同 (-_-)!! 3641 // position:absolute 3642 //var tt=''; // for debug 3643 // 2006/2/14: 經由 offset 一個個溯源 3644 var _o = node; 3645 while(_o&&!isNaN(_o.offsetLeft)){ // IE在用style:class時會出現誤差。 3646 /* 3647 n=_o.tagName; 3648 //if( !/^T(ABLE|BODY|R)$/.test(n=_o.tagName) && (countH||!/^H\d$/.test(n)) )l+=_o.offsetLeft,t+=_o.offsetTop; 3649 if(n=='DIV')add=outsideBLOCK; 3650 else if(n=='TD' || countH&&/^H\d$/.test(n))add=1; 3651 outsideBLOCK= n=='TABLE'||n=='DIV'; // _o.style.display 3652 tt+=(add?'':'#')+n+(_o.style.display?'('+_o.style.display+')':'')+':'+_o.offsetLeft+','+_o.offsetTop+(outsideBLOCK?', outside BLOCK':'')+'\n'; 3653 if(add)add=0,l+=_o.offsetLeft,t+=_o.offsetTop; 3654 */ 3655 3656 l += _o.offsetLeft || 0, t += _o.offsetTop || 0; 3657 _o = _o.offsetParent;//.parentNode 3658 } 3659 3660 // 有些會用到overflow,影響位置。 2008/5/31 0:10:7 3661 _o = node; 3662 while ((_o = _o.parentNode) && _o.tagName.toLowerCase() != 'body') 3663 l -= _o.scrollLeft || 0, t -= _o.scrollTop || 0; 3664 3665 // need to enable definition of tt above 3666 //alert('l '+l+',t '+t+',w '+r.w+',h '+r.h+(typeof tt=='string'?'\n'+tt:'')); 3667 3668 offset.left = l; 3669 offset.top = t; 3670 } 3671 3672 return offset; 3673 }; 3674 3675 3676 /* 3677 // get the [left,top,width,height] of obj 3678 function get_node_offset2(obj){ 3679 if(typeof obj=='string'){var o=document.getElementById(obj);if(o)obj=o;} // 若loc為id 3680 if(typeof obj=='object'&&typeof obj.offsetLeft!='undefined'){ // 若obj為Document Object 3681 //alert(obj.id+':'+obj.offsetLeft+','+obj.offsetTop+';'+obj.offsetWidth+','+obj.offsetHeight); 3682 var l=obj.offsetLeft,t=obj.offsetTop,n,add,outsideBLOCK,countH=window.navigator.userAgent.indexOf("MSIE")>=0,r=[]; 3683 if(typeof obj.offsetWidth!='undefined')r[2]=r.width=r.w=r.W=obj.offsetWidth,r[3]=r.height=r.h=r.H=obj.offsetHeight; 3684 3685 // 下面這段依瀏覽器而有不同 (-_-)!! 3686 // position:absolute 3687 //var tt=obj.tagName+':'+obj.offsetLeft+','+obj.offsetTop+'\n'; // for debug 3688 while(isNaN((obj=obj.parentNode).offsetLeft)){ // IE在用style:class時會出現誤差。 3689 n=obj.tagName; 3690 //if( !/^T(ABLE|BODY|R)$/.test(n=obj.tagName) && (countH||!/^H\d$/.test(n)) )l+=obj.offsetLeft,t+=obj.offsetTop; 3691 if(n=='DIV')add=outsideBLOCK; 3692 else if(n=='TD' || countH&&/^H\d$/.test(n))add=1; 3693 outsideBLOCK= n=='TABLE'||n=='DIV'; // obj.style.display 3694 //tt+=(add?'':'#')+n+(obj.style.display?'('+obj.style.display+')':'')+':'+obj.offsetLeft+','+obj.offsetTop+(outsideBLOCK?', outside BLOCK':'')+'\n'; 3695 if(add)add=0,l+=obj.offsetLeft,t+=obj.offsetTop; 3696 } 3697 //alert('l'+l+',t'+t+',w'+w+',h'+h+'\n'+tt); // need to enable definition of tt above 3698 r[0]=r.left=r.l=r.L=l,r[1]=r.top=r.t=r.T=t; 3699 return r; 3700 } 3701 } 3702 */ 3703 3704 /* locate a object(obj/div, dialogue box, popup dialog) on where we want followed window location 2005/1/12 19:-13 21:22 3705 此函數會盡量不使obj超出window範圍的大小,除非設定了noResize/noMove或發生錯誤。若moveable+resizable(default),會嘗試先move再resize。 3706 obj: 3707 object or id 3708 loc: 3709 [left,top]/[left,top,width,height]/reference obj or id/0||'mouse':by mouse loc 3710 若left,top設定成%或是0.-,會當作相對於螢幕的比例。 3711 margin: 3712 0/num=[num,num]/[offset x,offset y] 3713 在可能的情況下(不會造成超出window範圍)與loc之間空出的距離(所作的位移)。假如未輸入則自動設定。 3714 flag: locate_elementF.~ !表示未實作 3715 下面幾項為預設模式 3716 auto[Locate] 自動調整位置(default),若設定abs/rel則不會自動調整。 3717 resizable 可調整obj大小(default) <-> noResize 3718 moveable 可移動obj(default) <-> noMove 3719 下面幾項為模式選擇,擇一。 3720 auto[Locate] 自動判定並調整位置(default),若設定abs/rel則不會自動調整。 3721 abs[olute] 這裡的loc為絕對location。假如有提供margin,則會嘗試定位於loc+margin處。 3722 rel[ative] 這裡的loc為相對於window左上角的location。假如有提供margin,則會嘗試定位於loc+margin處。 3723 asDialog,dialog 預設是普通obj,但當設定為此項(dialog)時,loc會被當成reference obj。 3724 作為某obj(loc)之附屬obj(對話框/說明等),會避開主obj(reference obj)之顯示範圍。 3725 假如提供的loc並非obj,則會假設主obj是個從loc開始,長寬為margin的object。 3726 dialogDown,dialogUp,dialogRight,dialogLeft 預設是擺在下面,此flag可改成上面或其他不同方位。 3727 擇一 3728 resizable 可調整obj大小(default) <-> noResize 3729 noResize 不可調整obj大小,若可移動會將整個obj移到能看清的邊界。 3730 擇一 3731 moveable 可移動obj(default) <-> noMove 3732 noMove 不可移動obj,若可調整大小會將整個obj縮到能看清的大小。 3733 下面幾項可任喜好選購(笑) 3734 keepDisplay 是否維持顯示之display mode。沒有時則顯示之。 3735 create 假如不存在此obj就造出來。預設若無法取得此obj則會直接return 3736 3737 ! !假如沒足夠空間則不顯示,或是僅顯示警告。 3738 3739 * 假如在事件中設定'eventObj=event'可掌握mouse event 3740 3741 TODO: 3742 locate_elementClip=[l,t,w,h]: resizable時將obj限制在這個範圍內 3743 3744 to top: 3745 var locate_elementF; 3746 setObjValue('locate_elementF','resizable=0,moveable=0,autoLocate=0,auto=0,absolute=1,abs=1,relative=2,rel=2,asDialog=3,dialog=3,modeFlag=3,dialogDown=3,dialogUp=7,dialogRight=11,dialogLeft=15,dialogFlag=15,dialogForce=16,noResize=32,noMove=64,keepDisplay=128,create=256',1); // revise 3747 */ 3748 //locate_element[generateCode.dLK]='eventObj,locate_elementF,get_window_status,locate_element'; 3749 function locate_element(obj, loc, margin, flag) { 3750 // 前置處理 3751 3752 // setup obj 3753 if (!flag) 3754 flag = locate_elementF.auto; 3755 if (!obj) 3756 return; 3757 if (typeof obj == 'string') { 3758 var id = obj; 3759 if (!(obj = document.getElementById(id)) && (flag & locate_elementF.create)) 3760 document.body.appendChild(obj = document.createElement('div')), 3761 obj.id = id; 3762 } 3763 3764 // 在 dialog 時之預設位移 3765 var dMargin = { 3766 'X' : 2, 3767 'Y' : 2 3768 } 3769 , Display = flag & locate_elementF.keepDisplay ? obj.style.display : 'block', Visibility = flag 3770 & locate_elementF.keepDisplay ? obj.style.visibility : 'visible', win, dialog = (flag & locate_elementF.modeFlag) == locate_elementF.dialog ? flag 3771 & locate_elementF.dialogFlag 3772 : 0, turnPercent = function(p, v) { 3773 if (typeof p == 'string') { 3774 var t = parseFloat(p.match(/([\d.]+)/)); 3775 p = t ? t < 2 ? t * v : t < 200 ? t * v / 100 : t : 0; 3776 } else if ( 3777 // typeof p1='undefined'&& 3778 isNaN(p)) 3779 p = 0; 3780 return p; 3781 }, dealPercent = function(o, t) { 3782 // t: 0:loc, 1:margin 3783 3784 // 是否重新指定 3785 var d = 0; 3786 if (typeof o == 'string') 3787 o = o.split(','), d = 1; 3788 if (!dialog && typeof o == 'object') { 3789 // 取百分比% 3790 if (typeof o[t ? 'L' : 'X'] == 'undefined' 3791 && typeof o[0] != 'undefined') 3792 d = 1, o = t ? { 3793 'X' : o[0], 3794 'Y' : o[1] 3795 } : { 3796 'L' : o[0], 3797 'T' : o[1], 3798 // 假如o[2]未定義,W也會未定義(但有index) 3799 'W' : o[2], 3800 'H' : o[3] 3801 }; 3802 if (t) 3803 o.X = turnPercent(o.X, win.windowW), o.Y = turnPercent(o.Y, 3804 win.windowH); 3805 else { 3806 o.L = turnPercent(o.L, win.windowW), o.T = turnPercent(o.T, 3807 win.windowH); 3808 if (typeof o.W == 'undefined') { 3809 delete o.W; 3810 delete o.H; 3811 } else 3812 o.W = turnPercent(o.W, win.windowW), o.H = turnPercent(o.H, 3813 win.windowH); 3814 } 3815 } 3816 if (d) 3817 if (t) 3818 margin = o; 3819 else 3820 loc = o; 3821 }, makeFit = function(l, t, r, b, hc) { 3822 // test if out of range & 將box調整在range[left,top,right,bottom]內:先move,再resize 3823 if (boxL < l) 3824 boxL = l; 3825 if (boxT < t) 3826 boxT = t; 3827 var d = r - obj.offsetWidth; 3828 if (boxL > d) 3829 if (l > d) 3830 boxW = r - (boxL = l); 3831 else 3832 boxL = d; 3833 d = b - obj.offsetHeight; 3834 if (boxT > d) 3835 if (t > d) 3836 boxH = b - (boxT = t); 3837 else 3838 boxT = d; 3839 else if (hc && (boxT = hc - obj.offsetHeight / 2) < t) 3840 boxT = t; 3841 }; 3842 3843 with (obj.style) { 3844 overflow = visibility = 'hidden'; 3845 if (width) 3846 width = ''; 3847 if (height) 3848 // 重設obj。 3849 height = ''; 3850 // 得設定obj之display,因為不這樣不能定offset。但可不顯現出來…只是好像沒啥效果。 3851 display = 'block'; 3852 } 3853 3854 // if(dialog!=locate_elementF.dialogDown&&dialog!=locate_elementF.dialogUp)dialog=0; 3855 // setup loc#1: deal dialog 3856 if (typeof loc == 'string') { 3857 // 若loc為id 3858 var o = document.getElementById(loc); 3859 if (o) 3860 loc = o; 3861 } 3862 if (typeof loc == 'object' && typeof loc.offsetLeft != 'undefined') { 3863 // 若loc為Document Object 3864 3865 /* 3866 //alert(loc.id+':'+loc.offsetLeft+','+loc.offsetTop+';'+loc.offsetWidth+','+loc.offsetHeight); 3867 var l=loc.offsetLeft,t=loc.offsetTop,w,h,n,add,outsideBLOCK,countH=window.navigator.userAgent.indexOf("MSIE")>=0; // 真妙..moz表示在<H\d>中的obj時不把H\d當作parent算進去 3868 if(typeof loc.offsetWidth!='undefined')w=loc.offsetWidth,h=loc.offsetHeight; // loc.offsetWidth可能未定義? 3869 //var tt=loc.tagName+':'+loc.offsetLeft+','+loc.offsetTop+'\n'; // for debug 3870 // 下面這段依瀏覽器而有不同 (-_-)!! 3871 while(isNaN((loc=loc.parentNode).offsetLeft)){ // IE在用style:class時會出現誤差。 3872 n=loc.tagName; 3873 //if( !/^T(ABLE|BODY|R)$/.test(n=loc.tagName) && (countH||!/^H\d$/.test(n)) )l+=loc.offsetLeft,t+=loc.offsetTop; 3874 if(n=='DIV')add=outsideBLOCK; 3875 else if(n=='TD' || countH&&/^H\d$/.test(n))add=1; 3876 outsideBLOCK= n=='TABLE'||n=='DIV'; // loc.style.display 3877 //tt+=(add?'':'#')+n+(loc.style.display?'('+loc.style.display+')':'')+':'+loc.offsetLeft+','+loc.offsetTop+(outsideBLOCK?', outside BLOCK':'')+'\n'; 3878 if(add)add=0,l+=loc.offsetLeft,t+=loc.offsetTop; 3879 } 3880 //alert(l+','+t+'\n'+tt); // need to enable definition of tt above 3881 loc={'L':l,'T':t,'W':w,'H':h}; 3882 */ 3883 loc = get_node_offset(loc); 3884 if ((flag & locate_elementF.modeFlag) == locate_elementF.auto) 3885 flag += locate_elementF.dialog - locate_elementF.auto, dialog = locate_elementF.dialog; 3886 } 3887 3888 // setup margin 3889 win = get_window_status(); 3890 if (!margin) 3891 margin = 3892 // dialog?dMargin:{'X':0,'Y':0}; 3893 dMargin; 3894 else 3895 dealPercent(margin, 1); 3896 3897 // setup loc#2: deal abs/rel 3898 if (!loc || loc == 'mouse') 3899 loc = { 3900 L : win.mouseX || 0, 3901 T : win.mouseY || 0 3902 }; 3903 else { 3904 if ((flag & locate_elementF.modeFlag) == locate_elementF.auto && typeof loc == 'string' 3905 && /[%.]/.test(loc)) 3906 flag += locate_elementF.rel - locate_elementF.auto; 3907 dealPercent(loc); 3908 } 3909 // alert(loc.L+','+loc.T+';'+margin.X+','+margin.Y); 3910 if ((flag & locate_elementF.modeFlag) == locate_elementF.auto) 3911 // 到這裡還沒決定就很奇怪了 3912 flag += locate_elementF[loc.W && loc.H && loc.T < win.windowH 3913 && loc.L < win.windowW ? (dialog = locate_elementF.dialog) && 'dialog' 3914 : 'abs'] 3915 - locate_elementF.auto; 3916 3917 // 調整與判別 3918 // alert(loc.L+','+loc.T+';'+margin.X+','+margin.Y); 3919 // alert(loc.L+margin.X+','+(loc.T+margin.Y)); 3920 // alert('dialog:'+dialog); 3921 3922 if ((flag & locate_elementF.modeFlag) == locate_elementF.rel) 3923 // 改成絕對座標。此後僅存abs/dialog 3924 flag += locate_elementF.abs - locate_elementF.rel// -(flag&locate_elementF.modeFlag) 3925 , loc.L += win.scrollX, loc.T += win.scrollY; 3926 3927 // 最後要設定的值 3928 var resizable = !(flag & locate_elementF.noResize), boxL = loc.L, boxT = loc.T, boxW = -1, boxH = -1; 3929 if (flag & locate_elementF.noMove) 3930 if (resizable) 3931 makeFit((boxL += margin.X) - margin.X, (boxT += margin.Y) 3932 - margin.Y, win.scrollX + win.windowW, win.scrollY 3933 + win.windowH); 3934 else { 3935 if (margin.X < 0 3936 || boxL + margin.X >= win.scrollX 3937 && boxL + margin.X + obj.offsetWidth < win.scrollX 3938 + win.windowW) 3939 boxL += margin.X; 3940 if (margin.Y < 0 3941 || boxT + margin.Y >= win.scrollY 3942 && boxT + margin.Y + obj.offsetHeight < win.scrollY 3943 + win.windowH) 3944 boxT += margin.Y; 3945 } 3946 else if (!dialog) 3947 // abs 3948 boxL += margin.X, boxT += margin.Y, makeFit(win.scrollX, win.scrollY, 3949 win.scrollX + win.windowW, win.scrollY + win.windowH); 3950 else { 3951 // 自動調整位置 3952 if (dialog) { 3953 if (!loc.W) 3954 loc.W = 0; 3955 if (!loc.H) 3956 loc.H = 0; 3957 } else 3958 // abs時,相當於dialog在(0,0)大小(0,0) 3959 loc = { 3960 'L' : win.scrollX, 3961 'T' : win.scrollY, 3962 'W' : 0, 3963 'H' : 0 3964 }; 3965 if (!obj.innerHTML) 3966 // 起碼先設定個大小以安排位置 3967 obj.innerHTML = ' '; 3968 3969 var lA = win.scrollY + win.windowH - loc.T - loc.H, lB = loc.T 3970 - win.scrollY, lC = win.scrollX + win.windowW - loc.L - loc.W, lD = loc.L 3971 - win.scrollX, 3972 // args for makeFit() 3973 m1 = win.scrollX, m2 = win.scrollY, 3974 m3 = win.scrollX + win.windowW, m4 = win.scrollY + win.windowH 3975 // move kind set use locate_elementF.dialog~ flag 3976 , movekind; 3977 // alert(lA+','+lB+','+lC+','+lD+'\n'+obj.offsetWidth+','+obj.offsetHeight); 3978 3979 /* 3980 +---------------------+ 3981 | ^ | 3982 | | lB | <--screen (active frame) 3983 | | | 3984 |<---->#####<-------->| ###:reference obj 3985 | lD | lC | 3986 | | | 3987 | | lA | 3988 | | | 3989 +---------------------+ 3990 */ 3991 // 決定 mode 3992 if (dialog && (flag & locate_elementF.dialogForce)) 3993 movekind = dialog; 3994 else { 3995 if (obj.offsetWidth < win.windowW 3996 && (dialog != locate_elementF.dialogRight 3997 && dialog != locate_elementF.dialogLeft || obj.offsetHeight >= win.windowH)) 3998 if (obj.offsetHeight < lA 3999 && (dialog != locate_elementF.dialogUp || obj.offsetHeight >= lB)) 4000 movekind = locate_elementF.dialogDown; 4001 else if (obj.offsetHeight < lB) 4002 movekind = locate_elementF.dialogUp; 4003 if (!movekind && obj.offsetHeight < win.windowH) 4004 if (obj.offsetWidth < lC 4005 && (dialog != locate_elementF.dialogLeft || obj.offsetWidth >= lD)) 4006 movekind = locate_elementF.dialogRight; 4007 else if (obj.offsetWidth < lD) 4008 movekind = locate_elementF.dialogLeft; 4009 if (!movekind) 4010 movekind = 4011 // 以較大、可視的為準 4012 dialog != locate_elementF.dialogRight && dialog != locate_elementF.dialogLeft ? 4013 // 沒考慮假如lA<5時.. 4014 lA < lB && resizable ? locate_elementF.dialogUp : locate_elementF.dialogDown : 4015 // 4016 lC < lD && resizable ? locate_elementF.dialogLeft : locate_elementF.dialogRight; 4017 } 4018 4019 // alert(movekind); 4020 // 決定location 4021 if (movekind == locate_elementF.dialogDown) 4022 m2 = loc.T + loc.H, boxT += loc.H; 4023 else if (movekind == locate_elementF.dialogUp) 4024 m4 = loc.T, boxT -= obj.offsetHeight, margin.Y = -margin.Y; 4025 else if (movekind == locate_elementF.dialogRight) 4026 m1 = loc.L + loc.W, boxL += loc.W; 4027 else 4028 m3 = loc.L, boxL -= obj.offsetWidth, margin.X = -margin.X; 4029 //else if(movekind==locate_elementF.dialogLeft) 4030 4031 // 加上偏移 4032 boxL += margin.X, boxT += margin.Y; 4033 if (!resizable) { 4034 if (boxL < m1 && margin.X < 0 || boxL + obj.offsetWidth > m3 4035 && margin.X > 0) 4036 boxL -= margin.X; 4037 if (boxT < m2 && margin.Y < 0 || boxT + obj.offsetHeight > m4 4038 && margin.Y > 0) 4039 boxT -= margin.Y; 4040 // 確保不會撞到 4041 m3 += obj.offsetWidth, m4 += obj.offsetHeight; 4042 } 4043 // 奇怪的是,alert(obj.offsetWidth)後obj.offsetWidth就變成0了。可能因為這值需要出函數之後再改。 4044 // alert(resizable+'\n'+m1+','+m2+','+m3+','+m4+','+movekind+'\n'+obj.offsetWidth+','+obj.offsetHeight); 4045 makeFit(m1, m2, m3, m4, movekind == locate_elementF.dialogRight 4046 || movekind == locate_elementF.dialogLeft ? loc.T : 0); 4047 } 4048 4049 // 設定位置 4050 // alert(boxL+','+boxT+','+boxW+','+boxH+','+Display); 4051 with (obj.style) { 4052 position = 'absolute'; 4053 left = boxL + 'px'; 4054 top = boxT + 'px'; 4055 if (boxW >= 0 || boxH >= 0) { 4056 overflow = 'auto'; 4057 //alert(width+','+height+'\n'+typeof width+'\n->w,h:'+boxW+','+boxH); 4058 if (boxW >= 0) 4059 width = boxW + 'px'; 4060 if (boxH >= 0) 4061 height = boxH + 'px'; 4062 } 4063 display = Display; 4064 visibility = Visibility; 4065 } 4066 4067 // alert(obj.style.width+','+obj.style.height+'\n'+obj.offsetWidth+','+obj.offsetHeight); 4068 return obj; 4069 }; 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 // 2007/4/25-27 0:48:22 RFC 3492 IDNA Punycode 未最佳化 4080 // http://stackoverflow.com/questions/183485/can-anyone-recommend-a-good-free-javascript-for-punycode-to-unicode-conversion 4081 // http://xn-punycode.com/ 4082 function Punycode(){} 4083 4084 Punycode.map='abcdefghijklmnopqrstuvwxyz0123456789', 4085 Punycode.Dmap=0, 4086 Punycode.base=36,//Punycode.map.length 4087 Punycode.tmin=1, 4088 Punycode.tmax=26, 4089 Punycode.skew=38, 4090 Punycode.damp=700, 4091 Punycode.initial_bias=72,//偏移 4092 Punycode.initial_n=0x80,//128 4093 Punycode.prefix="xn--",//the default ACE prefix 4094 Punycode.delimiter='-'; 4095 Punycode._b=Punycode.base-Punycode.tmin, 4096 //Punycode._t=(Punycode._b*Punycode.tmax)>>1, 4097 Punycode._t=Math.floor(Punycode._b*Punycode.tmax/2); 4098 4099 // IDNA ToASCII 4100 Punycode.encodeDomain=function(UURL){ 4101 var m=UURL.match(/^([\w\d\-]+:\/\/)?([^\/]+)/),UDomain=m?m[2]:'',i=(m=UDomain)?UURL.indexOf(m):0; 4102 //document.write('<hr/>Punycode.encodeDomain UDomain: ['+i+']['+m+']<br/>'); 4103 if(m&&m.replace(/[\x01-\x7f]+/g,''))with(Punycode) 4104 m=m.replace(/([^.]+)\./g,function($0,$1){ 4105 //document.write($1+'→'+encode($1)+'<br/>'); 4106 return prefix+encode($1)+'.'; 4107 }),UURL=encodeURI(UURL.slice(0,i)+m+UURL.slice(i+UDomain.length)); 4108 return UURL; 4109 }; 4110 4111 // IDNA ToUnicode 4112 Punycode.decodeDomain=function(PURL){with(Punycode){ 4113 var m=PURL.match(/^([\w\d\-]+:\/\/)?([^\/]+)/),PDomain=m?m[2]:'',i=(m=PDomain)?PURL.indexOf(m):0; 4114 //document.write('<hr/>Punycode.decodeDomain PDomain: ['+i+']['+m+']<br/>'); 4115 if(m){ 4116 m=m.replace(new RegExp(prefix+'([^.]+)\\.','g'),function($0,$1){ 4117 //document.write($1+'→'+decode($1)+'<br/>'); 4118 return decode($1)+'.'; 4119 }); 4120 if(m!=PDomain){ 4121 PURL=PURL.slice(0,i)+m+PURL.slice(i+PDomain.length); 4122 try{PURL=decodeURI(PURL);}catch(e){PURL=unescape(PURL);} 4123 } 4124 } 4125 return PURL; 4126 }}; 4127 4128 4129 Punycode.adapt=function(delta,numpoints,firsttime){with(Punycode){ 4130 //document.write('*adapt: '+delta+', '+numpoints+', '+firsttime+', _b='+_b+', _t='+_t+'<br/>'); 4131 delta=firsttime?Math.floor(delta/damp):delta>>1;//Math.floor(delta/(firsttime?damp:2)); 4132 delta+=Math.floor(delta/numpoints); 4133 var k=0; 4134 for(;delta>_t;k+=base)delta=Math.floor(delta/_b); 4135 return k+Math.floor((_b+1)*delta/(delta+skew)); 4136 }}; 4137 4138 Punycode.encode=function(UString){with(Punycode){ 4139 var n=initial_n,cA=[],m,mA=[],i=0,c 4140 ,q,delta=0,bias=initial_bias,output=UString.replace(/[^\x01-\x7f]+/g,''),h=output.length,b=h; 4141 //document.write('<hr/>Punycode.encode begin: ['+output+']<br/>'); 4142 if(b)output+=delimiter; 4143 4144 for(;i<UString.length;i++){ 4145 cA.push(c=UString.charCodeAt(i)); 4146 if(c>n)mA.push(c); 4147 } 4148 mA.sort(function(a,b){return b-a;}); 4149 4150 while(h<cA.length){ 4151 do{c=mA.pop();}while(m==c); // 預防重複 4152 m=c; 4153 //if(m-n>(Number.MAX_VALUE-delta)/(h+1)){alert('Punycode: overflow');return;} 4154 delta+=(m-n)*(h+1);// should test overflow 4155 n=m; 4156 for(i=0;i<cA.length;i++){ 4157 if(c=cA[i],c<n)++delta;//if(c=cA[i],c<n&&!++delta){alert('Punycode: overflow');return;}// fail on overflow 4158 //document.write('<b>'+UString.charAt(i)+' '+(c.toString(16)+','+n.toString(16)).toUpperCase()+'</b><br/>'); 4159 if(c==n){ 4160 for(q=delta,k=base;;k+=base){ 4161 t=k<=bias/* +tmin not needed */?tmin:k>=bias+tmax?tmax:k-bias; 4162 if(q<t)break; 4163 output+=map.charAt(t+(q-t)%(base-t)); 4164 //document.write('<b>'+output+'</b><br/>'); 4165 q=Math.floor((q-t)/(base-t)); 4166 } 4167 output+=map.charAt(q); 4168 bias=adapt(delta,h+1,h==b); 4169 //document.write('h='+h+'/'+cA.length+', bias='+bias+', '+output+'<br/>'); 4170 delta=0,h++; 4171 } 4172 } 4173 delta++,n++; 4174 } 4175 //document.write(UString+'→'+output+'<br/>'); 4176 return output; 4177 }}; 4178 4179 Punycode.decode=function(PCode){with(Punycode){ 4180 var n=initial_n,i=0,p=PCode.lastIndexOf(delimiter),bias=initial_bias,output=p==-1?'':PCode.slice(0,p) 4181 ,oldi,w,digit,l; 4182 //document.write('<hr/>Punycode.decode begin: ['+output+']<br/>'); 4183 if(!Dmap)for(w=0,Dmap={};w<map.length;w++)Dmap[map.charAt(w)]=w;//,document.write('Dmap['+map.charAt(w)+']='+w+'<br/>'); 4184 while(p<PCode.length-1){ 4185 for(oldi=i,w=1,k=base;;k+=base){ 4186 if(++p>=PCode.length){alert('Punycode: invalid input: out of range');return PCode;} 4187 //document.write('PCode.charAt('+p+')'+' = '+PCode.charAt(p)+' → '+Dmap[PCode.charAt(p)]+'<br/>'); 4188 if(isNaN(digit=Dmap[PCode.charAt(p)])){alert('Punycode: invalid input');return PCode;} 4189 //if(digit>(Number.MAX_VALUE-i)/w){alert('Punycode: overflow');return;} 4190 i+=digit*w; 4191 t=k<=bias/* +tmin not needed */?tmin:k>=bias+tmax?tmax:k-bias; 4192 //document.write('i='+i+', t='+t+', digit='+digit+', k='+k+'<br/>'); 4193 if(digit<t)break; 4194 //if(w>Number.MAX_VALUE/(base-t)){alert('Punycode: overflow');return;} 4195 w*=base-t; 4196 } 4197 bias=adapt(i-oldi,l=output.length+1,oldi==0); 4198 //document.write('bias='+bias+', n='+n+', i='+i+', l='+l+'<br/>'); 4199 //if(i/l>Number.MAX_VALUE-n){alert('Punycode: overflow');return;} 4200 n+=Math.floor(i/l); 4201 i%=l; 4202 //document.write('['+output.length+']'+output+'+'+n+'(0x'+n.toString(16).toUpperCase()+')@'+i+'→'); 4203 output=output.slice(0,i)+String.fromCharCode(n)+output.slice(i); 4204 //document.write('['+output.length+']'+output+'<br/>'); 4205 i++; 4206 } 4207 //document.write(PCode+'→'+output+'<br/>'); 4208 return output; 4209 }}; 4210 4211 4212 /* 4213 var testC='Hello-Another-Way--fc4qua05auwb3674vfr0b',rC; 4214 document.write('<hr/>'+ 4215 //Punycode.encodeDomain('http://國際.計畫.org/國際.計畫.htm') 4216 Punycode.decodeDomain('http://xn--9cs229l.xn--gpyr35b.org/%E5%9C%8B%E9%9A%9B.%E8%A8%88%E7%95%AB.htm') 4217 //Punycode.encode('463578') 4218 //Punycode.decode('ihqwcrb4cv8a8dqg056pqjye')+'<hr/>'+Punycode.encode('他们为什么不说中文') 4219 //Punycode.decode('ihqwctvzc91f659drss3x8bo0yb')+'<hr/>'+Punycode.encode('他們爲什麽不說中文') 4220 //(rC=Punycode.decode(testC))+'<hr/>'+(rC=Punycode.encode(rC))+'<hr/>'+(testC==rC?'OK':'<b style="color:red">FAILED</b>:<br/>'+testC+'<br/>'+rC) 4221 ); 4222 */ 4223 4224 4225 4226 /* 一個非常不好的 deal onload 方法。只在onload不具有arguments時有用,應該亦可用setTimeout('~',0) 4227 where 0:back,1:front 4228 4229 for IE: 4230 <!--[if IE]><script defer type="text/javascript"> 4231 // onload code 4232 </script><![endif]--> 4233 4234 c.f. http://www.brothercake.com/ http://simonwillison.net/2004/May/26/addLoadEvent/ 4235 GO1.1 Generic onload by Brothercake 4236 window.addEventListener,document.addEventListener,typeof window.attachEvent 4237 c.f. setTimeout('~',0); 不過這不能確定已經load好 4238 */ 4239 /* 4240 function addonload(s,where){ 4241 if(!s||typeof window!='object')return 1; 4242 if(typeof s=='function'){ 4243 s=parseFunction(s); 4244 if(!s||!s.funcName)return 2; 4245 s=s.funcName+'()'; 4246 } 4247 var o=window.onload?typeof window.onload=='string'?window.onload:parseFunction(window.onload).contents:''; 4248 window.onload=new Function(where?s+';\n'+o:o+';\n'+s); 4249 } 4250 */ 4251 4252 4253 CeL.interact.DOM 4254 . 4255 DOM_loaded = function () { 4256 if (document.body) 4257 return _.DOM_loaded = function () { return true; }; 4258 else 4259 return false; 4260 }; 4261 4262 4263 /* 4264 // The DOM ready check for Internet Explorer 4265 try{document.documentElement.doScroll('left');} 4266 catch(e){setTimeout(arguments.callee, 50);return;} 4267 4268 */ 4269 CeL.interact.DOM 4270 . 4271 /** 4272 * 比較好點的 add onload。 4273 * 比起 add_listener(),本函數在已經 load 時依然會執行,而 add_listener 因為是用榜定的方法,因此 load 完就不再觸發(?)。 4274 * 這東西頂多只能擺在 include 的 JS file 中,不能 runtime include。 4275 * @example 4276 * CeL.use('net.web'); 4277 * CeL.on_load(function(){sl(1);},'sl(2);'); 4278 * @requires _.add_listener,_.DOM_loaded 4279 * @see 4280 * jQuery: $(document).ready(listener); 4281 * DOMContentLoaded http://webdesign.piipo.com/jquery/jquery_events 4282 * 可直接參考 SWFObject。 4283 * TODO: 4284 * <a href="http://javascript.nwbox.com/IEContentLoaded/" accessdate="2010/6/3 11:15" title="IEContentLoaded - An alternative for DOMContentLoaded on Internet Explorer">IEContentLoaded</a> 4285 * DOMContentLoaded是firefox下特有的Event, 當所有DOM解析完以後會觸發這個事件。 4286 * DOMContentLoaded與DOM中的onLoad事件與其相近。但onload要等到所有頁面元素加載完成才會觸發, 包括頁面上的圖片等等。 4287 * <a href="http://blog.darkthread.net/blogs/darkthreadtw/archive/2009/06/05/jquery-ready-vs-load.aspx" accessdate="2010/6/3 11:17">jQuery ready vs load - 黑暗執行緒</a> 4288 * $(document).ready(fn)發生在"網頁本身的HTML"載入後就觸發,而$(window).load(fn)則會等到"網頁HTML 標籤中引用的圖檔、內嵌物件(如Flash)、IFrame"等拉哩拉雜的東西都載入後才會觸發。 4289 * @memberOf CeL.interact.DOM 4290 */ 4291 on_load = function on_load() { 4292 var _s = _.on_load, loaded=_.DOM_loaded(),i = 0, a = arguments, l = a.length; 4293 for (; i < l; i++) 4294 if(loaded) 4295 a[i].call(document); 4296 else 4297 _.add_listener('load', a[i], document); 4298 }; 4299 4300 4301 CeL.interact.DOM 4302 . 4303 /** 4304 * bind/add listener. register event control, setup code to run. 4305 * listener 應該加上 try{}catch{},否則會搞不清楚哪裡出問題。 4306 * ** 對同樣的 object,事件本身還是會依照 call add_listener() 的順序跑,不會因為 p_first 而改變。 4307 * ** NOT TESTED!! 4308 * TODO: 4309 * removeEventListener, 4310 * remove_listener(), 4311 * default 'this' 4312 * 自訂 event 4313 * 4314 * @param {string} type listen to what event type. event name/action 4315 * @param listener listener function/function array/function string, 4316 * 須 String 之 recursive function 時可 "(function(){return function f(){f();};})()" 4317 * function(e){var target=e?e.target:(e=window.event).srcElement;if(e.stopPropagation)e.stopPropagation();else e.cancelBubble=true;if(e.preventDefault)e.preventDefault();else e.returnValue=false;return false;} 4318 * @param [target_element] bind/attach to what HTML element 4319 * @param [p_first] parentNode first 4320 * @return 4321 * @since 2010/1/20 23:42:51 4322 * @see 4323 * c.f., GEvent.add_listener() 4324 * @memberOf CeL.interact.DOM 4325 */ 4326 add_listener = function add_listener(type, listener, target_element, p_first) { 4327 if (!type || !listener) 4328 return; 4329 4330 if (typeof listener === 'string') 4331 listener = new Function('e', listener); 4332 4333 if (typeof target_element === 'string') 4334 target_element = _.get_element(target_element); 4335 4336 var _s = _.add_listener, i, adder; 4337 4338 if(typeof p_first !== 'bool') 4339 p_first = typeof p_first === 'undefined' ? _s.p_first : !!p_first; 4340 4341 // 進階功能 4342 if (library_namespace.is_Object(type)) 4343 // usage: add_listener({unload:Unload}); 4344 // usage: add_listener({load:{true:[function(){sl(1);},'sl(2);']}}); 4345 for (i in type) 4346 _s(i, type[i], target_element, p_first);// ,sl(i+': '+type[i]) 4347 4348 // Array or Object 4349 else if (library_namespace.is_Object(listener)) 4350 // usage: add_listener('unload',{true:Unload1}); 4351 // usage: add_listener('unload',[Unload1,Unload2]); 4352 // 因為 Array 會從最小的開始照順序出,所以這邊不再判別是否為 Array。 4353 for (i in listener) 4354 // if(isNaN(f))sl('add_listener: to '+i),_s.p_first=i==='true';//||i==1||i===true 4355 _s(type, listener[i], target_element, 4356 i === 'true' || (i === 'false' ? false : undefined));// ,sl((typeof i)+' ['+i+'] '+_s.p_first) 4357 4358 else if(library_namespace.is_Function(listener)){ 4359 /* 4360 * 先設定好 native listener adding function 4361 */ 4362 if (target_element) 4363 adder = target_element.addEventListener; 4364 else if (!(adder = _s.global_adder) && adder !== null) 4365 _s.global_adder = adder = _s.get_adder(); 4366 4367 //$(document).ready(listener); 4368 4369 // 使 listener 能以 this 取得 target_element 4370 i = function(e) { 4371 if(!e) 4372 e = window.event; 4373 4374 // 正規化 Document Object Model (DOM) Level 3 Events 4375 // http://www.w3.org/TR/2009/WD-DOM-Level-3-Events-20090908/#interface-Event 4376 if(!e.currentTarget) 4377 e.currentTarget = target_element; 4378 if(!e.target) 4379 e.target = e.srcElement || target_element; 4380 4381 // from fix in jQuery 4382 4383 // check if target is a textnode (safari) 4384 if ( e.target.nodeType === 3 ) 4385 e.target = e.target.parentNode; 4386 4387 // Add relatedTarget, if necessary 4388 if ( !e.relatedTarget && e.fromElement ) 4389 e.relatedTarget = e.fromElement === e.target ? e.toElement : e.fromElement; 4390 4391 // 取得滑鼠座標 4392 // http://hartshorne.ca/2006/01/23/javascript_cursor_position/ 4393 // http://hartshorne.ca/2006/01/18/javascript_events/ 4394 if ( isNaN(e.pageX) && !isNaN(e.clientX) ) { 4395 var s = _.get_window_status.scroll(); 4396 e.pageX = e.clientX + s[0] - s[2]; 4397 e.pageY = e.clientY + s[1] - s[3]; 4398 } 4399 4400 listener.call(target_element, e); 4401 }; 4402 4403 // 主要核心動作設定之處理 4404 // TODO: 在 onload 時使 target_element = null 4405 // sl(type+' ('+((typeof p_first=='undefined'?_s.p_first:p_first?true:false)?'p_first':'run first')+'): '+listener); 4406 if(adder){ 4407 try{ 4408 // 直接用 target_element.addEventListener 不會有問題。 4409 // .call(window.document): for Chrome 'Illegal invocation' issue 4410 // http://stackoverflow.com/questions/1007340/javascript-function-aliasing-doesnt-seem-to-work 4411 // 但 IE9 需要 .call(target_element) 或者別用 .call,否則會得到 "Invalid procedure call or argument" 4412 adder.call(target_element, type, i, p_first); 4413 }catch(e){ 4414 adder.call(window.document, type, i, p_first); 4415 } 4416 return; 4417 } 4418 4419 return target_element && (adder = target_element.attachEvent) ? 4420 // http://msdn.microsoft.com/en-us/library/ms536343(VS.85).aspx 4421 adder('on' + type, i) 4422 4423 : _s.default_adder(type, i, p_first, target_element) 4424 ; 4425 } 4426 4427 }; 4428 4429 CeL.interact.DOM 4430 . 4431 /** 4432 * useCapture: parentNode first 4433 * @see 4434 * <a href="http://www.w3.org/TR/DOM-Level-3-Events/#event-flow" accessdate="2010/4/16 22:40">Document Object Model (DOM) Level 3 Events Specification</a>, 4435 * <a href="http://www.w3.org/TR/DOM-Level-3-Events/#interface-EventTarget" accessdate="2010/4/16 22:42">Interface EventTarget</a> 4436 */ 4437 add_listener.p_first = false; 4438 4439 CeL.interact.DOM 4440 . 4441 /** 4442 * get (native) global listener adding function. 4443 * TODO: 只設定一次 4444 * historical for Netscape Navigator, mozilla: window.captureEvents, document.captureEvents 4445 */ 4446 add_listener.get_adder = function() { 4447 /** 4448 * moz (gecko), safari 1.2, ow5b6.1, konqueror, W3C standard: window.addEventListener 4449 * @ignore 4450 * @see 4451 * <a href="https://developer.mozilla.org/en/DOM/element.addEventListener" accessdate="2010/4/16 22:35">element.addEventListener - MDC</a> 4452 * <a href="http://simonwillison.net/2004/May/26/addLoadEvent/" accessdate="2010/4/16 22:36">Executing JavaScript on page load</a> 4453 */ 4454 return window.addEventListener || 4455 /* 4456 * opera 7.50, ie5.0w, ie5.5w, ie6w: window.attachEvent 4457 * opera 7.50: document.attachEvent 4458 */ 4459 window.attachEvent ? function(t, l) { 4460 window.attachEvent('on' + t, l); 4461 } : 4462 /* 4463 * MSN/OSX, opera 7.50, safari 1.2, ow5b6.1: document.addEventListener 4464 */ 4465 document.addEventListener || 4466 /* 4467 * ie5m, MSN/OSX, ie5.0w, ie5.5w ie6w: document.onreadystatechange 4468 */ 4469 null; 4470 4471 }; 4472 4473 CeL.interact.DOM 4474 . 4475 /** 4476 * 含括其他情況。 4477 * all: window.onload. 4478 * TODO: use queue 4479 * @param type listen to what event type 4480 * @param listener listener function/function array 4481 * @param [p_first] parentNode first 4482 * @param [target_element] bind/attach to what HTML element 4483 * @return 4484 * @see 4485 * http://blog.othree.net/log/2007/02/06/third-argument-of-addeventlistener/ 4486 */ 4487 add_listener.default_adder = function(type, listener, p_first, target_element) { 4488 if(!target_element) 4489 target_element = window; 4490 4491 var old = target_element[type = 'on' + type]; 4492 4493 return target_element[type] = 4494 old ? 4495 // TODO: typeof old==='string' 4496 p_first ? function(e) { 4497 old.call(target_element, e || window.event); 4498 listener.call(target_element, e || window.event); 4499 } : function(e) { 4500 listener.call(target_element, e || window.event); 4501 old.call(target_element, e || window.event); 4502 } 4503 : 4504 listener 4505 ; 4506 }; 4507 4508 CeL.interact.DOM 4509 . 4510 /** 4511 * TODO: 4512 * listener list. 4513 * 當無法執行 DOM 操作時(尚未載入、版本太舊不提供支援等)以此為主。 4514 * add_listener.list[node][event type]=[listener list] 4515 */ 4516 add_listener.list = {}; 4517 4518 CeL.interact.DOM 4519 . 4520 /** 4521 * TODO: 4522 * 觸發函數. 4523 * 當無法執行 DOM 操作時(尚未載入、版本太舊不提供支援等)以此為主。 4524 * add_listener.list[type]=[listener list] 4525 */ 4526 add_listener.list = {}; 4527 4528 4529 4530 CeL.interact.DOM 4531 . 4532 /** 4533 * 阻止 JavaScript 事件冒泡傳遞,使 event 不傳到 parentNode。 4534 * @param e event handle 4535 * @param c cancel bubble 4536 * @see 4537 * http://www.jb51.net/html/200705/23/9858.htm 4538 * @memberOf CeL.interact.DOM 4539 */ 4540 stop_event = function(e, c) { 4541 if (!e) 4542 e = window.event; 4543 4544 if(e.preventDefault) 4545 e.preventDefault(); 4546 else 4547 e.returnValue = false; 4548 4549 if(c) 4550 // cancelBubble 在IE下有效,stopPropagation 在 Firefox 下有效。 4551 // 停止冒泡,事件不會上升,我們就可以獲取精確的鼠標進入元素。 http://realazy.org/lab/bubble/ 4552 if(e.stopPropagation) 4553 e.stopPropagation(); 4554 else 4555 e.cancelBubble = true; 4556 }; 4557 4558 4559 4560 CeL.interact.DOM 4561 . 4562 /** 4563 * 獲取頁面上選中的選取區資訊。 4564 * 4565 * @example 4566 * CeL.add_listener('mouseup', function (e) { var s = CeL.get_selection(); if (s && s.text) CeL.debug('select @' + this + '(' + s.element + ')' + ' (' + s.left + '+' + s.width + ',' + s.top + '+' + s.height + '), (' + e.pageX + ',' + e.pageY + '): ' + s.text); }, target_element); 4567 * 4568 * @param {Number} [index] TODO: 第幾選取區, default: all or 0 if there's only ONE/ZERO selection 4569 * @return {Object} 4570 * { 4571 * left: {Number} in px, 4572 * top: {Number} in px, 4573 * width: {Number} in px, 4574 * height: {Number} in px, 4575 * text: {String} 文字, 4576 * element: {HTMLElement}, 4577 * selection: selection object (browser dependent) 4578 * } 4579 * @return {undefined} error. 4580 * @see 4581 * http://plugins.jquery.com/project/selectedText, 4582 * Gecko: https://developer.mozilla.org/en/DOM/Selection 4583 * @memberOf CeL.interact.DOM 4584 */ 4585 get_selection = function(index) { 4586 }; 4587 4588 4589 try{ 4590 4591 if (window.getSelection) 4592 _.get_selection = function(index) { 4593 // Firefox, Opera, Safari 4594 // http://help.dottoro.com/ljcvonpc.php 4595 // Although the selection object is supported by Opera, it is only partially suppported. The window.getSelection method provides more complex functionality in that browser. 4596 // http://www.dotvoid.com/2001/03/using-the-range-object-in-mozilla/ 4597 var e = document.activeElement, 4598 // 在 Opera 中,e 為 [object Text] 4599 tag = e && e.tagName && e.tagName.toLowerCase(), 4600 s = window.getSelection(); 4601 if(!s.rangeCount) 4602 // 點擊而無選擇? 4603 // 最起碼回應能得知的資訊 4604 return { 4605 text : '', 4606 element: s, 4607 selection: s 4608 }; 4609 4610 // 超出範圍可能會 Error: INDEX_SIZE_ERR: DOM Exception 1 4611 s = s.getRangeAt(!isNaN(index) && 0 <= index 4612 && index < s.rangeCount ? index : 0); 4613 4614 // Gecko: https://developer.mozilla.org/en/DOM/range 4615 // 除了 Gecko 外,都有 s.getBoundingClientRect 但無 s.endContainer.getBoundingClientRect。 4616 // Gecko 可以取 mouse event 作 workaround 4617 //library_namespace.debug(s.endContainer.parentNode); 4618 var offset = _.get_node_offset( 4619 s.getBoundingClientRect ? s : s.endContainer.parentNode 4620 ); 4621 4622 return { 4623 // TODO: offset 4624 // TODO: do test 4625 //s.startOffset, 4626 left : offset.left, 4627 top : offset.top, 4628 //s.endOffset, 4629 width : offset.width, 4630 height : offset.height, 4631 text : tag === 'textarea' || tag === 'input' || tag === 'select' 4632 ? e.value.substring(e.selectionStart, e.selectionEnd) 4633 : s.toString(), 4634 element: s,//s.endContainer, 4635 selection: s 4636 }; 4637 4638 }; 4639 4640 else if (document.selection && document.selection.createRange) { 4641 // Internet Explorer 4642 // http://msdn.microsoft.com/en-us/library/ms534692%28VS.85%29.aspx 4643 // TODO: http://help.dottoro.com/ljefwsqm.php 4644 4645 document.execCommand 4646 && document.execCommand('MultipleSelection', true, true); 4647 4648 _.get_selection = function(input) { 4649 var s = document.selection.createRange(); 4650 4651 return s.type !== 'None' && { 4652 // TODO: do test 4653 // http://msdn.microsoft.com/en-us/library/ms535872%28v=VS.85%29.aspx 4654 // s.offsetLeft, s.offsetTop 較不準 4655 left : s.boundingLeft, 4656 top : s.boundingTop, 4657 width : s.boundingWidth, 4658 height : s.boundingHeight, 4659 text : s.text, 4660 // TODO 4661 //element: null, 4662 selection: s 4663 }; 4664 4665 }; 4666 4667 } else if (document.getSelection) 4668 _.get_selection = function(input) { 4669 return { 4670 // TODO: get offset from mouse location 4671 text : document.getSelection() 4672 }; 4673 }; 4674 4675 }catch (e) { 4676 // TODO: handle exception 4677 } 4678 4679 /* 4680 ↑HTML only ------------------------------------------------------- 4681 */ 4682 4683 4684 4685 var is_IE=/*@cc_on!@*/!true; 4686 4687 /* 4688 http://www.real-blog.com/programming/259 4689 http://fettig.net/weblog/2006/10/09/detecting-ie7-in-javascript/ 4690 4691 if(typeof window.XMLHttpRequest!="undefined"){ 4692 // IE 7, mozilla, safari, opera 9 4693 }else{ 4694 // IE6, older browsers 4695 } 4696 */ 4697 4698 4699 4700 4701 4702 /* 4703 http://www.cnlei.org/blog/article.asp?id=337 4704 在IE下: 4705 >> 支持keyCode 4706 >> 不支持which和charCode,二者值為 undefined 4707 4708 在Firefox下: 4709 >> 支持keyCode,除功能鍵外,其他鍵值始終為 0 4710 >> 支持which和charCode,二者的值相同 4711 4712 在Opera下: 4713 >> 支持keyCode和which,二者的值相同 4714 >> 不支持charCode,值為 undefined 4715 4716 */ 4717 CeL.interact.DOM 4718 . 4719 /** 4720 * 條碼器(Barcode Scanner)/雷射讀碼器的輸入可用 onkeypress 取得 4721 * @param callback callback 4722 * @return 4723 * @since 2008/8/26 23:10 4724 * @example 4725 * // usage: 4726 * deal_barcode(function(t) { 4727 * if (t.length > 9 && t.length < 17) 4728 * document.getElementById("p").value = t, 4729 * document.forms[0].submit(); 4730 * }); 4731 * @memberOf CeL.interact.DOM 4732 */ 4733 deal_barcode = function (callback) { 4734 var k, lt = 0, st = 0; 4735 document.onkeypress = function(e) { 4736 var c = new Date(); 4737 if ( 4738 // 前後不超過 800, 4739 c - st > 800 || 4740 // 與上一輸入不超過 90 4741 c - lt > 90) { 4742 st = c; 4743 k = ""; 4744 } 4745 lt = c; 4746 c = e || window.event; 4747 c = c.keyCode || c.which || c.charCode; 4748 if (c > 32 && c < 120) 4749 k += String.fromCharCode(c); 4750 else if (c == 13) 4751 callback(k, e); 4752 }; 4753 4754 }; 4755 4756 4757 4758 // https://addons.mozilla.org/js/search-plugin.js 4759 // TODO, & Chrome 4760 function addEngine(){ 4761 } 4762 4763 4764 4765 // for string encoding ------------------------------------------------------- 4766 // 將HTML:ddd; → Unicode text 4767 // 此函數只能用一次,為輸入資料良好之情況下使用。完整版: HTML_to_Unicode 4768 //turnUnicode[generateCode.dLK]='setTool,getText'; 4769 function turnUnicode(b){ 4770 //s=s.replace(/(\d+);/g,String.fromCharCode("$1"));//行不通 4771 var s=this.valueOf().replace(/ /g,' ').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"').replace(/'/g,"'"),m,t; 4772 4773 //舊版本 4774 //if(m=s.match(/(\d{2,7});/g))for(var i=0;i<m.length;i++)s=s.replace(m[i],String.fromCharCode(parseInt(m[i].slice(2,-1)))); 4775 4776 s=s //.replace(/(0*38|[xX]0*26);/g,"\0") //預防&:&=& 4777 // .replace(/*38;([^\d;]|$)/g,"\0$1").replace(/[xX]0*26;?([^a-fA-F\d;]|$)/g,"\0$1") 4778 4779 .replace(/*(\d{2,7});/g,function($0,$1){return String.fromCharCode($1);}) //JScript 5.5~ 4780 // .replace(/*(\d{2,7});/g,function($0,$1){return $1>1114111?$0:String.fromCharCode($1);}) //預防error之版本,~10FFFF=1114111 4781 4782 //if(mode=='x') 4783 //.replace(/[xX]0*([a-fA-F\d]{2,6});/g,function($0,$1){return String.fromCharCode(parseInt($1,16));}) //$x111;之版本 4784 // .replace(/[xX]0*([a-fA-F\d]{2,6});/g,function($0,$1){var t=parseInt($1,16);return t>1114111?$0:String.fromCharCode(t);}) 4785 4786 //.replace(/\0/g,"&") //預防&回復 4787 ; 4788 if(b)s=s.gText(); 4789 return s; 4790 }; 4791 // 可適用perl: HTML::Entities::encode_entities() 4792 // 需要escape的: [\<\>\"\'\%\;\)\(\&\+], tr/A-Za-z0-9\ //dc http://www.cert.org/tech_tips/malicious_code_mitigation.html 4793 CeL.interact.DOM 4794 . 4795 /** 4796 * Translate HTML code to Unicode text 4797 * @param {String} HTML HTML code 4798 * @param {Boolean} only_digital 4799 * @returns 4800 * @memberOf CeL.interact.DOM 4801 */ 4802 HTML_to_Unicode=function (HTML, only_digital) { 4803 // 使用\0可能會 Warning: non-octal digit in an escape sequence that doesn't match a back-reference 4804 var t = HTML.valueOf(); 4805 4806 if (!only_digital) 4807 t = t 4808 // 自動clip null character 4809 .replace(/\0\0/g, '') 4810 .replace(/ /g, ' ') 4811 .replace(/</g, '<') 4812 .replace(/>/g, '>') 4813 .replace(/"/g, '"') 4814 .replace(/'/g, "'") 4815 .replace(/®/g, "®") 4816 ; 4817 4818 t = t 4819 //預防&:&=& 4820 .replace(/(0*38|[xX]0*26);/g, "\0\0") 4821 //預防error之版本,~10FFFF=1114111 4822 .replace(/*(\d{2,7});/g, function ($0, $1) { return $1 > 1114111 ? $0 : String.fromCharCode($1); }) 4823 .replace(/[xX]0*([a-fA-F\d]{2,6});/g, function ($0, $1) { var t = parseInt($1, 16); return t > 1114111 ? $0 : String.fromCharCode(t); }) 4824 ; 4825 4826 if (!only_digital) 4827 t = t 4828 //預防&回復 4829 .replace(/\0\0/g, "&") 4830 .replace(/&/g, '&') 4831 ; 4832 4833 return t; 4834 }; 4835 4836 CeL.interact.DOM 4837 . 4838 /** 4839 * Translate Unicode text to HTML 4840 * @param {String} text Unicode text 4841 * @param mode mode='x':hhh; 4842 * @return {String} HTML 4843 * @memberOf CeL.interact.DOM 4844 */ 4845 to_HTML=function (text, mode) { 4846 var html = '', t, i = 0; 4847 for (; i < text.length; i++) 4848 t = text.charCodeAt(i), html += '' + (mode === 'x' ? 'x' + t 4849 .toString(16) : t) + ';'; 4850 return html; 4851 }; 4852 CeL.interact.DOM 4853 . 4854 /** 4855 * Translate Unicode text to HTML code 4856 * @param text Unicode text 4857 * @param flags flags, f&1!=0: turn \t, (f&2)==0: \n→<br/>, f==4: to quoted 4858 * @param ignore_tags e.g., {object:{src:/^https?:\/\//},img:{src:/^https?:\/\//},a:{href:/^https?:\/\//}} 4859 * @return 4860 * @memberOf CeL.interact.DOM 4861 */ 4862 Unicode_to_HTML=function (text, flags, ignore_tags) { 4863 text = ('' + text) 4864 .replace(/&/g, '&') 4865 // 就是會出現這奇怪情況。 4866 .replace(/&/gi, '&') 4867 .replace(/>/g, '>') 4868 .replace(/"/g, '"') 4869 ; 4870 4871 if (ignore_tags) 4872 text = text.replace( 4873 /<([^>]+)>/g, 4874 function($0, $1) { 4875 if (!($1 in ignore_tags)) 4876 return '<' + $1; 4877 var s = $1.split(/ /), i = 1, l = s.length, c = ignore_tags[$1]; 4878 for (; i < l; i++) { 4879 m = s[i].match(/^([^=]+)(.+?)/); 4880 if (!(m[1] in c) 4881 || !(library_namespace.is_type( 4882 c[m[1]], 'RegExp') 4883 && c[m[1]].test(m[2]) || library_namespace 4884 .is_Function(c[m[1]]) 4885 && c[m[1]](m[2]))) 4886 s[i] = ''; 4887 return s.join(' '); 4888 } 4889 }); 4890 else 4891 text = text.replace(/</g, '<'); 4892 4893 if (flags == 4) return text; 4894 4895 text = text.replace(/ /g, ' '); 4896 4897 //if(!f)f=0; 4898 if (flags & 1) 4899 text = text.replace(/ /g, '<span style="margin-left:3em;"> </span>'); 4900 if (!(flags & 2)) 4901 text = text.replace(/(\r?\n)/g, '<br/>$1'); //+'<br/>\n'; 4902 return text; 4903 }; 4904 4905 // Ucode:\uhhhh及\xhh之意 4906 function UcodeToTxt(U) { 4907 var T = U.replace(/\\\\|\\u005[cC]|\\x5[cC]|\\134/g, "\0") 4908 /* 4909 //way 1 4910 .replace(/\\u([a-fA-F\d]{4})/g,function($0,$1){return String.fromCharCode(parseInt($1,16));}) 4911 .replace(/\\x([a-fA-F\d]{2})/g,function($0,$1){return String.fromCharCode(parseInt($1,16));}) 4912 .replace(/\\([0-7]{1,3})/g,function($0,$1){return String.fromCharCode(parseInt($1,16));}) 4913 //way 2 4914 .replace(/\\(u[a-fA-F\d]{4}|x[a-fA-F\d]{2})/g,function($0,$1){return String.fromCharCode(parseInt($1.substr(1),16));}) 4915 .replace(/\\([0-7]{1,3})/g,function($0,$1){return String.fromCharCode(parseInt($1,16));}) 4916 */ 4917 //way 3 4918 .replace(/\\(u[a-fA-F\d]{4}|x[a-fA-F\d]{2}|[0-7]{1,3})/g, function ($0, $1) { var t = $1.charAt(0); return String.fromCharCode(parseInt(t == 'u' || t == 'x' ? $1.substr(1) : $1, 16)); }) 4919 ; 4920 4921 if (T.indexOf("\\") != -1) 4922 T = T 4923 .replace(/\\t/g, "<Tab>") 4924 .replace(/\\n/g, "<Line Feed>") 4925 .replace(/\\v/g, "<Vertical Tab>") 4926 .replace(/\\f/g, "<Form Feed>") 4927 .replace(/\\r/g, "<Carriage Return>") 4928 .replace(/\\(.)/g, "$1"); 4929 4930 return T.replace(/\0/g, "\\"); 4931 } 4932 function TxtToUcode(T, l) { 4933 var i = 0, U = '', t; 4934 if (!l) l = 0; 4935 for (; i < T.length; i++) 4936 U += (t = T.charCodeAt(i)) < l ? T.charAt(i) : "\\u0000".substr(0, 6 - (t = t.toString(16)).length) + t; 4937 return U; 4938 } 4939 function CSSToTxt(C) { 4940 return C.replace(/\\\\|\\0{0,4}5[cC][ \t\r\n\f]?/g, "\0") 4941 .replace(/\\([a-fA-F\d]{1,6})[ \t\r\n\f]?/g, function ($0, $1) { return String.fromCharCode(parseInt($1, 16)); }) 4942 .replace(/\\(.)/g, "$1").replace(/\0/g, "\\"); 4943 } 4944 function TxtToCSS(T, r, sp) { 4945 // r:radio,sp:separator 4946 var i = 0, C = '', t, p = r && r > 3 && r < 9 ? '0'.x(r - 1) : ''; 4947 if (!sp) sp = ''; sp += '\\'; 4948 4949 for (; i < T.length; i++) 4950 t = T.charCodeAt(i).toString(16) 4951 , C += sp + p.substr(0, r - t.length) + t; //(p&&r>t.length?p.substr(0,r-t.length):''):如果length是0或負值,會傳回空字串。 4952 return C.slice(sp.length - 1); 4953 } 4954 4955 4956 CeL.interact.DOM 4957 . 4958 /** 4959 * Translate a query string to a native Object contains key/value pair set. 4960 * @param {String} query_string query string. default: location.search 4961 * @param {Object} add_to append to this object 4962 * @return key/value pairs 4963 * @type Object 4964 * @since 2010/6/16 15:18:50 4965 * @memberOf CeL.interact.DOM 4966 * @see 4967 */ 4968 get_query = function(query_string, add_to) { 4969 if (!query_string) 4970 query_string = window/* self */.location.search.slice(1); 4971 // else if(typeof query_string!=='string').. 4972 4973 var i, q = query_string.replace(/\+/g, ' ').split('&'), p, s = add_to || {}, k, v; 4974 for (i in q) 4975 try { 4976 if (p = q[i].match(/^([^=]*)=(.*)$/)) { 4977 k = decodeURIComponent(p[1]); 4978 v = decodeURIComponent(p[2]); 4979 if (k in s) 4980 if (typeof s[k] === 'string') 4981 s[k] = [ s[k], v ]; 4982 else 4983 s[k].push(v); 4984 else 4985 s[k] = v; 4986 } else 4987 s[decodeURIComponent(q[i])] = undefined; 4988 } catch (e) { 4989 // TODO: handle exception 4990 } 4991 4992 return s; 4993 }; 4994 4995 4996 CeL.interact.DOM 4997 . 4998 /** 4999 * Translate a native Object contains key/value pair set to a query string. 5000 * TODO 5001 * @param {Object} query_Object query Object. 5002 * @return {String} query string 5003 * @type String 5004 * @memberOf CeL.interact.DOM 5005 * @see 5006 * jQuery.param 5007 */ 5008 to_query_string = function(query_Object) { 5009 ; 5010 }; 5011 5012 /* 簡化 HTML (word) 5013 simplify HTML 5014 目標:剩下語意部分,去掉 style。 5015 TODO: 5016 保留 b, em 5017 */ 5018 5019 // 保留 color: return style string to add 5020 //reduceHTML.keep_color= 5021 reduceHTML._keep_color = 5022 function (c) { 5023 if (c !== 'black') 5024 return c; 5025 }; 5026 reduceHTML.file = function (FP, enc) { 5027 //sl('reduceHTML [' + FP + ']'); 5028 var t = simpleRead(FP, enc || simpleFileAutodetectEncode), l; 5029 if (!t) { 5030 err('Open [' + FP + '] failed.'); 5031 return; 5032 } 5033 5034 l = t.length; 5035 t = this(t); 5036 5037 FP = FP.replace(/\.s?html?$/i, function ($0) { return '.reduced' + $0; }); 5038 //sl('reduceHTML: ' + l + '→' + t.length + ' (' + parseInt(100 * t.length / l) + '%)' + ', save to [<a href="' + encodeURI(FP) + '">' + FP + '</a>].'); 5039 simpleWrite(FP, t, 'utf-8'); 5040 }; 5041 function reduceHTML(t) { 5042 if (!t) 5043 return; 5044 var _f = reduceHTML, f = function($0, $1, $2) { 5045 return $1 != $2 || ($1.toLowerCase() in { 5046 a : 1, 5047 p : 1, 5048 head : 1 5049 }) ? $0 : ''; 5050 }; 5051 //if(m=t.match(/<!--\[if [^\]]+\]>(.|\n)*?<!\[endif\]-->/))sl(m[0].replace(/</g,'<')); 5052 //if(m=t.match(/<!\[if !vml\]>((.|\n)*?)<!\[endif\]>/))sl(m[0]); 5053 5054 t = t 5055 .replace(/[\s\n]*<(t[dh])([^>]+)>[\s\n]*/ig, function ($0, $1, $2) { var a = $2.match(/[\s\n](col|row)span=['"]?\d{1,3}['"]?/ig); return '<' + $1 + (a ? a.join('') : '') + '>'; }) 5056 .replace(/<\?xml:namespace[^>]+>/g, '') 5057 .replace(/[\s\n]*(<\/t[dh]>)[\s\n]*/ig, '$1') 5058 .replace(/<wbr([^>]*)>/ig, '<br/>') 5059 .replace(/<([bh]r)[\s\n]+([^>]*)\/?>/ig, function ($0, $1, $2) { var m = $2.match(/[\s\n;"'][\s\n]*page-break-before[\s\n]*:[\s\n]*([^\s\n;"']+)/); return '<' + $1 + (m ? ' style="page-break-before:' + m[1] + '"' : '') + '>'; }) 5060 .replace(/<(span|font|p|div|b|u|i)[\s\n]+([^>]*)>/ig, function ($0, $1, $2) { 5061 var t = '<' + $1, s = '', m; 5062 if ( 5063 // /Italic/i.test($2) 5064 $2.indexOf('Italic') !== -1) 5065 s += 'font-style:italic;'; 5066 // TODO: <u>, <b> 5067 if (_f.keep_color && (m = $2.match(/[\s\n;"'][\s\n]*color[\s\n]*:[\s\n]*([^\s\n;"']+)/)) && (m = _f.keep_color(m[1]))) 5068 // 保留 color 5069 s += 'color:' + m + ';'; 5070 return t + (s ? ' style="' + s + '"' : '') + '>'; 5071 }) 5072 .replace(/<(tr|table)[\s\n]+([^>]*)>/ig, '<$1>') 5073 .replace(/<span>((.|\n)*?)<\/span>/ig, '$1') // 不能用 .+|\n ,IE8 sometimes crash 5074 .replace(/<span>((.|\n)*?)<\/span>/ig, '$1') // need several times 5075 .replace(/<font>((.|\n)*?)<\/font>/ig, '$1') 5076 .replace(/<([a-z\d]+)>[\s\n]*<\/([a-z\d]+)>/ig, f) 5077 .replace(/<([a-z\d]+)>[\s\n]*<\/([a-z\d]+)>/ig, f) // 2 times 5078 .replace(/<o:p>((.|\n)*?)<\/o:p>/ig, '$1') 5079 .replace(/<st1:[^>]+>((.|\n)*?)<\/st1:[^>]+>/ig, '$1') 5080 .replace(/<!\[if !vml\]>((.|\n)*?)<!\[endif\]>/ig, '$1') 5081 .replace(/<o:SmartTagType [^>]+\/>/ig, '') 5082 /* 5083 <td> 5084 <p> </p> 5085 </td> 5086 */ 5087 .replace(/<(span|p|div|t[dr])([^>]*>)<(span|p)>(([\s\n]+| )*?)<\/(span|p)><\/(span|p|div|t[dr])>/ig, '<$1$2$4</$7>') 5088 .replace(/<link rel=(File-List|colorSchemeMapping|themeData|Edit-Time-Data)[^>]+>/ig, '') 5089 .replace(/^\s*<html[^>]*>(\r?\n)*/, '<html>') 5090 .replace(/(\r?\n)*<body[^>]+>(\r?\n)*/, '<body>') 5091 .replace(/(\r?\n)*<!--\[if [^\]]+\]>(.|\n)*?<!\[endif\]-->(\r?\n)*/ig, '') 5092 .replace(/(\r?\n)*<style[^>]*>(.|\n)*?<\/style>(\r?\n)*/ig, '') 5093 .replace(/(\r?\n)*<meta[\s\n][^>]+>(\r?\n)*/ig, '') 5094 5095 // from HTML_to_Unicode() 5096 .replace(/*(\d{2,7});/ig, function ($0, $1) { return $1 > 1114111 ? $0 : String.fromCharCode($1); }) //預防error之版本,~10FFFF=1114111 5097 .replace(/([\s\n]+| )+$|^([\s\n]+| )+/g, '') 5098 ; 5099 5100 if (/<table[\s>\r\n]/.test(t)) 5101 //sl('Has table'), 5102 t = t.replace(/<\/head>/i, '<style type="text/css">table,th,td{border:1px solid #888;border-collapse:collapse;}</style></head>'); 5103 5104 return t; 5105 }; 5106 5107 5108 CeL.interact.DOM 5109 . 5110 /** 5111 * 將 BIG5 日文假名碼修改為 Unicode 日文假名。 5112 * @param {String} text Unicode text 5113 * @return 5114 * @see 5115 * from Unicode 補完計畫 jrename.js 5116 */ 5117 Big5_kana_fix = function(text) { 5118 var H = '', t, i = 0; 5119 for (; i < text.length; i++) 5120 t = c.charCodeAt(0) 5121 // 某次破解Windows Installer所用的資料 5122 // ,H+=String.fromCharCode(t>61300?t-48977:t); 5123 , H += t === 63219 ? 'ー' : String.fromCharCode( 5124 // ひらがな 5125 t >= 63223 && t <= 63305 ? t - 50870 : 5126 // カタカナ 5127 t >= 63306 && t <= 63391 ? t - 50857 : 5128 // text.charAt(i); 5129 t); 5130 return H; 5131 }; 5132 5133 5134 // ↑for string encoding ----------------------------------------------- 5135 5136 5137 5138 5139 return ( 5140 CeL.interact.DOM 5141 ); 5142 } 5143 5144 5145 }); 5146 5147