<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        JavaScript幾種形式的樹結構菜單_javascript技巧

        來源:懂視網 責編:小采 時間:2020-11-27 20:49:10
        文檔

        JavaScript幾種形式的樹結構菜單_javascript技巧

        JavaScript幾種形式的樹結構菜單_javascript技巧:1.懸浮層樹(Tree) 這種樹結構實現類似面包屑導航功能,監聽的是節點鼠標移動的事件,然后在節點下方或右方顯示子節點,依此遞歸顯示子節點的子節點。 用戶首頁博客設置文章相冊留言評論系統 這里要注意幾個小問題,其一這種樹結構是懸浮層絕對定位的,在創建
        推薦度:
        導讀JavaScript幾種形式的樹結構菜單_javascript技巧:1.懸浮層樹(Tree) 這種樹結構實現類似面包屑導航功能,監聽的是節點鼠標移動的事件,然后在節點下方或右方顯示子節點,依此遞歸顯示子節點的子節點。 用戶首頁博客設置文章相冊留言評論系統 這里要注意幾個小問題,其一這種樹結構是懸浮層絕對定位的,在創建

        1.懸浮層樹(Tree)
        這種樹結構實現類似面包屑導航功能,監聽的是節點鼠標移動的事件,然后在節點下方或右方顯示子節點,依此遞歸顯示子節點的子節點。

        用戶首頁博客設置文章相冊留言評論系統
        這里要注意幾個小問題,其一這種樹結構是懸浮層絕對定位的,在創建層的時候一定要直接放在body的下面,這樣做的是確保在IE里面能遮掩住任何層,因為在IE里面是有stacking context這種東西的潛規則在里面的,另外當然還有一個select你能遮住我嗎?老掉牙的問題,這里是采用在每個懸浮層后面加個iframe元素,當然同一級的菜單只產生一個iframe元素,菜單有幾級將產生幾個iframe遮掩,然后菜單顯示和隱藏的時候同時顯示和隱藏iframe。

        不過這種菜單并不合適前臺,因為目前只支持在腳本里動態添加菜單節點,而不能從現有的html元素獲取菜單節點,我們為了SEO等前臺導航一般是在后臺動態輸出的,假如菜單有多級的話也建議不超過2層,對客戶來說太多層也懶得去看,不過有個面包屑導航顯示還是很不錯的。

        menu.js
        代碼如下:
        /*
        ** Author : Jonllen
        ** Create : 2009-12-13
        ** Update : 2010-05-08
        ** SVN : 152
        ** WebSite: http://www.jonllen.com/
        */
        var Menu = function (container) {
        this.container = container;
        return this;
        }
        Menu.prototype = {
        list : new Array(),
        active : new Array(),
        iframes : new Array(),
        settings : {
        id : null,
        parentId : 0,
        name : null,
        url : null,
        level : 1,
        parent : null,
        children : null,
        css : null,
        element : null
        },
        push : function (item) {
        var list = Object.prototype.toString.apply(item) === '[object Array]' ? item : [item];
        for( var i=0; i< list.length; i++) {
        var settings = list[i];
        for( p in this.settings) {
        if( !settings.hasOwnProperty(p) ) settings[p] = this.settings[p];
        }
        this.list.push(settings);
        }
        return this;
        },
        getChlid : function (id) {
        var list = new Array();
        for( var i=0;i < this.list.length; i++)
        {
        var item = this.list[i];
        if( item.parentId == id)
        {
        list.push(item);
        }
        }
        return list;
        },
        render : function (container) {
        var _this = this;
        var menuElem = container || this.container;
        for( var i=0;i < this.list.length; i++)
        {
        var item = this.list[i];
        if ( item.parentId != 0 ) continue;
        var itemElem = document.createElement('div');
        itemElem.innerHTML = ''+item.name+'';
        itemElem.className = 'item';
        if ( item.css ) itemElem.className += ' '+item.css;
        var disabled = (' '+item.css+' ').indexOf(' disabled ')!=-1;
        if ( disabled ) {
        itemElem.childNodes[0].disabled = true;
        itemElem.childNodes[0].className = 'disabled';
        itemElem.childNodes[0].removeAttribute('href');
        }
        if ( (' '+item.css+' ').indexOf(' hidden ')!=-1 ) {
        itemElem.style.display = 'none';
        }
        itemElem.menu = item;
        itemElem.menu.children = this.getChlid(item.id);
        itemElem.onmouseover = function (e){
        _this.renderChlid(this);
        };
        menuElem.appendChild(itemElem);
        }
        document.onclick = function (e){
        e = window.event || e;
        var target = e.target || e.srcElement;
        if (!target.menu) {
        var self = _this;
        for( var i=1;i<_this.active.length;i++) {
        var item = _this.active[i];
        var menuElem = document.getElementById('menu'+item.id);
        if ( menuElem !=null)
        menuElem.style.display = 'none';
        }
        for(var j=1;j<_this.iframes.length;j++){
        _this.iframes[j].style.display = 'none';
        }
        }
        };
        },
        renderChlid : function (target){
        var self = this;
        var item = target.menu;
        var activeItem = self.active[item.level];
        while(activeItem) {
        var activeItemElem = activeItem.element;
        if ( activeItemElem!= null ) activeItemElem.style.display = 'none';
        activeItem = self.active[activeItem.level + 1];
        }
        self.active[item.level] = item;
        var level = item.level;
        while(this.iframes[level]) {
        this.iframes[level].style.display = 'none';
        level++;
        }
        var childElem = document.getElementById('menu'+item.id);
        if (childElem==null) {
        var hasChild = false;
        for( var j=0;jif( (' '+item.children[j].css+' ').indexOf(' hidden ') == -1) {
        hasChild = true;
        break;
        }
        }
        if( hasChild) {
        var xy = self.elemOffset(target);
        var x = xy.x;
        var y = target.offsetHeight + xy.y;
        if ( item.level >= 2 )
        {
        x += target.offsetWidth - 1;
        y -= target.offsetHeight;
        }
        childElem = document.createElement('div');
        childElem.id = 'menu'+item.id;
        childElem.className = 'child';
        childElem.style.position = 'absolute';
        childElem.style.left = x + 'px';
        childElem.style.top = y + 'px';
        childElem.style.zIndex = 1000 + item.level;
        for( var i=0;i < item.children.length; i++)
        {
        var childItem = item.children[i];
        var childItemElem = document.createElement('a');
        var disabled = (' '+childItem.css+' ').indexOf('disabled')!=-1;
        if ( disabled ) {
        childItemElem.disabled = true;
        childItemElem.className += ' '+childItem.css;
        }else {
        childItemElem.href = childItem.url;
        }
        if ( (' '+childItem.css+' ').indexOf(' hidden ')!=-1 ) {
        childItemElem.style.display = 'none';
        }
        childItemElem.innerHTML = childItem.name;
        childItemElem.menu = childItem;
        childItemElem.menu.children = self.getChlid(childItem.id);
        var hasChild = false;
        for( var j=0;jif( (' '+childItemElem.menu.children[j].css+' ').indexOf(' hidden ') == -1) {
        hasChild = true;
        break;
        }
        }
        if( hasChild ) {
        childItemElem.className += ' hasChild';
        }
        childItemElem.onmouseover = function (e) {
        self.renderChlid(this)
        };
        childElem.appendChild(childItemElem);
        }
        document.body.insertBefore(childElem,document.body.childNodes[0]);
        item.element = childElem;
        }
        }
        if( childElem!=null) {
        var iframeElem = this.iframes[item.level];
        if ( iframeElem == null) {
        iframeElem = document.createElement('iframe');
        iframeElem.scrolling = 'no';
        iframeElem.frameBorder = 0;
        iframeElem.style.cssText = 'position:absolute; overflow:hidden;';
        document.body.insertBefore(iframeElem,document.body.childNodes[0]);
        this.iframes[item.level]=iframeElem;
        }
        childElem.style.display = 'block';
        iframeElem.width = childElem.offsetWidth;
        iframeElem.height = childElem.offsetHeight;
        iframeElem.style.left = parseInt(childElem.style.left) + 'px';
        iframeElem.style.top = parseInt(childElem.style.top) + 'px';
        iframeElem.style.display = 'block';
        }
        },
        elemOffset : function(elem){
        if( elem==null) return {x:0,y:0};
        var t = elem.offsetTop;
        var l = elem.offsetLeft;
        while( elem = elem.offsetParent) {
        t += elem.offsetTop;
        l += elem.offsetLeft;
        }
        return {x : l,y : t};
        }
        };

        演示地址 http://demo.jb51.net/js/tree_json/menu.htm
        打包下載地址

        2.右鍵菜單樹(ContextMenu)
        自定義右鍵菜單(ContextMenu)和懸浮層樹(Tree)其實現上都大同小異,都是在腳本里動態添加節點,然后在生成一個絕對定位層,只不過右鍵菜單樹(ContextMenu)觸發的事件不一樣。另外右鍵菜單還需要提供一個動態添加菜單項功能,以實現右擊不同的元素可以顯示不同的右鍵菜單,我這里提供一種"回調函數",使用見如下代碼:
        ContextMenu回調函數
        代碼如下:
        //ContextMenu
        var contextmenu = new ContextMenu(...{ container : document.getElementById('treemenu') });
        contextmenu.push( ...{ html : 'Powered By: Jonllen', css : 'disabled'});
        contextmenu.push( ...{ html : '', css : 'line'});
        contextmenu.push( ...{ html : '刷新(R)', href : 'javascript:location.reload();'});
        for(var i=0;icontextmenu.push(...{
        id : menu[i].id,
        level : menu[i].level,
        parentId : menu[i].parentId,
        html : menu[i].name,
        href : menu[i].url
        });
        }
        contextmenu.render();
        //原有回調函數
        var contextmenuOnShow = contextmenu.onShow;
        //設置新的回調函數
        contextmenu.onShow = function (target, _this)...{
        var item = target.treemenu || target.parentNode.treemenu;
        if( item ) ...{
        var html = '添加'+item.html+'“子節點'+(item.children.length+1)+'”';
        _this.push( ...{
        html : html,
        click : function (e)...{
        item.expand = false;
        var newItem = ...{
        id : item.id + '0'+ (item.children.length+1),
        level : item.level + 1,
        parentId : item.id,
        html : item.html+'子節點'+(item.children.length+1),
        href : '#',
        css : 'item',
        createExpand : true
        };
        item.children.push(newItem);
        treemenu.list.push(newItem);
        treemenu.renderChild(item);
        },
        clickClose : true,
        index : 1,
        type : 'dynamic'
        });
        _this.push( ...{
        html : '刪除節點“'+item.html+'”',
        click : function (e)...{
        if( confirm('是否確認刪除節點“'+item.html+'”?'))
        treemenu.remove(item);
        },
        clickClose : true,
        index : 2,
        type : 'dynamic'
        });
        }
        contextmenuOnShow(target, _this);
        };

        那么"回調函數"如何來實現呢?其實很簡單,就是函數運行到某一行代碼時運行預先設置的"回調函數",有點像事件機制,如同綁定多個window.onload事件,由于之前可能有綁定函數,所以先記錄之前的函數,再設置新綁定的函數,之后再調用之前綁定的函數。上面的所示代碼實現右擊元素如果為treemenu節點,則在右鍵里添加添加和刪除treemenu節點菜單,效果見后面節點樹(TreeMenu)示例。
        回調函數里我們需要注意作用域,this指針指向當前回調函數對象,而不是在運行回調函數的上下里,不過我們也可以使用call方法來把回調函數在當前this上下文里運行。我這里是采用給回調函數傳遞2個參數的辦法,這樣在回調函數就能很方便的獲取this對象和其他變量,這個在Ajax的Callback回調函數里普遍使用。
        自定義右鍵菜單(ContextMenu)只適合一些輔助功能的快捷操作,如有一些業務功能復雜的OA系統等,下面我也將會結合節點樹(TreeMenu)進行使用。如果可以話盡量不要使用右鍵菜單,其一是需要培訓用戶右擊操作的習慣,其二自定義右鍵菜單丟失掉了原有右鍵菜單的一些功能,如查看源文件等。
        這里右鍵菜單區域。
        右擊我你可以看屬性哦。
        你也可以選擇我再右擊復制。
        你能遮住我嗎?
        ContextMenu.js
        代碼如下:
        /**//*
        ** Author : Jonllen
        ** Create : 2010-05-01
        ** Update : 2010-05-09
        ** SVN : 153
        ** WebSite: http://www.jonllen.com/
        */
        var ContextMenu = function (settings) ...{
        for( p in this.settings)
        ...{
        if( !settings.hasOwnProperty(p) ) settings[p] = this.settings[p];
        }
        this.settings = settings;
        this.settings.menu = document.createElement('div');
        this.settings.menu.className = this.settings.css;
        this.settings.menu.style.cssText = 'position:absolute;display:none;';
        document.body.insertBefore(this.settings.menu,document.body.childNodes[0]);
        return this;
        }
        ContextMenu.prototype = ...{
        list : new Array(),
        active : new Array(),
        iframes : new Array(),
        settings : ...{
        menu : null,
        excursionX : 0,
        excursionY : 0,
        css : 'contextmenu',
        container : null,
        locked : false
        },
        item : ...{
        id : null,
        level : 1,
        parentId : 0,
        html : '',
        title : '',
        href : 'javascript:;',
        target : '_self',
        css : null,
        element : null,
        childElement : null,
        parent : null,
        children : null,
        type : 'static',
        click : null,
        clickClose : false
        },
        push : function (item) ...{
        var list = Object.prototype.toString.apply(item) === '[object Array]' ? item : [item];
        for( var i=0; i< list.length; i++) ...{
        var _item = list[i];
        for( p in this.item) ...{
        if( !_item.hasOwnProperty(p) ) _item[p] = this.item[p];
        }
        _item.element = null;
        if( _item.name ) _item.html = _item.name;
        if( _item.url ) _item.href = _item.url;
        if( _item.type == 'static') ...{
        this.list.push(_item);
        }else ...{
        if(this.dynamic == null) this.dynamic = new Array();
        this.dynamic.push(_item);
        }
        }
        return this;
        },
        bind : function ()...{
        var _this = this;
        for( var i=0; this.dynamic && i...{
        var item = this.dynamic[i];
        var itemElem = document.createElement('div');
        itemElem.title = item.title;
        itemElem.innerHTML = ''+item.html+'';
        itemElem.className = 'item ' + (item.css?' '+item.css:'');
        item.element = itemElem;
        if( item.click ) ...{
        (function (item)...{
        item.element.childNodes[0].onclick = function (e)...{
        if( item.clickClose) _this.hidden();
        return item.click(e);
        };
        })(item);
        }
        itemElem.contextmenu = item;
        itemElem.onmouseover = function (e)...{ _this.hidden(item.level);};
        var index = item.index || 0;
        if( index >= this.settings.menu.childNodes.length)
        index = this.settings.menu.childNodes.length - 1;
        if( index < 0 )
        this.settings.menu.appendChild(itemElem);
        else
        this.settings.menu.insertBefore(itemElem, this.settings.menu.childNodes[index]);
        }
        },
        render : function ( container ) ...{
        var _this = this;
        container = container || this.settings.container;
        this.settings.menu.innerHTML = '';
        for( var i=0;i < this.list.length; i++)
        ...{
        var item = this.list[i];
        if ( item.parentId != 0 ) continue;
        var itemElem = document.createElement('div');
        itemElem.title = item.title;
        itemElem.innerHTML = ''+item.html+'';
        itemElem.className = 'item ' + (item.css?' '+item.css:'');
        var disabled = _this.hasClass(itemElem, 'disabled');
        if ( disabled ) ...{
        itemElem.childNodes[0].disabled = true;
        itemElem.childNodes[0].className = 'disabled';
        itemElem.childNodes[0].removeAttribute('href');
        }
        if ( _this.hasClass(itemElem, 'hidden') ) ...{
        itemElem.style.display = 'none';
        }
        if( item.click ) ...{
        (function (item)...{
        item.element.childNodes[0].onclick = function (e)...{
        if( item.clickClose) _this.hidden();
        return item.click(e);
        };
        })(item);
        }
        itemElem.contextmenu = item;
        itemElem.contextmenu.children = this.getChlid(item.id);
        if( itemElem.contextmenu.children.length > 0 )
        itemElem.childNodes[0].className += ' hasChild';
        itemElem.onmouseover = function (e)...{ _this.renderChlid(this);};
        this.settings.menu.appendChild(itemElem);
        }
        this.active[0] = ...{ element : _this.settings.menu };
        this.settings.menu.contextmenu = _this;
        container.oncontextmenu = function (e)...{
        e = window.event || e;
        var target = e.target || e.srcElement;
        if( e.preventDefault)
        e.preventDefault();
        var mouseCoords = _this.mouseCoords(e);
        _this.settings.menu.style.left = mouseCoords.x + _this.settings.excursionX + 'px';
        _this.settings.menu.style.top = mouseCoords.y + _this.settings.excursionY + 'px';
        _this.hidden();
        _this.show(0, target);
        return false;
        };
        this.addEvent(document, 'click', function (e)...{
        e = window.event || e;
        var target = e.target || e.srcElement;
        var isContextMenu = !!target.contextmenu;
        if( isContextMenu == false) ...{
        var parent = target.parentNode;
        while( parent!=null) ...{
        if( parent.contextmenu) ...{
        isContextMenu = true;
        break;
        }
        parent = parent.parentNode;
        }
        }
        if (isContextMenu == false) ...{
        _this.hidden();
        }
        });
        },
        renderChlid : function ( target )...{
        if(this.settings.locked) return;
        var contextmenu = target.contextmenu;
        var currentLevel = contextmenu.level;
        this.hidden(currentLevel);
        var hasChild = false;
        for( var j=0;jif( (' '+contextmenu.children[j].css+' ').indexOf(' hidden ') == -1) ...{
        hasChild = true;
        break;
        }
        }
        if( !hasChild) return;
        var childElem = contextmenu.element;
        if (childElem == null) ...{
        childElem = document.createElement('div');
        childElem.className = this.settings.css;
        childElem.style.position = 'absolute';
        childElem.style.zIndex = 1000 + contextmenu.level;
        var _this = this;
        for( var i=0;i < contextmenu.children.length; i++)
        ...{
        var childItem = contextmenu.children[i];
        var childItemElem = document.createElement('div');
        childItemElem.title = childItem.title;
        childItemElem.innerHTML = ''+childItem.html+'';
        childItemElem.className = 'item' + (childItem.css?' '+childItem.css : '');
        var disabled = this.hasClass(childItemElem, 'disabled');
        if ( disabled ) ...{
        childItemElem.childNodes[0].disabled = true;
        childItemElem.childNodes[0].removeAttribute('href');
        }
        if ( this.hasClass(childItemElem, 'hidden') ) ...{
        childItemElem.style.display = 'none';
        }
        if( childItem.click ) ...{
        (function (childItem)...{
        childItem.element.childNodes[0].onclick = function (e)...{
        if( childItem.clickClose) _this.hidden();
        return childItem.click(e);
        };
        })(childItem);
        }
        childItem.parent = contextmenu;
        childItemElem.contextmenu = childItem;
        childItemElem.contextmenu.children = this.getChlid(childItem.id);
        var hasChild = false;
        for( var j=0; jif( (' '+childItemElem.contextmenu.children[j].css+' ').indexOf(' hidden ') == -1) ...{
        hasChild = true;
        break;
        }
        }
        if( hasChild ) ...{
        childItemElem.childNodes[0].className += ' hasChild';
        }
        childItemElem.onmouseover = function (e)...{ _this.renderChlid(this);};
        childElem.appendChild(childItemElem);
        }
        document.body.insertBefore(childElem,document.body.childNodes[0]);
        contextmenu.element = childElem;
        }
        this.active[currentLevel] = contextmenu;
        var xy = this.elemOffset(target);
        var x = xy.x + target.offsetWidth + this.settings.excursionX;
        var y = xy.y + this.settings.excursionY;
        childElem.style.left = x + 'px';
        childElem.style.top = y + 'px';
        childElem.style.display = 'block';
        this.show(currentLevel);
        },
        getChlid : function (id) ...{
        var list = new Array();
        for( var i=0;i < this.list.length; i++)
        ...{
        var item = this.list[i];
        if( item.parentId == id)
        ...{
        list.push(item);
        }
        }
        return list;
        },
        show : function (level, target) ...{
        if(this.settings.locked) return;
        level = level || 0;
        var item = this.active[level];
        if ( level == 0 ) ...{
        for( var i=0;this.dynamic && i < this.dynamic.length; i++)
        ...{
        var dynamicItemElem = this.dynamic[i].element;
        if( dynamicItemElem !=null) dynamicItemElem.parentNode.removeChild(dynamicItemElem);
        }
        if (this.dynamic) this.dynamic.length = 0;
        this.onShow(target, this);
        }
        var menuElem = item.element;
        menuElem.style.display = 'block';
        var iframeElem = this.iframes[level];
        if ( iframeElem == null) ...{
        iframeElem = document.createElement('iframe');
        iframeElem.scrolling = 'no';
        iframeElem.frameBorder = 0;
        iframeElem.style.cssText = 'position:absolute; overflow:hidden;';
        document.body.insertBefore(iframeElem,document.body.childNodes[0]);
        this.iframes.push(iframeElem);
        }
        iframeElem.width = menuElem.offsetWidth;
        iframeElem.height = menuElem.offsetHeight;
        var menuElemOffset = this.elemOffset(menuElem);
        iframeElem.style.left = menuElemOffset.x + 'px';
        iframeElem.style.top = menuElemOffset.y + 'px';
        iframeElem.style.display = 'block';
        },
        onShow : function (target, _this) ...{
        if( target.nodeType == 1 && target.tagName == 'A' && target.innerHTML.indexOf('.rar') != -1 )...{
        //解壓文件
        _this.push( ...{
        html : '解壓縮到“'+target.innerHTML.substring(0,target.innerHTML.lastIndexOf('.'))+'\\”...',
        click : function (e)...{
        e = e || window.event;
        var srcElement = e.srcElement || e.target;
        srcElement.className = 'on';
        srcElement.innerHTML = '解壓縮到“'+target.innerHTML.substring(0,target.innerHTML.lastIndexOf('.'))+'\\”...';
        var url = '/Ajax/FileZip.aspx?mode=unzip&files='+target.href.substring(target.href.replace('//','xx').indexOf('/'));
        if( typeof Ajax == 'undefined') return;
        Ajax.get(url, function (data, _this)...{
        _this.settings.locked = true;
        eval(data);
        if( rs.success ) ...{
        location.reload();
        }else...{
        alert(rs.error);
        _this.hidden();
        }
        }, _this);
        srcElement.onclick = null;
        _this.settings.locked = true;
        },
        clickClose : false,
        index : 2,
        type : 'dynamic'
        });
        }
        else if( target.nodeType == 1 && target.title.indexOf('添加到') == 0) ...{
        //添加單個壓縮文件
        _this.push( ...{
        html : target.title,
        title : target.title,
        click : function (e)...{
        var index = target.href.indexOf('?path=');
        if( index != -1)...{
        var fullName = target.href.substring(index+'?path='.length);
        }else ...{
        var fullName = target.href.substring(target.href.replace('//','xx').indexOf('/'));
        }
        e = e || window.event;
        var srcElement = e.srcElement || e.target;
        srcElement.className = 'on';
        srcElement.innerHTML = '正在添加到“'+fullName.substring(fullName.lastIndexOf('/')+1)+'.rar”...';
        var url = '/Ajax/FileZip.aspx?mode=zip&files='+fullName;
        if( typeof Ajax == 'undefined') return;
        Ajax.get(url, function (data, _this)...{
        _this.settings.locked = true;
        eval(data);
        if( rs.success ) ...{
        location.reload();
        }else...{
        alert(rs.error);
        _this.hidden();
        }
        }, _this);
        srcElement.onclick = null;
        _this.settings.locked = true;
        },
        clickClose : false,
        index : 2,
        type : 'dynamic',
        css : 'on'
        });
        }else ...{
        //添加多個壓縮文件
        var fileName = '';
        var files = new Array();
        var ids = document.getElementsByName('ids');
        for( var i=0; iif( !ids[i].checked) continue;
        var file = ids[i].value;
        files.push(file);
        if( files.length == 1) ...{
        fileName = file.substring(file.lastIndexOf('/')+1) + '.rar';
        }
        }
        if( files.length > 0 )...{
        _this.push( ...{
        html : '添加'+files.length+'個文件到壓縮包“'+fileName+'”',
        click : function (e)...{
        e = e || window.event;
        var srcElement = e.srcElement || e.target;
        srcElement.className = 'on';
        srcElement.innerHTML = '正在添加到“'+fileName+'”...';
        var url = '/Ajax/FileZip.aspx?mode=zip&files='+files.join('|');
        if( typeof Ajax == 'undefined') return;
        Ajax.get(url, function (data, _this)...{
        _this.settings.locked = true;
        eval(data);
        if( rs.success ) ...{
        location.reload();
        }else...{
        alert(rs.error);
        _this.hidden();
        }
        }, _this);
        srcElement.onclick = null;
        _this.settings.locked = true;
        },
        clickClose : false,
        index : 2,
        type : 'dynamic'
        });
        }
        }
        if( target.nodeType == 1 && target.tagName == 'A') ...{
        _this.push( ...{
        html : '屬性“'+target.innerHTML+'”',
        href : target.href,
        click : function (e)...{
        prompt('屬性“'+target.innerHTML+'”',target.href);
        return false;
        },
        clickClose : true,
        index : 3,
        type : 'dynamic'
        });
        }
        var selection = window.getSelection ? window.getSelection().toString() : document.selection.createRange().text;
        if( selection ) ...{
        _this.push( ...{
        html : '復制“' + (selection.length > 15 ? selection.substring(0,12) + '...' : selection) +'”',
        title : '復制“' + selection + '”',
        click : function (e) ...{
        if(window.clipboardData) ...{
        window.clipboardData.clearData();
        window.clipboardData.setData("Text", selection);
        }else ...{
        netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
        var clip = Components.classes['@mozilla.org/widget/clipboard;1'].createInstance(Components.interfaces.nsIClipboard);
        var trans = Components.classes['@mozilla.org/widget/transferable;1'].createInstance(Components.interfaces.nsITransferable);
        if (!clip || !trans) return;
        trans.addDataFlavor('text/unicode');
        var len = new Object();
        var str = Components.classes["@mozilla.org/supports-string;1"].createInstance(Components.interfaces.nsISupportsString);
        str.data = selection;
        trans.setTransferData("text/unicode",str,selection.length*2);
        var clipid=Components.interfaces.nsIClipboard;
        if (!clip) return false;
        clip.setData(trans,null,clipid.kGlobalClipboard);
        }
        },
        clickClose : true,
        index : 0,
        type : 'dynamic'
        });
        }
        _this.bind();
        },
        hidden : function (level) ...{
        level = level || 0;
        for( var i = level; ivar item = this.active[i];
        var iframeElem = this.iframes[i];
        if ( iframeElem !=null)
        iframeElem.style.display = 'none';
        if(this.settings.locked) return;
        var menuElem = item.element;
        if ( menuElem !=null)
        menuElem.style.display = 'none';
        }
        this.onHidden(level);
        },
        onHidden : function (level) ...{
        },
        hasClass : function (elem, name)
        ...{
        return !!elem && (' '+elem.className+' ').indexOf(' '+name+' ') != -1;
        },
        elemOffset : function(elem)...{
        var left = 0;
        var top = 0;
        while (elem.offsetParent)...{
        left += elem.offsetLeft;
        top += elem.offsetTop;
        elem = elem.offsetParent;
        }
        left += elem.offsetLeft;
        top += elem.offsetTop;
        return ...{x:left, y:top};
        },
        mouseCoords : function (e)...{
        if (e.pageX && e.pageY) ...{
        return ...{
        x: e.pageX,
        y: e.pageY
        };
        }
        var d = (document.documentElement && document.documentElement.scrollTop) ? document.documentElement : document.body;
        return ...{
        x: e.clientX + d.scrollLeft,
        y: e.clientY + d.scrollTop
        };
        },
        addEvent : function(target,eventType,func)...{
        if(target.attachEvent)
        ...{
        target.attachEvent("on" + eventType, func);
        }else if(target.addEventListener)
        ...{
        target.addEventListener(eventType == 'mousewheel' ? 'DOMMouseScroll' : eventType, func, false);
        }
        return this;
        },
        removeEvent : function(target,eventType,func)...{
        if(target.detachEvent)
        ...{
        target.detachEvent("on" + eventType, func);
        }else if(target.removeEventListener)
        ...{
        target.removeEventListener(eventType == 'mousewheel' ? 'DOMMouseScroll' : eventType, func, false);
        }
        return this;
        }
        }

        演示地址 http://demo.jb51.net/js/tree_json/ContextMenu.htm

        3.節點樹(TreeMenu)
        節點樹(TreeMenu)是我們實際項目中運用得最多了,網上很著名的有梅花雪的MzTreeVew,聽說對大數據量時做了一些優化,效率很高。但我不太喜歡拿來主義,有些東西既然我看不懂或還不明白它為什么要這么做,所以就想嘗試著自己來"造輪子"。當然功能肯定是沒有MzTreeVew的那么強大,大數據量時我也沒有做效率測試,圖片先借MzTreeVew的。

        無限級節點樹

        要實現無限級的功能,如果沒有什么小技巧,好象就只能遞歸了。不過需要注意一定要有個正確條件判斷來return,避免死循環。從數據的存放結構來說,一般我們數據庫里保存有id、name、parentId字段,樹結構里仍然保存這種結構,在展開樹節點的時候我們需要根據id獲取它所有的子節點,并保存起來,避免第二次重復遍歷。

        層次關系結構

        我這里是想說,呈現出來的HTML具有層次關系,每一個樹節點對象有層次關系。HTML層次關系表現為子節點的元素一定是父節點的元素的子節點,本來我覺得這并不是必須的,后來我發現只有這樣做才能保持子子節點的狀態,比如我點擊一級節點只需要展開所有的二級節點,三級或四級節點的狀態不需要改變,HTML結構有這種層次關系支持就很容易實現。與之相對應的是樹節點對象,它保存著父節點對象、子節點集合對象、引用元素等等,以方便遞歸調用,這些信息都被附加到對應的dom元素上。

        帶checkbox和radio選擇

        實際項目的需求都是復雜多變的,有時候我們需要提供radio單選功能,有時候可能需要提供checkbox多選功能,為了能在后臺直接獲取選擇的值,提供帶checkbox和radio選擇功能也是必須的。當然,是否創建checkbox或radio我們可以在實例化時配置指定,每一個節點初始化時是否選中也可設置指定,這里需要注意的是我們直接創建checkbox和radio是不能指定name屬性的,轉個彎換種思路來實現即可。
        代碼如下:
        var inputTemp = document.createElement('div');
        inputTemp.innerHTML = '';
        var inputElem = inputTemp.childNodes[0];

        只綁定一個click事件

        看似較復雜的樹結構,其實我只給最外面的容器元素綁定了一個click事件而已,另外點擊checkbox的聯動也是在這個click事件里處理的,因為元素的事件是會向父元素冒泡觸發的,并且很容易使用事件對象event獲取觸發源元素,因此我就能獲取你點擊是checkbox還是什么其他的元素了,很方便。這樣做的好處就是集中來處理一個事件,而不需要臃腫的給每一個元素添加事件,充分展示代碼的優雅之美。

        演示效果: http://demo.jb51.net/js/tree_json/TreeMenu.htm
        打包下載地址 JavaScript 多種樹結構菜單效果
        本文轉載自金龍博客:http://www.jonllen.com/jonllen/js/menu.aspx,轉載請保留此段聲明。

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        JavaScript幾種形式的樹結構菜單_javascript技巧

        JavaScript幾種形式的樹結構菜單_javascript技巧:1.懸浮層樹(Tree) 這種樹結構實現類似面包屑導航功能,監聽的是節點鼠標移動的事件,然后在節點下方或右方顯示子節點,依此遞歸顯示子節點的子節點。 用戶首頁博客設置文章相冊留言評論系統 這里要注意幾個小問題,其一這種樹結構是懸浮層絕對定位的,在創建
        推薦度:
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 中文有码亚洲制服av片| av无码东京热亚洲男人的天堂| 亚洲欧洲国产精品久久| 91视频免费观看高清观看完整| 亚洲成av人片一区二区三区| 免费精品国自产拍在线播放| 亚洲一区无码精品色| 国产精品一区二区三区免费| 亚洲日本一区二区三区在线| 99精品视频在线视频免费观看| 亚洲综合在线视频| **俄罗斯毛片免费| 久久亚洲国产成人影院| 国产成人青青热久免费精品| 一级一级一片免费高清| 亚洲国产精品无码久久一区二区| 免费黄网站在线观看| 亚洲国产人成在线观看| 日本人护士免费xxxx视频| 一级毛片在播放免费| 亚洲AV无码成人网站久久精品大 | 又粗又大又猛又爽免费视频| 羞羞视频免费网站日本| 亚洲国产精华液网站w| 美丽的姑娘免费观看在线播放| 亚洲欧美熟妇综合久久久久| 亚洲一级片内射网站在线观看| 四虎影视在线影院在线观看免费视频 | 免费精品国产自产拍在| 亚洲爆乳少妇无码激情| 日日噜噜噜噜夜夜爽亚洲精品 | 中文字幕精品亚洲无线码二区| 无码国产精品一区二区免费式芒果 | 黄色网站软件app在线观看免费| 亚洲美女精品视频| 国产精品99久久免费| 永久免费不卡在线观看黄网站| 亚洲高清视频在线| 亚洲免费人成在线视频观看| 91情侣在线精品国产免费| 人成电影网在线观看免费|