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