知识水平:入门
我对代码的期望:
- 用户单击名为open的类
- "open"中的textNode将替换为-符号
- 然后,我转到该类的父级的第一个子级,即
h2
标记,并获取标题,以便将其放置在名为"info"的"open"的同级中 - 信息终于可见了
三元运算符用于检查firstChild
中是否只有3的nodeType
。如果是,则获取文本,如果不是,则获取整个innerHTML。由于我从getElementsByClassName
获得了一个html集合,所以我倾向于创建一个循环,以便修改样式。
为什么我这样做或不使用jQuery:我正在努力鞭策自己,学习如何在没有第三方库的情况下有效地操纵dom。我很感激关于改进我的代码的提示,但请保持基本结构不变,因为我仍然不喜欢高级捷径,我正在努力学习而不是复制。
问题我不确定我操纵dom的想法有多"正确"。我无法实现这一点,也不知道如何有效地告诉javascript只处理当前单击的元素。
http://jsfiddle.net/r7bL6vLy/28/
function wrapper () {
var open = document.getElementsByClassName(open);
function trigger (){
var info = this.nextSibling;
var getTitle = this.parentNode.firstChild.(nodeType == 3 ? textContent : innerHTML)
this.removeChild(textContent);
this.appendChild(document.createTextNode('-'));
info.appendChild(document.createTextNode(getTitle + 'details'));
info.style.visibility = 'visible';
}
for (i = 0; i < open.length; i++) {
open[i].addEventListener('click', trigger, false);
}
}
HTML
<div id='A'>
<h1>Stackoverflow Question</h1>
<div class='open'>+</div>
<div class='info'>Content A...</div>
</div>
<div id='B'>
<h1>Stackoverflow Question</h1>
<div class='open'>+</div>
<div class='info'>Content B...</div>
</div>
-
this.nextSibling
将为您提供表示元素之间空白的textNode。请改用.this.nextElementSibling
。 -
您不需要进行任何遍历就可以将
+
更改为-
,因为您已经拥有了open
元素。只需为其指定新值。this.textContent = "-";
-
要分配
h2
内容,只需使用.previousElementSibling.textContent
并将其分配给info.textContent
info.textContent = this.previousElementSibling.textContent
你做错了一些事情:
-
此处使用无效语法:
var getTitle = this.parentNode.firstChild.(nodeType == 3 ? textContent : innerHTML)
应该是一个
if
语句,尽管这个条件似乎并不是真正必要的。只要不需要HTML
表示,也可以在元素上使用.textContent
。从技术上讲,你可以这样做:
var child = this.parentNode.firstElementChild; var getTitle = child[child.nodeType === 3 ? "textContent" : "innerHTML"];
但那太难看了。避免这种聪明的把戏。
-
使用
textContent
作为对元素的引用:this.removeChild(textContent);
可以改进的地方:
-
在更改文本时,比起创建新的文本节点,更喜欢操作
.textContent
。现有节点是可变的,因此可以重用。 -
如果要将DOM的一部分复制到新位置,请不要使用
.innerHTML
,而是使用.cloneNode(true)
。var copy = myElem.cloneNode(true); targetElem.appendChild(copy);
否则,您将获取DOM节点,将它们序列化为HTML,然后立即将HTML解析为新节点。所有这些字符串操作都可以简单地通过克隆来避免。
你几乎做到了:
function trigger (){
var info = this.nextElementSibling,
getTitle = this.parentNode.firstElementChild.textContent;
this.textContent = '-';
info.appendChild(document.createTextNode(getTitle + 'details'));
info.style.visibility = 'visible';
}
var open = document.getElementsByClassName('open');
for (i = 0; i < open.length; i++)
open[i].addEventListener('click', trigger, false);
function trigger (){
var info = this.nextElementSibling,
getTitle = this.parentNode.firstElementChild.textContent;
this.textContent = '-';
info.appendChild(document.createTextNode(getTitle + 'details'));
info.style.visibility = 'visible';
}
var open = document.getElementsByClassName('open');
for (i = 0; i < open.length; i++)
open[i].addEventListener('click', trigger, false);
#a, #b {
width:50%;
height:100%;
margin:auto;
}
h1 {
width:100%;
font-size:160%;
text-align:center;
}
.open {
width:22%;
margin:auto;
padding:10% 0;
line-height:0;
font-size:150%;
text-align:center;
font-weight:bold;
background:yellow;
border-radius:100%;
}
.info {
width:100%;
padding:5%;
margin:5% auto 0 auto;
text-align:center;
background:ghostwhite;
visibility:hidden;
}
<div id='A'>
<h1>Stackoverflow Question</h1>
<div class='open'>+</div>
<div class='info'>Content A...</div>
</div>
<div id='B'>
<h1>Stackoverflow Question</h1>
<div class='open'>+</div>
<div class='info'>Content B...</div>
</div>
请记住,元素之间的空白将成为一个文本节点。因此,最好使用firstElementChild
和nextElementSibling
,而不是firstChild
和nextSibling
。