初学js遇到的一个问题,关于this和event.srcElement,希望高手能给予帮助!~先谢过!
 
在事件响应函数tdGradeonclick()中
 var index = IndexOf(tds,this);
 这里的this换成event.srcElement出现异常,评分只能点击一次,第二次点击次不响应了,在tds数组中查询不到对应event.srcElemnt的td
 代码如下:
     
<head>
     <title>评分</title>
     <script type="text/javascript">
         function IndexOf(arr,element) {//
             for (var i = 0; i < arr.length; i++) {
                 if (arr == element) {
                     return i;//数组中有这个元素,返回元素在数组中的索引号
          }
             }
             return -1;//数组中没有此元素则返回-1
         }
 
        function iniEvent() {//动态添加事件
        var tableGrade = document.getElementById("tableGrade");
             var tds = tableGrade.getElementsByTagName("td"); //获取tableGrade表格中的td单元格数组
        for(var i=0;i<tds.length;i++){
                    tds.onclick=tdGradeonclick;//动态添加td的onclick事件
            tds.style.cursor="pointer";
             }
         }
 
        function tdGradeonclick() {//表中单元格点击事件响应函数
        var tableGrade = document.getElementById("tableGrade");
             var tds = tableGrade.getElementsByTagName("td");
             var index = IndexOf(tds,this);//为什么此处不能用event.srcElement?用event.srcElemnet时点击第二次不响应了,在tds数组中查询不到对应event.srcElement的td,但是第一次点击正常,不解~      
 
            for (var i = 0; i <= index; i++) {
                 tds.innerHTML = "<font color='Yellow'>★</font>";
             }
 
            for (var i = index + 1; i < tds.length; i++) {
                 tds.innerHTML = "☆";
             }
         }
     </script>
 </head>
 <body>
    <table id="tableGrade">
      <tr><td>☆</td><td>☆</td><td>☆</td><td>☆</td><td>☆</td></tr>
    </table>
 </body>
 </html>
通过调试发现,使用event.srcElement,举例:第一次点击第4个星时,event.srcElement的offsetLeft属性为78,offsetWidth属性为23,查询数组匹配成功,但是第二次点击第四颗星时则发现出行问题,此时调用event.srcElement,它的属性中offsetLeft值为1,offsetWidth为21,而获取到的5个td的属性值offsetLeft中,最左边的td的offsetLeft值为2,offsetWidth值为23和第一次点击时一样,未发生变化,两次点击的时事件发生源event.srcElement的属性却是不同,event.srcElement究竟是怎么得到的?做了什么呢?为何不一样?很不解

解决方案 »

  1.   

    首先你上面的代码有问题,虽然我估计是笔误。正确的代码应该是:
    <html>
    <head>
      <title>??</title>
      <script type="text/javascript">
      function IndexOf(arr,element) {//
      for (var i = 0; i < arr.length; i++) {
      if (arr[i] == element) {
      return i;
      }
      }
      return -1;
      }
      
      function initEvent() {
      var tableGrade = document.getElementById("tableGrade");
      var tds = tableGrade.getElementsByTagName("td"); 
      for(var i=0;i<tds.length;i++){
      tds[i].onclick=tdGradeonclick;
      tds[i].style.cursor="pointer";
      }
      }
      
      function tdGradeonclick() {
      var tableGrade = document.getElementById("tableGrade");
      var tds = tableGrade.getElementsByTagName("td");
      var index = IndexOf(tds,this);
     
      for (var i = 0; i <= index; i++) {
          tds[i].innerHTML = "<font color='Yellow'>★</font>";
      }
      
      for (var i = index + 1; i < tds.length; i++) {
          tds[i].innerHTML = "☆";
      }
      }
      </script>
     </head>
     <body onload="initEvent();">
      <table id="tableGrade">
      <tr><td>☆</td><td>☆</td><td>☆</td><td>☆</td><td>☆</td></tr>
      </table>
     </body>
     </html>不过tdGradeonclick里的两个for循环都用了i变量,个人认为是不好的习惯,因为javascript里变量的作用域是整个函数,虽然在这个例子里不出错,但这是不好的习惯,第二个变量改作j较好。再说为什么event.srcElement会出错。原因在于第一次点击后,加上了"<font color='Yellow'>★</font>";这样第二次点击时,event.srcElement就成了这个font元素,而不是tabelCell元素,所以匹配不上了。你可以在chrome下调试一下,很方便。
      

  2.   

    谢谢 hzzasdf的回复,可是在VS中调试,第二次点击第4颗星,拿到的event.srcElement,属性中offsetLeft为1如和解释呢?如果第二次点击时,event.srcElement就成了这个font元素,而不是tabelCell元素,那得到的offsetLeft属性值也不会1吧
      

  3.   

    奥 明白了 因为event.srcElement就成了这个font元素,所以得到的offsetLeft属性值1,是它相对于容器tabelCell元素的位置,也因此得不到匹配,很感谢啊,这个问题及时因为动态添加了
    tds[i].innerHTML = "<font color='Yellow'>★</font>";
    造成的,所以用this,得到的始终是监听onclick事件的tabelCell元素,这样始终得到匹配,谢谢了~结贴