게시판 즐겨찾기
편집
드래그 앤 드롭으로
즐겨찾기 아이콘 위치 수정이 가능합니다.
자바스크립트 트리 메뉴 로직 관련 질문드립니다.
게시물ID : programmer_10449짧은주소 복사하기
작성자 : 레이드데이
추천 : 0
조회수 : 1994회
댓글수 : 4개
등록시간 : 2015/05/26 20:00:25
옵션
  • 본인삭제금지
지금 자바스크립트 만 사용하여 트리메뉴를 구성하는 것을 하고 있는데,
 
로직쪽에 문제가 발생하여 아무리 생각해도 타개책이 나질 않아 염치불구하고 이렇게 질문글을 올립니다..
 
현재 트리의 기본적인 기능인 추가,삭제 등의 기능은 구현이 되어 있으나,
 
더블클릭 했을때 메뉴를 펼치거나 접는 Function에서 문제가 생겼습니다.
 
현재
 
        var menus = [
    [1, 0, '회사'],
    [2, 1, '경영지원부'],
    [3, 1, '사업부1'],
    [4, 1, '사업부2'],
    [5, 1, '사업부3'],
    [6, 1, '사업부4'],
    [7, 6, '자식노드1'],
    [8, 6, '자식노드2'],
    [9, 6, '자식노드3'],
    [10, 9, '자식자식노드1'],
    [11, 9, '자식자식노드2'],
    [12, 1, '사업부5'],
//ID, 부모값, 이름
        ];
 
이렇게 있는데,
 
자식노드3를 더블클릭하면, 9번(자식노드3)을 parent로 하는 자식자식노드1과 자식자식노드2는 display가 none으로되어 보이지 않게 됩니다.
그런데 문제는, 이 상태에서 9번(자식노드3)의 parent인 6번(사업부4)를 더블클릭하면, 6번을 부모로 하는 자식노드1, 자식노드2, 자식노드3은 이상없이 접혀지나, display=none처리 되었던 자식자식노드1과 자식자식노드2가 block로 바뀌며 화면에 나타나게 됩니다.
 
해당 기능이 사용되어 문제가 되고 있는 Function은 중앙쯤의 //메뉴 펼치기 접기 function closeMenu(fid)입니다.
 
F12의 개발자 도구로 보시면 아시겠지만 구조가 전부 <ui> <li>가 아닌 전부 <div>형태의 형제 노드로 구성이 되어있다 보니
원하는 결과를 얻기 위해서는 다소 난해한 문제를 해결해야 할 것 같습니다.
 
최상위 부모 노드를 찾아 더블클릭하면 최상위 부모 노드를 제외한 모든 하위 노드의(하위의 하위, 또 그 하위의 하위...) display값이 none, block 여부와 관계없이 전부 다 none처리로 하고 싶습니다.
 
혹시 해당 방법에 대하여 방법이 있다면, 그 방향이라도 제시해 주시면 감사하겠습니다...
 
 
 
 
 
