为什么我的ChildNodes在JS事件处理程序上返回undefined?

时间:2017-01-05 21:59:42

标签: javascript

我将click处理程序添加到其中一个表元素中。我在检查时确认了它 - >控制台,这是返回我需要的值,地址值。

document.getElementById('donut-attributes').parentNode.childNodes[10].childNodes[1].childNodes[30].innerText 
//returns 123 Some Address on console log

这是主页上的完整脚本:

<script>
window.onload = function(){
  var donutContainer = document.getElementById("donut-attributes");
  donutContainer.addEventListener('click', function(e){
    alert(e.target.parentNode);
    address = e.target.parentNode.childNodes[10].childNodes[1].childNodes[30].innerText;
    alert("donut container after");
    });
  }
</script>

我设置了几个alert()以确保一切正常。当它归结为alert(e.target.parentNode)时,会显示[object HTMLTableRowElement]。但是,当它归结为alert(e.target.parentNode.childNodes[10]);时,它会返回undefined

如何修复点击处理程序,以便在单击任何表格元素时,我会将地址值存储到address中?为什么它在控制台日志中显示地址,当我将其与clickhandler一起使用时显示undefined

编辑:表格html (index.html.erb)看起来像这样:

  <table border=1 class="table table-condensed donut-attributes">
      <tbody class="table-hover">
          <tr>
            <td rowspan=5>
              Some_image
            </td>

              <tr>
                <td class="center" style="vertical-align: middle">Some_name</td>
              </tr>
              <tr>
                <td class="center" style="vertical-align: middle">Some_phone</td>
              </tr>
              <tr>
                <td class="center" style="vertical-align: middle">Some_rating</td>
              </tr>
              <tr>
                <td class="center" style="vertical-align: middle" id="address" >Some_address</td>
              </tr>

                        <tr>
            <td rowspan=5>
              Some_image2
            </td>

              <tr>
                <td class="center" style="vertical-align: middle">Some_name2</td>
              </tr>
              <tr>
                <td class="center" style="vertical-align: middle">Some_phone2</td>
              </tr>
              <tr>
                <td class="center" style="vertical-align: middle">Some_rating2</td>
              </tr>
              <tr>
                <td class="center" style="vertical-align: middle" id="address" >Some_address2</td>
              </tr>
          </tr>
      </tbody>

如何将鼠标悬停在表格行的任何元素上,单击它并获取相应的地址? (例如,如果我将鼠标悬停在第二行的任何列上第二行行,我需要它返回some_address2)

2 个答案:

答案 0 :(得分:1)

<强>更新

现在更新了,它确实完成了OP所需的操作,因此如果点击<tbody>,我们将获得其中的td.address文本。在源头是一个&#34; lynchpin&#34;添加注释以更改extractData()函数,以便它收集所点击的任何内容的文本。详情请参阅代码段代码。

<强>段

&#13;
&#13;
<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1, user-scalable=no">
  <title>00A00</title>
  <style>
    table.X {
      padding: 0;
      box-shadow: 0 1px 9px 1px #ccc;
      border-radius: 6px;
      margin: 20px auto;
    }
    .X th {
      color: #FFF;
      background: #FA768E;
      padding: 10px;
      text-align: center;
      vertical-align: middle;
    }
    .X tr:nth-child(odd) {
      background-color: #FA768E;
      color: #FFF;
    }
    .X tr:nth-child(even) {
      background-color: #D3E9FF;
      color: #F9F;
    }
    .X td {
      border-style: solid;
      border-width: 1px;
      border-color: #FA768E;
      padding: 5px;
      text-align: left;
      vertical-align: top;
    }
    .X thead th:first-child {
      border-top-left-radius: 6px;
    }
    .X thead th:last-child {
      border-top-right-radius: 6px;
    }
    .X tbody tr:first-child td:first-child {
      border-top-left-radius: 6px;
    }
    .X tbody tr:first-child td:last-child {
      border-top-right-radius: 6px;
    }
    .X thead+tbody tr:first-child td:first-child {
      border-top-left-radius: 0;
    }
    .X thead+tbody tr:first-child td:last-child {
      border-top-right-radius: 0;
    }
    .X tbody tr:last-child td:first-child {
      border-bottom-left-radius: 6px;
    }
    .X tbody tr:last-child td:last-child {
      border-bottom-right-radius: 6px;
    }
    .X tbody td.center.center {
      text-align: center;
      padding: 10px;
      vertical-align: middle;
    }
    .X tbody a {
      color: #121;
    }
    .a {
      background: #FEDAE0;
    }
    .rating {
      font-size: 1.5rem;
    }
    .col2 {
      color: #Fed;
      background: #123;
    }
    .X tr:nth-child(even) td.col2 {
      background: #Edf;
      color: #325;
    }
  </style>
</head>

<body>
  <table id="toons" class="table table-condensed X">
    <tbody class="table-hover" data-lvl='1'>
      <tr>
        <td rowspan='5' class='col1'>
          <img src='http://iconshow.me/media/images/ui/app-ui-icon/png/128/donut.png' class: 'thumbnail' style='margin-bottom:50px;'>
          <img src='http://icons.veryicon.com/png/Movie%20%26%20TV/Simpsons%204/Homer%20Simpson%2001%20Donut.png' class='thumbnail' style='width:200px;height:200px;'>
        </td>
      </tr>
      <tr>
        <td class="link center col1"><a href='https://www.facebook.com/HurtsDonutCompany'>Hurt's Donut Company</a>
        </td>
      </tr>
      <tr>
        <td class="phone center col1">417.300.6106</td>
      </tr>
      <tr>
        <td class="rating center col1">&#11088;&#11088;&#11088;&#11088;&#11088;</td>
      </tr>
      <tr>
        <td class="address center col1">320 Park Central W.
          <br>Springfield, Missouri, USA</td>
      </tr>
    </tbody>
    <tbody class="table-hover">
      <tr>
        <td rowspan='5' class='col2'>
          <img src='http://imgh.us/space-donut.gif' class: 'thumbnail' style='margin-bottom:50px;width:200px;'>
          <img src='http://imgh.us/gir_zim.gif' class='thumbnail' style='width:200px;height:200px;'>
        </td>
      </tr>
      <tr>
        <td class="link center col2"><a href='https://training.gov.au/Training/Details/FDFRB3014A'>Fried Yeast Products</a>
        </td>
      </tr>
      <tr>
        <td class="phone center col2">&#43640;&#4175;&#128784;&#128883;</td>
      </tr>
      <tr>
        <td class="rating center col2">&#127758;&#127758;&#127758;&#127758;&#127758;</td>
      </tr>
      <tr>
        <td class="address center col2">WarpGate U812
          <br>Horsehead Nebula, Irk</td>
      </tr>
    </tbody>
  </table>
  <script>
    // Collect and reference every <tbody>
    var T = document.querySelectorAll('tbody');

     // For each <tbody>...
    [].forEach.call(T, function(t, idx) {

      /* When any part of the <tbody> is clicked...
		 	|| ...function extractData() is called
		 	*/
      T[idx].addEventListener('click', extractData, false);

    });

    /* extractData() will pass an event object...
		|| ...and using it's properties to find...
		|| ...event.target (the node that was clicked)...
		|| ...Next we store the event.target in a var...
		|| ...and check to see if it has the class .address...
		|| ...if it doesn't, we will find the <tbody> ...
		|| ...that it belongs to. From there we'll find...
		|| ...td.address and get it's text content...
		|| ...Otherwise if we had clicked the td.address...
		|| ...we'll have the text already.
		*/
    function extractData(event) {
      if (event.target !== event.currentTarget) {
        var dataSource = event.target;

        //* Remove a '/' to get the exact text of each <td>
        if (!dataSource.classList.contains('address')) {
          var grandma = dataSource.closest('tbody');
         console.log(grandma.querySelector('.address').textContent);
        } else //*/
          console.log(dataSource.textContent);

      }
    }
  </script>
</body>

</html>
&#13;
&#13;
&#13;

在标记(HTML)中,每个&#34;主题&#34;在它自己的<tbody>中,这不仅有助于我们更好地组织数据,还有助于DOM横向移植。拥有多个<tbody>也是完全有效的。

答案 1 :(得分:1)

HTML中不允许id属性的重复值,因此您应该使用tdid="address"删除该属性,因为它会重复出现。

识别&#34; last&#34;在组中的行,您可以推断该行的行索引(从零开始)为4,加上5的倍数。或者换句话说,它是4模5。一旦知道行的行索引正在被点击,找到具有这样一个索引的下一行并不困难:

&#13;
&#13;
window.addEventListener('DOMContentLoaded', function(){
  var donutContainer = document.getElementById("donut-attributes");
  donutContainer.addEventListener('click', function(e){
    // Get the clicked element
    var el = e.target;
    // Find row that contains (or is) the clicked element
    while (el.tagName !== 'TR') {
        if (el === this) return; // give up
        el = el.parentNode;
    }
    // Get last row within group of rows
    el = this.rows[el.rowIndex - el.rowIndex % 5 + 4];
    // Get its text
    address = el.cells[0].textContent;
    alert(address);
  });
});
&#13;
table, td {border: 1px solid}
&#13;
<table id="donut-attributes" class="table table-condensed">
  <tbody class="table-hover">
    <tr>
        <td rowspan=5>[image 1]</td>
    </tr>
    <tr>
        <td class="center" style="vertical-align: middle">name1</td>
    </tr>
    <tr>
        <td class="center" style="vertical-align: middle">phone1</td>
    </tr>
    <tr>
        <td class="center" style="vertical-align: middle">rating1</td>
    </tr>
    <tr>
        <td class="center" style="vertical-align: middle">address1</td>
    </tr>
    <tr>
        <td rowspan=5>[image 2]</td>
    </tr>
    <tr>
        <td class="center" style="vertical-align: middle">name2</td>
    </tr>
    <tr>
        <td class="center" style="vertical-align: middle">phone2</td>
    </tr>
    <tr>
        <td class="center" style="vertical-align: middle">rating2</td>
    </tr>
    <tr>
        <td class="center" style="vertical-align: middle">address2</td>
    </tr>
</table>
&#13;
&#13;
&#13;

请注意,如果表中有一个特殊的标题行,或者其他行不符合五分之一模式,则必须相应地调整公式。