📄 zpmenu-core.js
字号:
// We don't need this any more np.__zp_icons = null; item.className += " zpMenu-item-collapsed"; this.toggleItem(id); if (/(^|\s)selected(\s|$)/i.test(li.className)) { this.selectedItem = item; } subtree = true; } li.removeChild(fc); } else { // Label li.removeChild(fc); if (fc.nodeType == 3) { // Text var label = fc.data.replace(/(^\s+|\s+$)/g, ''); if (label) { var strInnerHtml = label; if (Zapatec.Menu.onDocumentKeyDown && !accessKey) { strInnerHtml = label.replace(/_([a-z0-9])/i, '<span style="text-decoration:underline">$1</span>'); accessKey = RegExp.$1; } var span = Zapatec.Utils.createElement("span", td); // IE 6.0 doesn't escape correctly plain text when it is assigned to // innerHTML property if (strInnerHtml == label) { // Plain text span.appendChild(document.createTextNode(strInnerHtml)); } else { // Contains <span> span.innerHTML = strInnerHtml; } if (title) span.setAttribute('title', title); // To make title work in Opera } } else if (fc.tagName) { // Skip comments, etc. if (fc.tagName.toLowerCase() == 'img') { // Icon this.item_addIcon(item, fc); has_icon = true; if (objContainer.__zp_icons instanceof Array) { objContainer.__zp_icons.push(fc); } } else { // Other stuff if (fc.tagName.toLowerCase() == 'hr') { Zapatec.Utils.addClass(item, "zpMenu-item-hr"); } else if (fc.tagName.toLowerCase() == 'input' && fc.getAttribute('type') == 'checkbox') { fc.onmousedown = function(ev){ if (this.checked) { this.checked = false; } else { this.checked = true; } return Zapatec.Utils.stopEvent(ev); }; } else if (fc.tagName.toLowerCase() == 'input' && fc.getAttribute('type') == 'radio') { fc.onmousedown = function(ev){ this.checked = true; return Zapatec.Utils.stopEvent(ev); }; } else if (fc.tagName.toLowerCase() == 'a') { if (Zapatec.Menu.onDocumentKeyDown && !accessKey) { accessKey = getAccessKey(fc); } // Tab navigation support fc.tabIndex = ++Zapatec.Menu.tabIndex; fc.onfocus = Zapatec.Menu.onItemMouseOver; fc.onblur = Zapatec.Menu.onItemMouseOut; } td.appendChild(fc); if (title && !fc.getAttribute('title')) fc.setAttribute('title', title); // To make title work in Opera } } } } if (accessKey) { accessKey = accessKey.toUpperCase().charCodeAt(0); objContainer.__zp_keymap[accessKey] = item; } if (!has_icon && !/zpMenu-item-hr/i.test(item.className)) // No icons for this non-HR menu item if (this.config.defaultIcons) // Use user config setting defaultIcons className this.item_addDefaultIcon(item, this.config.defaultIcons); else // No icons default className this.item_addDefaultIcon(item, "zpMenu-noicon"); return item;};/** * Aligns captions in the sub-menu. * * @private * @param {object} objSubMenu Sub-menu container */Zapatec.Menu.prototype.alignSubMenu = function(objSubMenu) { // Get icons array var arrIcons = objSubMenu.__zp_icons; var arrIconsSrc = []; for (var iIcon = 0; iIcon < arrIcons.length; iIcon++) { arrIconsSrc.push(arrIcons[iIcon].src); } // Wait while icons are loading var objMenu = this; Zapatec.Transport.preloadImages({ urls: arrIconsSrc, onLoad: function() { // Get max icon width var iMaxIconWidth = 0; for (var iIcon = 0; iIcon < arrIcons.length; iIcon++) { var iIconWidth = arrIcons[iIcon].width; if (iIconWidth && iMaxIconWidth < iIconWidth) { iMaxIconWidth = iIconWidth; } } // Get stylesheet if (!objMenu.styleSheet) { objMenu.styleSheet = new Zapatec.StyleSheet(); } // Set caption width objMenu.styleSheet.addRule('#' + objSubMenu.id + ' .icon div', 'width:' + iMaxIconWidth + 'px'); }, timeout: 60000 // 1 minute });};/** * <pre> * Adds a TD element having a certain class attribute which helps having a tree * containing icons without defining IMG tags for each item. The class name will * be "tgb icon className" (where "className" is the specified parameter). * Further, in order to customize the icons, one should add some CSS lines like * this: * * div.tree-item td.customIcon { * background: url("themes/img/fs/document2.png") no-repeat 0 50%; * } * div.tree-item-expanded td.customIcon { * background: url("themes/img/fs/folder-open.png") no-repeat 0 50%; * } * div.tree-item-collapsed td.customIcon { * background: url("themes/img/fs/folder.png") no-repeat 0 50%; * } * * As you can see, it's very easy to customize the default icons for a normal * tree item (that has no subtrees) or for expanded or collapsed items. For * the above example to work, one has to pass { defaultIcons: "customIcon" } in * the tree configuration object. * * This function does nothing if the className parameter has a false logical * value (i.e. is null). * </pre> * * @private * @param {object} item DIV element holding the item * @param {string} className Additional class name */Zapatec.Menu.prototype.item_addDefaultIcon = function(item, className) { if (!className) { return; } var last_td = item.firstChild.firstChild.firstChild.lastChild, td; var td = Zapatec.Utils.createElement("td"); td.className = "tgb icon " + className; last_td.parentNode.insertBefore(td, last_td); // To be able to set table cell width Zapatec.Utils.createElement('div', td);};/** * If img is passed, adds it as an icon for the given item. If not passed, * creates a "+/-" button for the given item. * * @private * @param {object} item DIV holding the item elements * @param {object} img Optional. IMG element; normally one found in the <LI> */Zapatec.Menu.prototype.item_addIcon = function(item, img) { var last_td = item.firstChild.firstChild.firstChild; var td; last_td = img ? last_td.lastChild : last_td.firstChild; if (!img || !item.__zp_icon) { td = Zapatec.Utils.createElement("td"); td.className = "tgb " + (img ? "icon" : "minus"); last_td.parentNode.insertBefore(td, last_td); } else { td = item.__zp_icon; img.style.display = "none"; } // To be able to set table cell width var objDiv = Zapatec.Utils.createElement('div', td); if (!img) { objDiv.innerHTML = " "; item.className += " zpMenu-item-more"; item.__zp_state = true; // expanded item.__zp_expand = td; } else { objDiv.appendChild(img); item.__zp_icon = td; }};/** * This function gets called from a global event handler when some item was * clicked. It selects the item and toggles it if it has a subtree (expands or * collapses it). * * @param {string} item_id Item ID */Zapatec.Menu.prototype.itemClicked = function(item_id) { this.selectedItem = this.toggleItem(item_id); if (this.selectedItem) { Zapatec.Menu.selectItem(this.selectedItem); } this.onItemSelect(item_id);};/** * This function toggles an item if the state parameter is not specified. * If state is true then it expands the item, and if state is false * then it collapses the item. * * @param {string} item_id Item ID * @param {boolean} state Optional. Desired item state * @return Item element if found, null otherwise * @type object */Zapatec.Menu.prototype.toggleItem = function(item_id, state) { if (!item_id) { return null; } if (this.selectedItem) { Zapatec.Menu.unselectItem(this.selectedItem); } var item = this.items[item_id]; if (typeof state == "undefined") state = !item.__zp_state; if (state != item.__zp_state) { var subtree = this._getTree(item.__zp_subtree, this.creating_now); if (subtree) { if (state) { // Unselect all children for (var i = 0; i < subtree.__zp_items.length; i++) { var subItemID = subtree.__zp_items[i]; Zapatec.Menu.unselectItem(this.items[subItemID]); if (subtree.__zp_activeitem == subItemID) subtree.__zp_activeitem = ''; } } else { // Recursively hide all children for (var i = 0; i < subtree.__zp_items.length; i++) { var subItemID = subtree.__zp_items[i]; this.toggleItem(subItemID, state); Zapatec.Menu.unselectItem(this.items[subItemID]); if (subtree.__zp_activeitem == subItemID) subtree.__zp_activeitem = ''; } } this.treeSetDisplay(subtree, state); Zapatec.Utils.removeClass(item, "zpMenu-item-expanded"); Zapatec.Utils.removeClass(item, "zpMenu-item-collapsed"); Zapatec.Utils.addClass(item, state ? "zpMenu-item-expanded" : "zpMenu-item-collapsed"); } var img = item.__zp_expand; if (img) img.className = "tgb " + (state ? "minus" : "plus"); item.__zp_state = state; if (state) { var hideItems = this._getTree(item.__zp_parent).__zp_items; for (var i = hideItems.length; --i >= 0;) { if (hideItems[i] != item_id && hideItems[i].__zp_state) { this.toggleItem(hideItems[i], false); } } } } return item;};/** * Call this function to collapse all items in the tree. */Zapatec.Menu.prototype.collapseAll = function() { for (var i in this.trees) this.toggleItem(this._getTree(i).__zp_item, false);};/** * Call this function to expand all items in the tree. */Zapatec.Menu.prototype.expandAll = function() { for (var i in this.trees) this.toggleItem(this._getTree(i).__zp_item, true);};/** * Call this function to toggle all items in the tree. */Zapatec.Menu.prototype.toggleAll = function() { for (var i in this.trees) this.toggleItem(this._getTree(i).__zp_item);};/** * Call this function to synchronize the tree to a given item. This means that * all items will be collapsed, except that item and the full path to it. * * @param {string} item_id ID of the item to sync to */Zapatec.Menu.prototype.sync = function(item_id) { var item = this.items[item_id]; if (item) { this.collapseAll(); this.selectedItem = item; var path = []; while (item.__zp_parent) { path[path.length] = item; var parentItem = this._getTree(item.__zp_parent); if (parentItem.__zp_item) { item = this.items[parentItem.__zp_item]; } else { break; } } for (var ii = path.length; --ii >= 0;) { var item = path[ii]; var item_id = item.__zp_item; this.itemShow(item_id); var menu = this._getTree(item.__zp_parent); menu.__zp_activeitem = item_id; Zapatec.Menu.selectItem(item); } }};/** * Highlight specified item and all higher items. * * @param {string} item_id ID of the item */Zapatec.Menu.prototype.highlightPath = function(item_id) { // Put this menu on top this.putOnTop(); // Highlight path var item = this.items[item_id]; if (item) { var a = []; while (item.__zp_parent) { a[a.length] = item; var pt = this._getTree(item.__zp_parent); if (pt.__zp_item) item = this.items[pt.__zp_item]; else break; } for (var i = a.length; --i >= 0;) { Zapatec.Utils.addClass(a[i], 'zpMenuPath'); } }};/** * Destroys the tree. Removes all elements. Does not destroy the Zapatec.Menu * object itself (actually there's no proper way in JavaScript to do that). */Zapatec.Menu.prototype.destroy = function() { var p = this.top_parent; p.parentNode.removeChild(p);};/** * Used when "dynamic initialization" is on. Retrieves a reference to a subtree * if already created, or creates it if it wasn't yet and dont_call is false * (returns null in that case). * * @private * @param {string} tree_id ID of the subtree * @param {boolean} dont_call Pass true here if you don't want the subtree to be * created * @return Reference to the tree if it was found or created, null otherwise * @type object */Zapatec.Menu.prototype._getTree = function(tree_id, dont_call) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -