js className报错Cannot read property 'className' of undefined

js写了个tab选项卡老报错,求大神指点迷津
html部分:

<!DOCTYPE html>
<html>
<head>
<meta name="description" content="选项卡制作">
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>选项卡</title>
</head>
<body>
<div class="wrap">
  <ul class="panel-title clearfix">
    <li class="item">选项1</li>
    <li class="item">选项2</li>
    <li class="item">选项3</li>
  </ul>
  <div class="panel-content active">选项内容1</div>
  <div class="panel-content ">选项内容2</div>
  <div class="panel-content">选项内容3</div>
  </div>
</body>
</html>

css部分:

div,ul,li{
  padding: 0;
  margin: 0;
}
.clearfix:after{
  content: ' ';
  display: block;
  clear: both;
}
ul,li{
  list-style: none;
}
.panel-title{
  background:#ccc;
  padding: 10px
}
.item{
  float:left;
  margin: 0 10px;
  cursor: pointer;
}
.item.active{
  color:#fff;
}
.panel-content{
  display: none;
  background:#cdc;
  height: 50px;
  padding: 10px;
  border: 1px solid #ccc;
}
.panel-content.active{
  display: block;
}

js部分:

function trim(str){
  var newStr = str.replace(/(^\s*)|(\s*$)/g,'');
  return newStr;
}

function hasClass(ele, cls){
  return !!ele.className.match(new RegExp('\\b' +cls+ '\\b'));
}

function addClass(ele, cls){
  if(!hasClass(ele, cls)){
    ele.className += ' '+cls;
  }
} 

function removeClass(ele, cls){
  if(hasClass(ele, cls)){
    ele.className = ele.className.replace(new RegExp('\\b' +cls+ '\\b'),'');
    return trim(ele.className);
  }
}

function removeAll(els, cls){
  for(var i=0;i<els.length;i++){
    removeClass(els[i], cls);
  }
}
 var titleArr = document.getElementsByClassName("item");
 var ctArr = document.getElementsByClassName("panel-content");
 var ul = document.getElementsByClassName('panel-title')[0];
 ul.onclick = function(e){
  if(hasClass(e.target), "item"){
    var idx = e.target.getAttribute('data-idx');
    removeAll(ctArr, "active");
    addClass(ctArr[idx], "active");
  }
}

报错部分:
图片描述
代码链接:
jsbin演示

阅读 11.5k
3 个回答

1. hasClass(e.target), "item")item写在了括号外

clipboard.png

2. 报错为hasClass方法内部ele获取classname出错,所以肯定是调用hasClass方法传参ele有问题,
你的代码有三处调用了hasClass,可以先将removeAlladdClass注释然后逐一排查,可以发现是addClass的时候出问题了,传的参数是undefined,也就是ctArr[idx]这个参数undefined,再看var idx = e.target.getAttribute('data-idx');,你这个应该是想获取html对应lidata-idx,但是你没写啊,所以取得时候undefined,我加了几行代码,猜测你的想法应该是这样的,然后就不报错了

clipboard.png

3. 你的click方法写的不好,不应该绑定在ul上面,以至于我只要不点在li上,点在li之外的ul上也会报错取不到classname,所以你应该更改click方法到li

ul.onclick = function(e){
  if(hasClass(e.target), "item"){
    var idx = e.target.getAttribute('data-idx');
    removeAll(ctArr, "active");
    addClass(ctArr[idx], "active");
  }
}

上面获取idx为空,然后addClass(ctArr[idx], "active");这里传入的ctArr[idx]为空,然后hasClass报错

var idx = e.target.getAttribute('data-idx');,你HTML中没有定义'data-idx'这个属性,所以idx为null,后面ctArr[idx]也就为undefined,所以报了这个错。
另外, if(hasClass(e.target), "item")这句也有错误,应该是if(hasClass(e.target, "item"))才对吧。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题