0

次のhtml構造があります。誰かが "switch" div をクリックすると、コンテンツ div とブランチ ul 兄弟に非表示クラスを追加したいと考えています。もう一度クリックすると、それらを削除したいと思います。クリックイベントは書けるのですが、入れ子になったコンテンツを参照してクリックイベントから分岐する方法がわかりません。

<ul id="tree">
    <li class="leaf">
        <div class="switch"></div>
        <div class="content">
            ... stuff
        </div>
        <ul class="branch">
            <li class="leaf">
                <div class="switch"></div>
                <div class="content">
                    ... stuff
                </div>
                <ul class="branch">
                    <!-- Can be many layers deep -->
                </ul>
            </li>
        </ul>
    </li>
    <li class="leaf">
        <div class="switch"></div>
        <div class="content">
            ... stuff
        </div>
        <ul class="branch">
            <li class="leaf">
                <div class="switch"></div>
                <div class="content">
                    ... stuff
                </div>
                <ul class="branch">
                    <!-- Can be many layers deep -->
                </ul>
            </li>
        </ul>
    </li>
    <!-- Can be many more of these -->
</ul>

Javascript

var Library = (function () {
    "use strict";


    /**
     * Create click events for all classes passed in.
     *
     * This is used by newer browsers that have getElementsByClassName.
     *
     * @param {array} class_names The class names to attatch click events to.
     * @param {function} The callback to handle the click event.
     *
     * @return void
     */
    var classNameClick = function(class_names, clickEvent) {
        for(var i = 0; i < class_names.length; i++) {
            var elements = document.getElementsByClassName(class_names[i]);
            for(var j = 0; j < elements.length; j++) {
                elements[j].onclick = clickEvent;
            }
        }
    };

    /**
     * Loops through all DOM elements to find classes to attatch click events to.
     *
     * This is used by older browsers that don't have getElementsByClassName
     *
     * @param {array} class_names The class names to attatch click events to.
     * @param {function} The callback to handle the click event.
     *
     * @return void
     */
    var classTagClick = function(class_names, clickEvent) {
        var elements = document.getElementsByTagName("*");
        for(var i = 0; i < elements.length; i++) {
            var element = elements[i];
            for(var j = 0; j < class_names.length; j++) {
                if(element.className.indexOf(class_names[j]) >= 0) {
                    element.onclick = function() {
                        clickEvent();
                    }
                }
            }
        }
    };

    return {

        /**
         * Loops through all DOM elements to find classes to attatch click events to.
         *
         * @param {array} class_names The class names to attatch click events to.
         * @param {function} The callback to handle the click event.
         *
         * @return void
         */
        classClick : function(class_names, clickEvent) {
            if (typeof document.getElementsByClassName !== "undefined") {
                classNameClick(class_names, clickEvent);
            } else {
                classTagClick(class_names, clickEvent);
            }
        }

    };
}());

var Tree = (function () {
    "use strict";

    return {

        construct : function () {

            Library.classClick("switch", function() {
                // Not sure how to reference the relevant content and branch class here.
            });

        }
    };
}());

window.onload = function() {
    Tree.construct();
}

jQueryや他のライブラリが使えない(jQueryなら簡単)。

4

1 に答える 1

1

2 つのクラスのクリック イベントに以下を追加して、これを解決しました。

element.onclick = function() {
    clickEvent.apply(this);
}

これにより、クリック イベント関数の this オブジェクトが、クリックされた dom 要素に置き換えられます。

次に、クリックイベントに次を追加しました。

Library.classClick(["switch"], function() {
    var leaf_node = this.parentNode;
    var parent_class = leaf_node.className;
    if (parent_class.indexOf(" closed") === -1) {
        leaf_node.className += " closed";
    } else {
        leaf_node.className = leaf_node.className.replace(" closed", "");
    }
});

最後に以下のcssを追加

li.leaf.closed > .content, li.leaf.closed > .branch { 表示: なし; }

于 2012-07-11T10:26:46.040 に答える