2017-01-05 4 views
0

私はクリックハンドラをテーブル要素の1つに追加しています。私はinspectでそれを確認しました - >これは私が必要とする値、アドレス値を返すことです。私のChildNodesがJSイベントハンドラで未定義に戻ったのはなぜですか?

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と表示されますか?


EDIT:テーブルの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> 

はどのようにして、テーブルの行の任意の要素の上にカーソルを置く、それをクリックして、対応するアドレスを取得することができますか? (私は置いて、行をクリックした場合、すなわち、2行目のどのの列に、私はそれがsome_address2を返却する必要があります)

、今ではない、まさにOPので更新
+2

'childNodes'には、空白文字のテキストノードと、カウント中の要素間のコメントノードが含まれます。 '.children'を使用して – zer00ne

+0

e.targetとは対照的に、e.currentTargetが必要になるでしょう。それを言って、確かにあなたが望む要素を得る良い方法がある – aw04

+0

あなたは 'address'をテーブルで言うと、戦艦ゲームのような意味ですか?例。列3行8? – zer00ne

答えて

1

id属性の重複値はHTMLでは許可されないため、tdからその属性を削除する必要があります。これは繰り返されるため、id="address"です。

グループの「最後の」行を識別するために、この行に4の行インデックス(ゼロベース)と5の倍数を加えた理由が考えられます。つまり、4を法とした5です。あなたが持っている場合は、その

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); 
 
    }); 
 
});
table, td {border: 1px solid}
<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>

注:あなたがクリックされた行の行インデックスがわかれば、このようなインデックスを持って次の行を見つけることは難しいことではありませんテーブル内の特別なヘッダー行、または複数の5のパターンに従わない他の行の場合、式はそれに応じて適合されなければなりません。

1

UPDATE

<tbody>がクリックされた場合、td.addressのテキストが表示されます。ソースには、extractData()関数を変更するために追加された "lynchpin"コメントがあり、クリックされたもののテキストを収集します。詳細はスニペットのコードでコメントされています。マークアップ(HTML)で

SNIPPET

<!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... 
 
\t \t \t || ...function extractData() is called 
 
\t \t \t */ 
 
     T[idx].addEventListener('click', extractData, false); 
 

 
    }); 
 

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

、それぞれの "件名" は、それ自身の<tbody>である、これはまた、より良いデータを整理するだけでなく、私たちを助けDOMトランスバーサルも容易になります。 <tbody>が複数あることも完全に有効です。

関連する問題