如何使用纯javascript创建嵌套的树打开/关闭按钮
我有下面的html结构。当有人单击“switch”div时,我想向content div和branch添加一个hide类。当再次单击时,我想删除它们。我可以编写click事件,但我不知道如何引用click事件中的嵌套内容和分支如何使用纯javascript创建嵌套的树打开/关闭按钮,javascript,Javascript,我有下面的html结构。当有人单击“switch”div时,我想向content div和branch添加一个hide类。当再次单击时,我想删除它们。我可以编写click事件,但我不知道如何引用click事件中的嵌套内容和分支 <ul id="tree"> <li class="leaf"> <div class="switch"></div> <div class="content">
<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>
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", "");
}
});
-
... 东西
-
... 东西
-
... 东西
-
... 东西
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();
}
var库=(函数(){
“严格使用”;
/**
*为传入的所有类创建单击事件。
*
*这是由具有GetElementsByCassName的较新浏览器使用的。
*
*@param{array}class_命名要附加到click事件的类名。
*@param{function}处理单击事件的回调。
*
*@返回无效
*/
变量classNameClick=函数(类名称,clickEvent){
对于(var i=0;i=0{
element.onclick=function(){
clickEvent();
}
}
}
}
};
返回{
/**
*循环遍历所有DOM元素以查找要附加的类,单击事件。
*
*@param{array}class_命名要附加到click事件的类名。
*@param{function}处理单击事件的回调。
*
*@返回无效
*/
classClick:函数(类名称,clickEvent){
if(typeof document.getElementsByClassName!=“未定义”){
类名称单击(类名称,单击事件);
}否则{
classTagClick(类名称,clickEvent);
}
}
};
}());
变量树=(函数(){
“严格使用”;
返回{
构造:函数(){
classClick(“开关”,函数(){
//不确定如何在此处引用相关内容和分支类。
});
}
};
}());
window.onload=函数(){
Tree.construct();
}
我不能使用jQuery或其他库(使用jQuery很容易)。我通过在两个类单击事件中添加以下内容解决了这个问题
element.onclick = function() {
clickEvent.apply(this);
}
这将使用单击的dom元素替换单击事件函数中的This对象
然后,我将以下内容添加到click事件中
<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>
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{
显示:无;
}sidenote:我会将类添加到父li,而不是特定的子节点(兄弟节点)。这样,您将只有一个位置来切换类(例如,
节点。parentNode
)。@Yoshi将隐藏开关,并且它将无法再次打开。内容和分支节点可以嵌套在单个div中,以提高代码的效率。为什么li.open>.branch{display:block}
(例如)将保持开关未动。这样你甚至可以根据州来设计开关。@Yoshi啊,对了,我现在明白了。是的,这将使定位分支和内容更容易,而无需额外的节点。我会加上一个。