我的javascript提示脚本不起作用.访问和操作DOM



知识水平:入门

我对代码的期望

  1. 用户单击名为open的类
  2. "open"中的textNode将替换为-符号
  3. 然后,我转到该类的父级的第一个子级,即h2标记,并获取标题,以便将其放置在名为"info"的"open"的同级中
  4. 信息终于可见了

三元运算符用于检查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>

请记住,元素之间的空白将成为一个文本节点。因此,最好使用firstElementChildnextElementSibling,而不是firstChildnextSibling

最新更新