[ Index ] |
|
Code source de Joomla 1.0.13 |
1 /* 2 JSCookMenu v1.4.3. (c) Copyright 2002-2005 by Heng Yuan 3 4 Permission is hereby granted, free of charge, to any person obtaining a 5 copy of this software and associated documentation files (the "Software"), 6 to deal in the Software without restriction, including without limitation 7 the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 and/or sell copies of the Software, and to permit persons to whom the 9 Software is furnished to do so, subject to the following conditions: 10 11 The above copyright notice and this permission notice shall be included 12 in all copies or substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 ITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 DEALINGS IN THE SOFTWARE. 21 */ 22 23 // Globals 24 var _cmIDCount = 0; 25 var _cmIDName = 'cmSubMenuID'; // for creating submenu id 26 27 var _cmTimeOut = null; // how long the menu would stay 28 var _cmCurrentItem = null; // the current menu item being selected; 29 30 var _cmNoAction = new Object (); // indicate that the item cannot be hovered. 31 var _cmNoClick = new Object (); // similar to _cmNoAction but does not respond to mouseup/mousedown events 32 var _cmSplit = new Object (); // indicate that the item is a menu split 33 34 var _cmItemList = new Array (); // a simple list of items 35 36 // default node properties 37 var _cmNodeProperties = 38 { 39 // main menu display attributes 40 // 41 // Note. When the menu bar is horizontal, 42 // mainFolderLeft and mainFolderRight are 43 // put in <span></span>. When the menu 44 // bar is vertical, they would be put in 45 // a separate TD cell. 46 47 // HTML code to the left of the folder item 48 mainFolderLeft: '', 49 // HTML code to the right of the folder item 50 mainFolderRight: '', 51 // HTML code to the left of the regular item 52 mainItemLeft: '', 53 // HTML code to the right of the regular item 54 mainItemRight: '', 55 56 // sub menu display attributes 57 58 // HTML code to the left of the folder item 59 folderLeft: '', 60 // HTML code to the right of the folder item 61 folderRight: '', 62 // HTML code to the left of the regular item 63 itemLeft: '', 64 // HTML code to the right of the regular item 65 itemRight: '', 66 // cell spacing for main menu 67 mainSpacing: 0, 68 // cell spacing for sub menus 69 subSpacing: 0, 70 // auto disappear time for submenus in milli-seconds 71 delay: 500, 72 73 // act on click to open sub menu 74 // not yet implemented 75 // 0 : use default behavior 76 // 1 : hover open in all cases 77 // 2 : click on main, hover on sub 78 // 3 : click open in all cases 79 clickOpen: 1 80 }; 81 82 ////////////////////////////////////////////////////////////////////// 83 // 84 // Drawing Functions and Utility Functions 85 // 86 ////////////////////////////////////////////////////////////////////// 87 88 // 89 // produce a new unique id 90 // 91 function cmNewID () 92 { 93 return _cmIDName + (++_cmIDCount); 94 } 95 96 // 97 // return the property string for the menu item 98 // 99 function cmActionItem (item, prefix, isMain, idSub, orient, nodeProperties) 100 { 101 var clickOpen = _cmNodeProperties.clickOpen; 102 if (nodeProperties.clickOpen) 103 clickOpen = nodeProperties.clickOpen; 104 105 // var index = _cmItemList.push (item) - 1; 106 _cmItemList[_cmItemList.length] = item; 107 var index = _cmItemList.length - 1; 108 idSub = (!idSub) ? 'null' : ('\'' + idSub + '\''); 109 orient = '\'' + orient + '\''; 110 prefix = '\'' + prefix + '\''; 111 var onClick = (clickOpen == 3) || (clickOpen == 2 && isMain); 112 var returnStr; 113 if (onClick) 114 returnStr = ' onmouseover="cmItemMouseOver (this,' + prefix + ',' + isMain + ',' + idSub + ',' + index + ')" onmousedown="cmItemMouseDownOpenSub (this,' + index + ',' + prefix + ',' + orient + ',' + idSub + ')"'; 115 else 116 returnStr = ' onmouseover="cmItemMouseOverOpenSub (this,' + prefix + ',' + isMain + ',' + idSub + ',' + orient + ',' + index + ')" onmousedown="cmItemMouseDown (this,' + index + ')"'; 117 return returnStr + ' onmouseout="cmItemMouseOut (this,' + nodeProperties.delay + ')" onmouseup="cmItemMouseUp (this,' + index + ')"'; 118 } 119 120 // 121 // this one is used by _cmNoClick to only take care of onmouseover and onmouseout 122 // events which are associated with menu but not actions associated with menu clicking/closing 123 // 124 function cmNoClickItem (item, prefix, isMain, idSub, orient, nodeProperties) 125 { 126 // var index = _cmItemList.push (item) - 1; 127 _cmItemList[_cmItemList.length] = item; 128 var index = _cmItemList.length - 1; 129 idSub = (!idSub) ? 'null' : ('\'' + idSub + '\''); 130 orient = '\'' + orient + '\''; 131 prefix = '\'' + prefix + '\''; 132 return ' onmouseover="cmItemMouseOver (this,' + prefix + ',' + isMain + ',' + idSub + ',' + index + ')" onmouseout="cmItemMouseOut (this,' + nodeProperties.delay + ')"'; 133 } 134 135 function cmNoActionItem (item, prefix) 136 { 137 return item[1]; 138 } 139 140 function cmSplitItem (prefix, isMain, vertical) 141 { 142 var classStr = 'cm' + prefix; 143 if (isMain) 144 { 145 classStr += 'Main'; 146 if (vertical) 147 classStr += 'HSplit'; 148 else 149 classStr += 'VSplit'; 150 } 151 else 152 classStr += 'HSplit'; 153 return eval (classStr); 154 } 155 156 // 157 // draw the sub menu recursively 158 // 159 function cmDrawSubMenu (subMenu, prefix, id, orient, nodeProperties) 160 { 161 var str = '<div class="' + prefix + 'SubMenu" id="' + id + '"><table summary="sub menu" cellspacing="' + nodeProperties.subSpacing + '" class="' + prefix + 'SubMenuTable">'; 162 var strSub = ''; 163 164 var item; 165 var idSub; 166 var hasChild; 167 168 var i; 169 170 var classStr; 171 172 for (i = 5; i < subMenu.length; ++i) 173 { 174 item = subMenu[i]; 175 if (!item) 176 continue; 177 178 hasChild = (item.length > 5); 179 idSub = hasChild ? cmNewID () : null; 180 181 if (item == _cmSplit) 182 item = cmSplitItem (prefix, 0, true); 183 184 str += '<tr class="' + prefix + 'MenuItem"'; 185 if (item[0] != _cmNoClick) 186 str += cmActionItem (item, prefix, 0, idSub, orient, nodeProperties); 187 else 188 str += cmNoClickItem (item, prefix, 0, idSub, orient, nodeProperties); 189 str += '>' 190 191 if (item[0] == _cmNoAction || item[0] == _cmNoClick) 192 { 193 str += cmNoActionItem (item, prefix); 194 str += '</tr>'; 195 continue; 196 } 197 198 classStr = prefix + 'Menu'; 199 classStr += hasChild ? 'Folder' : 'Item'; 200 201 str += '<td class="' + classStr + 'Left">'; 202 203 if (item[0] != null) 204 str += item[0]; 205 else 206 str += hasChild ? nodeProperties.folderLeft : nodeProperties.itemLeft; 207 208 str += '</td><td class="' + classStr + 'Text">' + item[1]; 209 210 str += '</td><td class="' + classStr + 'Right">'; 211 212 if (hasChild) 213 { 214 str += nodeProperties.folderRight; 215 strSub += cmDrawSubMenu (item, prefix, idSub, orient, nodeProperties); 216 } 217 else 218 str += nodeProperties.itemRight; 219 str += '</td></tr>'; 220 } 221 222 str += '</table></div>' + strSub; 223 return str; 224 } 225 226 // 227 // The function that builds the menu inside the specified element id. 228 // 229 // @param id id of the element 230 // orient orientation of the menu in [hv][ab][lr] format 231 // menu the menu object to be drawn 232 // nodeProperties properties for each menu node 233 // 234 function cmDraw (id, menu, orient, nodeProperties, prefix) 235 { 236 var obj = cmGetObject (id); 237 238 if (!nodeProperties) 239 nodeProperties = _cmNodeProperties; 240 if (!prefix) 241 prefix = ''; 242 243 var str = '<table summary="main menu" class="' + prefix + 'Menu" cellspacing="' + nodeProperties.mainSpacing + '">'; 244 var strSub = ''; 245 246 if (!orient) 247 orient = 'hbr'; 248 249 var orientStr = String (orient); 250 var orientSub; 251 var vertical; 252 253 // draw the main menu items 254 if (orientStr.charAt (0) == 'h') 255 { 256 // horizontal menu 257 orientSub = 'v' + orientStr.substr (1, 2); 258 str += '<tr>'; 259 vertical = false; 260 } 261 else 262 { 263 // vertical menu 264 orientSub = 'v' + orientStr.substr (1, 2); 265 vertical = true; 266 } 267 268 var i; 269 var item; 270 var idSub; 271 var hasChild; 272 273 var classStr; 274 275 for (i = 0; i < menu.length; ++i) 276 { 277 item = menu[i]; 278 279 if (!item) 280 continue; 281 282 str += vertical ? '<tr' : '<td'; 283 str += ' class="' + prefix + 'MainItem"'; 284 285 hasChild = (item.length > 5); 286 idSub = hasChild ? cmNewID () : null; 287 288 str += cmActionItem (item, prefix, 1, idSub, orient, nodeProperties) + '>'; 289 290 if (item == _cmSplit) 291 item = cmSplitItem (prefix, 1, vertical); 292 293 if (item[0] == _cmNoAction || item[0] == _cmNoClick) 294 { 295 str += cmNoActionItem (item, prefix); 296 str += vertical? '</tr>' : '</td>'; 297 continue; 298 } 299 300 classStr = prefix + 'Main' + (hasChild ? 'Folder' : 'Item'); 301 302 str += vertical ? '<td' : '<span'; 303 str += ' class="' + classStr + 'Left">'; 304 305 str += (item[0] == null) ? (hasChild ? nodeProperties.mainFolderLeft : nodeProperties.mainItemLeft) 306 : item[0]; 307 str += vertical ? '</td>' : '</span>'; 308 309 str += vertical ? '<td' : '<span'; 310 str += ' class="' + classStr + 'Text">'; 311 str += item[1]; 312 313 str += vertical ? '</td>' : '</span>'; 314 315 str += vertical ? '<td' : '<span'; 316 str += ' class="' + classStr + 'Right">'; 317 318 str += hasChild ? nodeProperties.mainFolderRight : nodeProperties.mainItemRight; 319 320 str += vertical ? '</td>' : '</span>'; 321 322 str += vertical ? '</tr>' : '</td>'; 323 324 if (hasChild) 325 strSub += cmDrawSubMenu (item, prefix, idSub, orientSub, nodeProperties); 326 } 327 if (!vertical) 328 str += '</tr>'; 329 str += '</table>' + strSub; 330 obj.innerHTML = str; 331 //document.write ("<xmp>" + str + "</xmp>"); 332 } 333 334 // 335 // The function builds the menu inside the specified element id. 336 // 337 // This function is similar to cmDraw except that menu is taken from HTML node 338 // rather a javascript tree. This feature allows links to be scanned by search 339 // bots. 340 // 341 // This function basically converts HTML node to a javascript tree, and then calls 342 // cmDraw to draw the actual menu, replacing the hidden menu tree. 343 // 344 // Format: 345 // <div id="menu"> 346 // <ul style="visibility: hidden"> 347 // <li><span>icon</span><a href="link" title="description">main menu text</a> 348 // <ul> 349 // <li><span>icon</span><a href="link" title="description">submenu item</a> 350 // </li> 351 // </ul> 352 // </li> 353 // </ul> 354 // </div> 355 // 356 function cmDrawFromText (id, orient, nodeProperties, prefix) 357 { 358 var domMenu = cmGetObject (id); 359 var menu = null; 360 for (var currentDomItem = domMenu.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling) 361 { 362 if (!currentDomItem.tagName || currentDomItem.tagName.toLowerCase () != 'ul') 363 continue; 364 menu = cmDrawFromTextSubMenu (currentDomItem); 365 break; 366 } 367 if (menu) 368 cmDraw (id, menu, orient, nodeProperties, prefix); 369 } 370 371 // 372 // a recursive function that build menu tree structure 373 // 374 function cmDrawFromTextSubMenu (domMenu) 375 { 376 var items = new Array (); 377 for (var currentDomItem = domMenu.firstChild; currentDomItem; currentDomItem = currentDomItem.nextSibling) 378 { 379 if (!currentDomItem.tagName || currentDomItem.tagName.toLowerCase () != 'li') 380 continue; 381 if (currentDomItem.firstChild == null) 382 { 383 items[items.length] = _cmSplit; 384 continue; 385 } 386 var item = new Array (); 387 var currentItem = currentDomItem.firstChild; 388 for (; currentItem; currentItem = currentItem.nextSibling) 389 { 390 // scan for span tag 391 if (!currentItem.tagName || currentItem.tagName.toLowerCase () != 'span') 392 continue; 393 if (!currentItem.firstChild) 394 item[0] = null; 395 else 396 item[0] = currentItem.innerHTML; 397 break; 398 } 399 if (!currentItem) 400 continue; 401 for (; currentItem; currentItem = currentItem.nextSibling) 402 { 403 // scan for span tag 404 if (!currentItem.tagName || currentItem.tagName.toLowerCase () != 'a') 405 continue; 406 item[1] = currentItem.innerHTML; 407 item[2] = currentItem.href; 408 item[3] = currentItem.target; 409 item[4] = currentItem.title; 410 if (item[4] == '') 411 item[4] = null; 412 break; 413 } 414 415 for (; currentItem; currentItem = currentItem.nextSibling) 416 { 417 // scan for span tag 418 if (!currentItem.tagName || currentItem.tagName.toLowerCase () != 'ul') 419 continue; 420 var subMenuItems = cmDrawFromTextSubMenu (currentItem); 421 for (i = 0; i < subMenuItems.length; ++i) 422 item[i + 5] = subMenuItems[i]; 423 break; 424 } 425 items[items.length] = item; 426 } 427 return items; 428 } 429 430 ////////////////////////////////////////////////////////////////////// 431 // 432 // Mouse Event Handling Functions 433 // 434 ////////////////////////////////////////////////////////////////////// 435 436 // 437 // action should be taken for mouse moving in to the menu item 438 // 439 // Here we just do things concerning this menu item, w/o opening sub menus. 440 // 441 function cmItemMouseOver (obj, prefix, isMain, idSub, index) 442 { 443 clearTimeout (_cmTimeOut); 444 445 if (!obj.cmPrefix) 446 { 447 obj.cmPrefix = prefix; 448 obj.cmIsMain = isMain; 449 } 450 451 var thisMenu = cmGetThisMenu (obj, prefix); 452 453 // insert obj into cmItems if cmItems doesn't have obj 454 if (!thisMenu.cmItems) 455 thisMenu.cmItems = new Array (); 456 var i; 457 for (i = 0; i < thisMenu.cmItems.length; ++i) 458 { 459 if (thisMenu.cmItems[i] == obj) 460 break; 461 } 462 if (i == thisMenu.cmItems.length) 463 { 464 //thisMenu.cmItems.push (obj); 465 thisMenu.cmItems[i] = obj; 466 } 467 468 // hide the previous submenu that is not this branch 469 if (_cmCurrentItem) 470 { 471 // occationally, we get this case when user 472 // move the mouse slowly to the border 473 if (_cmCurrentItem == obj || _cmCurrentItem == thisMenu) 474 { 475 var item = _cmItemList[index]; 476 cmSetStatus (item); 477 return; 478 } 479 480 var thatPrefix = _cmCurrentItem.cmPrefix; 481 var thatMenu = cmGetThisMenu (_cmCurrentItem, thatPrefix); 482 483 if (thatMenu != thisMenu.cmParentMenu) 484 { 485 if (_cmCurrentItem.cmIsMain) 486 _cmCurrentItem.className = thatPrefix + 'MainItem'; 487 else 488 _cmCurrentItem.className = thatPrefix + 'MenuItem'; 489 if (thatMenu.id != idSub) 490 cmHideMenu (thatMenu, thisMenu, thatPrefix); 491 } 492 } 493 494 // okay, set the current menu to this obj 495 _cmCurrentItem = obj; 496 497 // just in case, reset all items in this menu to MenuItem 498 cmResetMenu (thisMenu, prefix); 499 500 var item = _cmItemList[index]; 501 var isDefaultItem = cmIsDefaultItem (item); 502 503 if (isDefaultItem) 504 { 505 if (isMain) 506 obj.className = prefix + 'MainItemHover'; 507 else 508 obj.className = prefix + 'MenuItemHover'; 509 } 510 511 cmSetStatus (item); 512 } 513 514 // 515 // action should be taken for mouse moving in to the menu item 516 // 517 // This function also opens sub menu 518 // 519 function cmItemMouseOverOpenSub (obj, prefix, isMain, idSub, orient, index) 520 { 521 cmItemMouseOver (obj, prefix, isMain, idSub, index); 522 523 if (idSub) 524 { 525 var subMenu = cmGetObject (idSub); 526 cmShowSubMenu (obj, prefix, subMenu, orient); 527 } 528 } 529 530 // 531 // action should be taken for mouse moving out of the menu item 532 // 533 function cmItemMouseOut (obj, delayTime) 534 { 535 if (!delayTime) 536 delayTime = _cmNodeProperties.delay; 537 _cmTimeOut = window.setTimeout ('cmHideMenuTime ()', delayTime); 538 window.defaultStatus = ''; 539 } 540 541 // 542 // action should be taken for mouse button down at a menu item 543 // 544 function cmItemMouseDown (obj, index) 545 { 546 if (cmIsDefaultItem (_cmItemList[index])) 547 { 548 if (obj.cmIsMain) 549 obj.className = obj.cmPrefix + 'MainItemActive'; 550 else 551 obj.className = obj.cmPrefix + 'MenuItemActive'; 552 } 553 } 554 555 // 556 // action should be taken for mouse button down at a menu item 557 // this is one also opens submenu if needed 558 // 559 function cmItemMouseDownOpenSub (obj, index, prefix, orient, idSub) 560 { 561 cmItemMouseDown (obj, index); 562 563 if (idSub) 564 { 565 var subMenu = cmGetObject (idSub); 566 cmShowSubMenu (obj, prefix, subMenu, orient); 567 } 568 } 569 570 // 571 // action should be taken for mouse button up at a menu item 572 // 573 function cmItemMouseUp (obj, index) 574 { 575 var item = _cmItemList[index]; 576 577 var link = null, target = '_self'; 578 579 if (item.length > 2) 580 link = item[2]; 581 if (item.length > 3 && item[3]) 582 target = item[3]; 583 584 if (link != null) 585 { 586 window.open (link, target); 587 } 588 589 var prefix = obj.cmPrefix; 590 var thisMenu = cmGetThisMenu (obj, prefix); 591 592 var hasChild = (item.length > 5); 593 if (!hasChild) 594 { 595 if (cmIsDefaultItem (item)) 596 { 597 if (obj.cmIsMain) 598 obj.className = prefix + 'MainItem'; 599 else 600 obj.className = prefix + 'MenuItem'; 601 } 602 cmHideMenu (thisMenu, null, prefix); 603 } 604 else 605 { 606 if (cmIsDefaultItem (item)) 607 { 608 if (obj.cmIsMain) 609 obj.className = prefix + 'MainItemHover'; 610 else 611 obj.className = prefix + 'MenuItemHover'; 612 } 613 } 614 } 615 616 ////////////////////////////////////////////////////////////////////// 617 // 618 // Mouse Event Support Utility Functions 619 // 620 ////////////////////////////////////////////////////////////////////// 621 622 // 623 // move submenu to the appropriate location 624 // 625 // @param obj the menu item that opens up the subMenu 626 // subMenu the sub menu to be shown 627 // orient the orientation of the subMenu 628 // 629 function cmMoveSubMenu (obj, subMenu, orient) 630 { 631 var mode = String (orient); 632 var p = subMenu.offsetParent; 633 var subMenuWidth = cmGetWidth (subMenu); 634 var horiz = cmGetHorizontalAlign (obj, mode, p, subMenuWidth); 635 if (mode.charAt (0) == 'h') 636 { 637 if (mode.charAt (1) == 'b') 638 subMenu.style.top = (cmGetYAt (obj, p) + cmGetHeight (obj)) + 'px'; 639 else 640 subMenu.style.top = (cmGetYAt (obj, p) - cmGetHeight (subMenu)) + 'px'; 641 if (horiz == 'r') 642 subMenu.style.left = (cmGetXAt (obj, p)) + 'px'; 643 else 644 subMenu.style.left = (cmGetXAt (obj, p) + cmGetWidth (obj) - subMenuWidth) + 'px'; 645 } 646 else 647 { 648 if (horiz == 'r') 649 subMenu.style.left = (cmGetXAt (obj, p) + cmGetWidth (obj)) + 'px'; 650 else 651 subMenu.style.left = (cmGetXAt (obj, p) - subMenuWidth) + 'px'; 652 if (mode.charAt (1) == 'b') 653 subMenu.style.top = (cmGetYAt (obj, p)) + 'px'; 654 else 655 subMenu.style.top = (cmGetYAt (obj, p) + cmGetHeight (obj) - cmGetHeight (subMenu)) + 'px'; 656 } 657 } 658 659 // 660 // automatically re-adjust the menu position based on available screen size. 661 // 662 function cmGetHorizontalAlign (obj, mode, p, subMenuWidth) 663 { 664 var horiz = mode.charAt (2); 665 if (!(document.body)) 666 return horiz; 667 var body = document.body; 668 var browserLeft; 669 var browserRight; 670 if (window.innerWidth) 671 { 672 // DOM window attributes 673 browserLeft = window.pageXOffset; 674 browserRight = window.innerWidth + browserLeft; 675 } 676 else if (body.clientWidth) 677 { 678 // IE attributes 679 browserLeft = body.clientLeft; 680 browserRight = body.clientWidth + browserLeft; 681 } 682 else 683 return horiz; 684 if (mode.charAt (0) == 'h') 685 { 686 if (horiz == 'r' && (cmGetXAt (obj) + subMenuWidth) > browserRight) 687 horiz = 'l'; 688 if (horiz == 'l' && (cmGetXAt (obj) + cmGetWidth (obj) - subMenuWidth) < browserLeft) 689 horiz = 'r'; 690 return horiz; 691 } 692 else 693 { 694 if (horiz == 'r' && (cmGetXAt (obj, p) + cmGetWidth (obj) + subMenuWidth) > browserRight) 695 horiz = 'l'; 696 if (horiz == 'l' && (cmGetXAt (obj, p) - subMenuWidth) < browserLeft) 697 horiz = 'r'; 698 return horiz; 699 } 700 } 701 702 // 703 // show the subMenu w/ specified orientation 704 // also move it to the correct coordinates 705 // 706 // @param obj the menu item that opens up the subMenu 707 // subMenu the sub menu to be shown 708 // orient the orientation of the subMenu 709 // 710 function cmShowSubMenu (obj, prefix, subMenu, orient) 711 { 712 if (!subMenu.cmParentMenu) 713 { 714 // establish the tree w/ back edge 715 var thisMenu = cmGetThisMenu (obj, prefix); 716 subMenu.cmParentMenu = thisMenu; 717 if (!thisMenu.cmSubMenu) 718 thisMenu.cmSubMenu = new Array (); 719 //thisMenu.cmSubMenu.push (subMenu); 720 thisMenu.cmSubMenu[thisMenu.cmSubMenu.length] = subMenu; 721 } 722 723 // position the sub menu 724 cmMoveSubMenu (obj, subMenu, orient); 725 subMenu.style.visibility = 'visible'; 726 727 // 728 // On IE, controls such as SELECT, OBJECT, IFRAME (before 5.5) 729 // are window based controls. So, if the sub menu and these 730 // controls overlap, sub menu would be hidden behind them. Thus 731 // one needs to turn the visibility of these controls off when the 732 // sub menu is showing, and turn their visibility back on 733 // when the sub menu is hiding. 734 // 735 if (document.all) // it is IE 736 { 737 /* part of Felix Zaslavskiy's fix on hiding controls 738 not really sure if this part is necessary, but shouldn't 739 hurt. */ 740 if (!subMenu.cmOverlap) 741 subMenu.cmOverlap = new Array (); 742 /*@cc_on @*/ 743 /*@if (@_jscript_version >= 5.5) 744 @else @*/ 745 cmHideControl ("IFRAME", subMenu); 746 /*@end @*/ 747 cmHideControl ("SELECT", subMenu); 748 cmHideControl ("OBJECT", subMenu); 749 } 750 } 751 752 // 753 // reset all the menu items to class MenuItem in thisMenu 754 // 755 function cmResetMenu (thisMenu, prefix) 756 { 757 if (thisMenu.cmItems) 758 { 759 var i; 760 var str; 761 var items = thisMenu.cmItems; 762 for (i = 0; i < items.length; ++i) 763 { 764 if (items[i].cmIsMain) 765 str = prefix + 'MainItem'; 766 else 767 str = prefix + 'MenuItem'; 768 if (items[i].className != str) 769 items[i].className = str; 770 } 771 } 772 } 773 774 // 775 // called by the timer to hide the menu 776 // 777 function cmHideMenuTime () 778 { 779 if (_cmCurrentItem) 780 { 781 var prefix = _cmCurrentItem.cmPrefix; 782 cmHideMenu (cmGetThisMenu (_cmCurrentItem, prefix), null, prefix); 783 _cmCurrentItem = null; 784 } 785 } 786 787 // 788 // hide thisMenu, children of thisMenu, as well as the ancestor 789 // of thisMenu until currentMenu is encountered. currentMenu 790 // will not be hidden 791 // 792 function cmHideMenu (thisMenu, currentMenu, prefix) 793 { 794 var str = prefix + 'SubMenu'; 795 796 // hide the down stream menus 797 if (thisMenu.cmSubMenu) 798 { 799 var i; 800 for (i = 0; i < thisMenu.cmSubMenu.length; ++i) 801 { 802 cmHideSubMenu (thisMenu.cmSubMenu[i], prefix); 803 } 804 } 805 806 // hide the upstream menus 807 while (thisMenu && thisMenu != currentMenu) 808 { 809 cmResetMenu (thisMenu, prefix); 810 if (thisMenu.className == str) 811 { 812 thisMenu.style.visibility = 'hidden'; 813 cmShowControl (thisMenu); 814 } 815 else 816 break; 817 thisMenu = cmGetThisMenu (thisMenu.cmParentMenu, prefix); 818 } 819 } 820 821 // 822 // hide thisMenu as well as its sub menus if thisMenu is not 823 // already hidden 824 // 825 function cmHideSubMenu (thisMenu, prefix) 826 { 827 if (thisMenu.style.visibility == 'hidden') 828 return; 829 if (thisMenu.cmSubMenu) 830 { 831 var i; 832 for (i = 0; i < thisMenu.cmSubMenu.length; ++i) 833 { 834 cmHideSubMenu (thisMenu.cmSubMenu[i], prefix); 835 } 836 } 837 cmResetMenu (thisMenu, prefix); 838 thisMenu.style.visibility = 'hidden'; 839 cmShowControl (thisMenu); 840 } 841 842 // 843 // hide a control such as IFRAME 844 // 845 function cmHideControl (tagName, subMenu) 846 { 847 var x = cmGetX (subMenu); 848 var y = cmGetY (subMenu); 849 var w = subMenu.offsetWidth; 850 var h = subMenu.offsetHeight; 851 852 var i; 853 for (i = 0; i < document.all.tags(tagName).length; ++i) 854 { 855 var obj = document.all.tags(tagName)[i]; 856 if (!obj || !obj.offsetParent) 857 continue; 858 859 // check if the object and the subMenu overlap 860 861 var ox = cmGetX (obj); 862 var oy = cmGetY (obj); 863 var ow = obj.offsetWidth; 864 var oh = obj.offsetHeight; 865 866 if (ox > (x + w) || (ox + ow) < x) 867 continue; 868 if (oy > (y + h) || (oy + oh) < y) 869 continue; 870 871 // if object is already made hidden by a different 872 // submenu then we dont want to put it on overlap list of 873 // of a submenu a second time. 874 // - bug fixed by Felix Zaslavskiy 875 if(obj.style.visibility == "hidden") 876 continue; 877 878 //subMenu.cmOverlap.push (obj); 879 subMenu.cmOverlap[subMenu.cmOverlap.length] = obj; 880 obj.style.visibility = "hidden"; 881 } 882 } 883 884 // 885 // show the control hidden by the subMenu 886 // 887 function cmShowControl (subMenu) 888 { 889 if (subMenu.cmOverlap) 890 { 891 var i; 892 for (i = 0; i < subMenu.cmOverlap.length; ++i) 893 subMenu.cmOverlap[i].style.visibility = ""; 894 } 895 subMenu.cmOverlap = null; 896 } 897 898 // 899 // returns the main menu or the submenu table where this obj (menu item) 900 // is in 901 // 902 function cmGetThisMenu (obj, prefix) 903 { 904 var str1 = prefix + 'SubMenu'; 905 var str2 = prefix + 'Menu'; 906 while (obj) 907 { 908 if (obj.className == str1 || obj.className == str2) 909 return obj; 910 obj = obj.parentNode; 911 } 912 return null; 913 } 914 915 // 916 // return true if this item is handled using default handlers 917 // 918 function cmIsDefaultItem (item) 919 { 920 if (item == _cmSplit || item[0] == _cmNoAction || item[0] == _cmNoClick) 921 return false; 922 return true; 923 } 924 925 // 926 // returns the object baring the id 927 // 928 function cmGetObject (id) 929 { 930 if (document.all) 931 return document.all[id]; 932 return document.getElementById (id); 933 } 934 935 // 936 // functions that obtain the width of an HTML element. 937 // 938 function cmGetWidth (obj) 939 { 940 var width = obj.offsetWidth; 941 if (width > 0 || !cmIsTRNode (obj)) 942 return width; 943 if (!obj.firstChild) 944 return 0; 945 // use TABLE's length can cause an extra pixel gap 946 //return obj.parentNode.parentNode.offsetWidth; 947 948 // use the left and right child instead 949 return obj.lastChild.offsetLeft - obj.firstChild.offsetLeft + cmGetWidth (obj.lastChild); 950 } 951 952 // 953 // functions that obtain the height of an HTML element. 954 // 955 function cmGetHeight (obj) 956 { 957 var height = obj.offsetHeight; 958 if (height > 0 || !cmIsTRNode (obj)) 959 return height; 960 if (!obj.firstChild) 961 return 0; 962 // use the first child's height 963 return obj.firstChild.offsetHeight; 964 } 965 966 // 967 // functions that obtain the coordinates of an HTML element 968 // 969 function cmGetX (obj) 970 { 971 var x = 0; 972 973 do 974 { 975 x += obj.offsetLeft; 976 obj = obj.offsetParent; 977 } 978 while (obj); 979 return x; 980 } 981 982 function cmGetXAt (obj, elm) 983 { 984 var x = 0; 985 986 while (obj && obj != elm) 987 { 988 x += obj.offsetLeft; 989 obj = obj.offsetParent; 990 } 991 if (obj == elm) 992 return x; 993 return x - cmGetX (elm); 994 } 995 996 function cmGetY (obj) 997 { 998 var y = 0; 999 do 1000 { 1001 y += obj.offsetTop; 1002 obj = obj.offsetParent; 1003 } 1004 while (obj); 1005 return y; 1006 } 1007 1008 function cmIsTRNode (obj) 1009 { 1010 var tagName = obj.tagName; 1011 return tagName == "TR" || tagName == "tr" || tagName == "Tr" || tagName == "tR"; 1012 } 1013 1014 // 1015 // get the Y position of the object. In case of TR element though, 1016 // we attempt to adjust the value. 1017 // 1018 function cmGetYAt (obj, elm) 1019 { 1020 var y = 0; 1021 1022 if (!obj.offsetHeight && cmIsTRNode (obj)) 1023 { 1024 var firstTR = obj.parentNode.firstChild; 1025 obj = obj.firstChild; 1026 y -= firstTR.firstChild.offsetTop; 1027 } 1028 1029 while (obj && obj != elm) 1030 { 1031 y += obj.offsetTop; 1032 obj = obj.offsetParent; 1033 } 1034 1035 if (obj == elm) 1036 return y; 1037 return y - cmGetY (elm); 1038 } 1039 1040 // 1041 // extract description from the menu item and set the status text 1042 // @param item the menu item 1043 // 1044 function cmSetStatus (item) 1045 { 1046 var descript = ''; 1047 if (item.length > 4) 1048 descript = (item[4] != null) ? item[4] : (item[2] ? item[2] : descript); 1049 else if (item.length > 2) 1050 descript = (item[2] ? item[2] : descript); 1051 1052 window.defaultStatus = descript; 1053 } 1054 1055 // 1056 // debug function, ignore :) 1057 // 1058 function cmGetProperties (obj) 1059 { 1060 if (obj == undefined) 1061 return 'undefined'; 1062 if (obj == null) 1063 return 'null'; 1064 1065 var msg = obj + ':\n'; 1066 var i; 1067 for (i in obj) 1068 msg += i + ' = ' + obj[i] + '; '; 1069 return msg; 1070 } 1071 1072 /* v1.4.3 1. changed how _cmSplit is handled a bit so that _cmNoClick can work 1073 properly. All splits in predefined themes are changed to use 1074 _cmNoClick instead of _cmNoAction. 1075 */ 1076 /* v1.4.2 1. fixed _cmNoClick mouse hoover bug. 1077 2. fixed a statusbar text problem that cause text to disappear when 1078 hoovering mouse within the same menu item. 1079 3. changed the behavior of cmDrawFromText s.t. if the title of the 1080 of a link is empty, the actual url is used as text. To clear 1081 this link information, title needs to be ' '. 1082 */ 1083 /* v1.4.1 1. fixed a problem introduced in 1.4 where re-entering a main menu 1084 item which doesn't have a child can disable its hover setting. 1085 Apparently I deleted an extra line of code when I was doing 1086 cleaning up. Reported by David Maliachi and a few others. 1087 */ 1088 /* JSCookMenu v1.4 1. fixed a minor td cell closure problem. Thanks to Georg Lorenz 1089 <georg@lonux.de> for discovering that. 1090 2. added clickOpen to nodeProperties. See _cmNodeProperties for 1091 description. Basically menus can be opened on click only. 1092 3. added an ability to draw menu from an html node instead of a javascript 1093 tree, making this script search bot friendly (I hope?). 1094 */ 1095 /* JSCookMenu v1.31 1. fix a bug on IE with causes submenus to display at the top 1096 left corner due to doctype. The fix was provided by 1097 Burton Strauss <Burton@ntopsupport.com>. 1098 */ 1099 /* JSCookMenu v1.3 1. automatically realign (left and right) the submenu when 1100 client space is not enough. 1101 2. add _cmNoClick to get rid of menu closing behavior 1102 on the particular menu item, to make it possible for things 1103 such as search box to be inside the menu. 1104 */ 1105 /* JSCookMenu v1.25 1. fix Safari positioning issue. The problem is that all TR elements are located 1106 at the top left corner. Thus, need to obtain the "virtual" 1107 position of these element could be at. 1108 */ 1109 /* JSCookMenu v1.24 1. fix window based control hiding bug 1110 thanks to Felix Zaslavskiy <felix@bebinary.com> for the fix. 1111 */ 1112 /* JSCookMenu v1.23 1. correct a position bug when the container is positioned. 1113 thanks to Andre <anders@netspace.net.au> for narrowing down 1114 the problem. 1115 */ 1116 /* JSCookMenu v1.22 1. change Array.push (obj) call to Array[length] = obj. 1117 Suggestion from Dick van der Kaaden <dick@netrex.nl> to 1118 make the script compatible with IE 5.0 1119 2. Changed theme files a little to add z-index: 100 for sub 1120 menus. This change is necessary for Netscape to avoid 1121 a display problem. 1122 3. some changes to the DOM structure to make this menu working 1123 on Netscape 6.0 (tested). The main reason is that NN6 does 1124 not do absolute positioning with tables. Therefore an extra 1125 div layer must be put around the table. 1126 */ 1127 /* JSCookMenu v1.21 1. fixed a bug that didn't add 'px' as part of coordinates. 1128 JSCookMenu should be XHTML validator friendly now. 1129 2. removed unnecessary display attribute and corresponding 1130 theme entry to fix a problem that Netscape sometimes 1131 render Office theme incorrectly 1132 */ 1133 /* JSCookMenu v1.2. 1. fix the problem of showing status in Netscape 1134 2. changed the handler parameters a bit to allow 1135 string literals to be passed to javascript based 1136 links 1137 3. having null in target field would cause the link 1138 to be opened in the current window, but this behavior 1139 could change in the future releases 1140 */ 1141 /* JSCookMenu v1.1. added ability to hide controls in IE to show submenus properly */ 1142 /* JSCookMenu v1.01. cmDraw generates XHTML code */ 1143 /* JSCookMenu v1.0. (c) Copyright 2002 by Heng Yuan */
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
Généré le : Wed Nov 21 14:43:32 2007 | par Balluche grâce à PHPXref 0.7 |
![]() |