코드는 아래와 같습니다.
 
 
 
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
    <!-- Default 값 -->
    <script type="text/javascript">
        //포커스
        var focusid = null;
    </script>
    <!-- 함수 선언 부분 -->
    <script type="text/javascript">
        // 메뉴 구성
        function makeMenu(id, dep) {
            for (var i = 0, length = menus.length; i < length; i++) {
                var html = "";
                if (id === menus[i][1]) {
                    //노드 세팅 후 도큐먼트에 추가
                    var node = document.createElement('div');
                    node.setAttribute('id', menus[i][0]);
                    node.setAttribute('parent', menus[i][1]);
                    node.setAttribute('onclick', 'getId(' + menus[i][0] + ');' + 'ChangeBackground(' + menus[i][0] + ')');
                    node.setAttribute('ondblclick','closeMenu(' + menus[i][0] + ')');
                    var depthSpace = addDepth(dep);
                    node.appendChild(document.createTextNode(depthSpace + menus[i][2]))
                    document.getElementById('root').appendChild(node);
                    makeMenu(menus[i][0], dep + 1);
                }
            }
            return node;
        }
        //노드 클릭시 index 값 받기
        function getId(id) {
            //alert(id)
            focusid = id;
        }
        //Depth 설정
        function addDepth(depth) {
            var depthSpace = "";
            for (var i = 0; i < depth; i++) {
                depthSpace += "ㅁ";
            }
            return depthSpace;
        }
        //클릭된 노드의 자식 노드 추가(+버튼)
        function addNodes(fid) {
            if (fid === null) {
                alert("하위 메뉴를 추가할 상위 메뉴를 선택해 주세요.");
                return;
            }
            //idArray에 menus의 0번째(id)값을 배열로 삽입
            var idArray = new Array;
            for (var i = 0 ; i < menus.length; i++) {
                idArray[i] = menus[i][0];
            }
            //id값 중 max 값 구하기
            var maxValue = Math.max.apply(null, idArray);
            //텍스트박스의 값
            var txtValue = document.getElementById("txtName")
            if (txtValue.value != "") {
                //menus의 맨 뒤에 새로운 값 추가
                menus.push([maxValue + 1, fid, txtValue.value]);
            }
                //텍스트박스에 값이 없을 경우 예외처리
            else {
                alert("텍스트박스에 값을 입력하세요");
                return;
            }
            //노드 전부 삭제 한 뒤에 새로 생성
            var delNode = document.getElementById("root");
            while (delNode.hasChildNodes()) {
                delNode.removeChild(delNode.firstChild);
            }
            makeMenu(0, 1);
        }

        //클릭된 노드의 삭제(-버튼(수정중)
        function deleteNode(fid) {
            if (fid === 1) {
                alert("디폴트 ID는 삭제할 수 없습니다");
                return;
            }
            for (var i = 0; i < menus.length; i++) {
                if (menus[i][0] === fid) {
                    //id가 focusid인 값 잘라내기
                    menus.splice(i, 1);
                    //부모id가 focusid인 값 잘라내기
                    deleteParentNode(fid);
                }
            }
            //노드를 전부 삭제한 후 새로 생성하기
            var delNode = document.getElementById("root");
            while (delNode.hasChildNodes()) {
                delNode.removeChild(delNode.firstChild);
            }
            makeMenu(0, 1);
        }
        //부모id가 focusid인 값 잘라내기
        function deleteParentNode(pid) {
            for (var i = 0; i < menus.length; i++) {
                if (menus[i][1] === pid) {
                    var id = menus[i][0];
                    menus.splice(i, 1);
                    //parentID를 보내 부모값이 같으면 삭제
                    deleteParentNode(pid);
                    //자기 ID를 parentID로 하는 자식 노드값을 삭제
                    deleteParentNode(id);
                }
            }
        }
        //클릭한 div 색상 변환
        function ChangeBackground(itemID) {
            itemClear();
            var item = document.getElementById(itemID);
            item.className = "menuclick";
        }
        //색상 변환 초기화
        function itemClear() {
            var idArray = new Array;
            for (var i = 0 ; i < menus.length; i++) {
                //id값 이전
                idArray[i] = menus[i][0];
                //이전된 id값 삽입
                document.getElementById(idArray[i]).className = "menudefault";
            }
            idArray = null;
        }
        //메뉴 펼치기 접기
        function closeMenu(fid) {
            for (var i = 0; i < menus.length; i++) {
                if (menus[i][1] === fid) {
                    var id = menus[i][0];
                    if (document.getElementById(id).style.display == 'none') {
                        //if (document.getElementById(fid).style.display == '' || document.getElementById(fid).style.display == 'block') {
                        //    document.getElementById(id).style.display = 'none';
                        //}
                        document.getElementById(id).style.display = 'block';
                    }
                    else if (document.getElementById(id).style.display == 'block' || document.getElementById(id).style.display == '') {
                        //if (document.getElementById(fid).style.display == 'none') {
                        //    document.getElementById(id).style.display = 'none';
                        //}
                        document.getElementById(id).style.display = 'none';
                    }
                    //자식노드의 자식도 숨기기
                    closeMenu(id);
                }
            }
        }
    </script>
    <!-- 실행 부분 -->
    <script type="text/javascript">
        window.onload = function () {
            makeMenu(0, 1);
            //document.getElementById('root').innerHTML += defaultValue;
            //document.getElementById('root').appendChild(node);
        }
        var menus = [
    [1, 0, '회사'],
    [2, 1, '경영지원부'],
    [3, 1, '사업부1'],
    [4, 1, '사업부2'],
    [5, 1, '사업부3'],
    [6, 1, '사업부4'],
    [7, 6, '자식노드1'],
    [8, 6, '자식노드2'],
    [9, 6, '자식노드3'],
    [10, 9, '자식자식노드1'],
    [11, 9, '자식자식노드2'],
    [12, 1, '사업부5'],
        ];
    </script>
    <style type="text/css">
        .depth {
            padding-left: 20px;
        }
        .main {
            border: 1px solid black;
            width: 300px;
        }
        .menuclick {
            background-color: #0099FF;
            font-weight: bold;
        }
        .menudefault {
            background-color: #FFFFFF;
            font-weight: normal;
        }
    </style>
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
    <table>
        <tr>
            <td style="vertical-align:top; width:300px;">
                <div class="main" id="root"></div>
            </td>
            <td style="vertical-align: top; width: 300px;">
                <input type="button" id="btnAdd" onclick="addNodes(focusid)" value="추가" />
                <input type="text" id="txtName" onkeydown="if (event.keyCode == 13)
        {document.getElementById('btnAdd').click(); return false;}" />
                <br />
                <input type="button" id="btnDelete" onclick="deleteNode(focusid)" value="삭제" />
            </td>
        </tr>
    </table>
</asp:Content>
 
감사합니다.
꼬릿말 보기
전체 추천리스트 보기
새로운 댓글이 없습니다.
새로운 댓글 확인하기
글쓰기
◀뒤로가기
PC버전
맨위로▲
공지 운영 자료창고 청소년보호