якорный тег с DOM, в то время как событие l oop всегда возвращает последний элемент element.parentNode в таблице - PullRequest
0 голосов
/ 20 апреля 2020

У меня есть таблица, в которой каждая строка содержит тег <a> в первом столбце, к которому было добавлено событие onclick. Событие запускает функцию, которая проверяет первый parentNode, равный <tr> html тег строки.
Функция работает в том, что она всегда находит tr parentNode, но по какой-то причине она всегда находит тег <tr> в последней строке таблицы.

Я не понимаю, почему, поскольку структура таблицы означает, что первый parentNode будет тегом <td>, а затем тегом <tr> текущей строки, из которой происходит событие:

<table>
    <thead>
        <th>Accept</th>
        <th>Value</th>
    </thead>
    <tbody>
        <tr>
            <td>
                <a href="#">Push 1</a>
            </td>
            <td>Val 1</td>
        </tr>
        <tr>
            <td>
                <a href="#">Push 2</a>
            </td>
            <td>Val 2</td>
        </tr>
        <tr>
            <td>
                <a href="#">Push 3</a>
            </td>
            <td>Val 3</td>
       </tr> <!--alway returns the last row-->
    </tbody>
</table>

Я связываю событие onclick при построении таблицы в функции window.onload{buildTable();} , которая работает . Вот фрагмент:


    mycurrent_row = document.createElement("tr");
    // creates a <td> element
    mycurrent_cell = document.createElement("td");
    // create anchor element
    mybut = document.createElement("a");
    // set anchor text
    buttext = document.createTextNode("Push " + key);
    // append text to anchor
    mybut.appendChild(buttext);
    // set href attribute of anchor
    mybut.setAttribute("href", "#");
    // set event to anchor
    mybut.onclick = () => {MYMODCLASS.findParent(mybut, "tr");}
    // appends the Text Node we created into the cell <td>
    mycurrent_cell.appendChild(mybut);

    // find closest parentnode by tagname
    MYMODCLASS.findParent = function (el, tag) {
        while( el && el.tagName && el.tagName !== tag.toUpperCase()) {
            console.log(el.parentNode);
            el = el.parentNode;     
        } return el;
    } 

function builTb(/* element on which to append table */ id, /* new table id */ tablenme, /* set tbody row group names */ trbodyNme, 
    /* set table css class style */ clss, /* key:value pair data object */ dArr, /* header array */ hArr) {
// get the reference for the id element
var mybody = document.getElementById(id);
var head_bool = false;
//create get closest row element function
function getRows(/* set tr group name to search for */ trbodyNme) {
var rows = document.getElementsByName(trbodyNme);
console.log(rows);
}
//count rows within tbody element
function cntRows(/* table id to search rows */ tablenme) {
var col_tbodies = document.getElementById(tablenme).tBodies;
console.log(col_tbodies[0].rows.length);
}
// creates <table> and <tbody> elements
mytable = document.createElement("table");
mytablehead = document.createElement("thead");
mytablebody = document.createElement("tbody");

// creating all cells
for(const [key, value] of Object.entries(dArr)) {// rows
if (!head_bool) {// check if header has been set
// creates a <tr> element
mycurrent_row = document.createElement("tr");
for (let h = 0; h < hArr.length; h++) {// header array
// creates a <th> element
mycurrent_cell = document.createElement("th");
// creates a Text Node
currenttext = document.createTextNode("cell is head row is " + hArr[h] + ", column key " + h);
// appends the Text Node we created into the cell <th>
mycurrent_cell.appendChild(currenttext);
// appends the cell <th> into the row <tr>
mycurrent_row.appendChild(mycurrent_cell);
}
// appends the row <tr> into <thead>
mytablehead.appendChild(mycurrent_row);
head_bool = true;
}
// creates a <tr> element
mycurrent_row = document.createElement("tr");
// row counter
var row_cnt = 0;
for(var k in value) {// columns
if (typeof value[k] !== 'function') {
// check counter in order to add <a> tag in first column
if (row_cnt === 0) {
// creates a <td> element
mycurrent_cell = document.createElement("td");
mybut = document.createElement("a");
buttext = document.createTextNode("Push " + key);
mybut.appendChild(buttext);
mybut.setAttribute("href", "#");
mybut.onclick = () => {findParent(mybut, "tr");}
// appends the Text Node we created into the cell <td>
mycurrent_cell.appendChild(mybut);
// appends the cell <td> into the row <tr>
mycurrent_row.appendChild(mycurrent_cell);
}
// creates a <td> element
mycurrent_cell = document.createElement("td");
// creates a Text Node
currenttext = document.createTextNode("cell is row is " + key + " row value is " + value[k] + ", column key " + k);
// appends the Text Node we created into the cell <td>
mycurrent_cell.appendChild(currenttext);
// appends the cell <td> into the row <tr>
mycurrent_row.appendChild(mycurrent_cell);
// increase counter
row_cnt++;

}
}
//set name of current <tr> row
mycurrent_row.setAttribute("name", trbodyNme);
// appends the row <tr> into <tbody>
mytablebody.appendChild(mycurrent_row);
}
// appends <thead> into <table>
mytable.appendChild(mytablehead);
// appends <tbody> into <table>
mytable.appendChild(mytablebody);
// appends <table> into id element
mybody.appendChild(mytable);
// sets the border attribute of mytable to 2;
mytable.className = clss;
mytable.setAttribute("id", tablenme);
};
// find closest parentnode by tagname
function findParent(el, tag) {
  while (el && el.tagName && el.tagName !== tag.toUpperCase()) {
    console.log(el.parentNode.outerHTML);
    el = el.parentNode;
  }
  return el;
}
var arr = {
                    1: {id: 4, name: "monkey",val: 42, doc: "wer-123456"},
                    2: {id: 5, name: "bear",val: 3, doc: "wer-6086"},
                    3: {id: 8, name: "hippo",val: 102, doc: "wer-65409856"},
                    4: {id: 10, name: "cock",val: 78, doc: "wer-345629"},
                    5: {id: 9, name: "snake",val: 85, doc: "wer-126"},
                    6: {id: 20, name: "goat",val: 75, doc: "wer-965780"},
                    7: {id: 24, name: "elephant",val: 2, doc: "wer-709988"},
                    8: {id: 43, name: "pig",val: 201, doc: "wer-345"},
                    9: {id: 47, name: "cuttle fish",val: 85, doc: "wer-126"},
                    10: {id: 1, name: "squid",val: 75, doc: "wer-965780"},
                    11: {id: 100, name: "otter",val: 2, doc: "wer-709988"},
                    12: {id: 75, name: "sheep",val: 201, doc: "wer-345"}
                }
                var headArr = ["Accept","Id","Name","Number","Document"]
builTb("table-holder", "pricelist-tb", "pricelist-tr", "table-data", arr, headArr);
<body id="table-holder">
</body>

Я могу сделать это легко с jQuery, но не могу в этом проекте. Это должно быть чисто javascript решение.

Может кто-нибудь дать мне понять, почему всегда возвращается родительский узел последней строки?

1 Ответ

1 голос
/ 20 апреля 2020

mybut - это глобальная переменная, хранящая последнее содержимое.

Вы можете использовать это в вызове как элемент, на котором вы находитесь. Но в основном это окно внутри JS кода - если оно не «зашито» в атрибуте события. Или событие - также аргумент функции по умолчанию (arguments [0] - по умолчанию, если вы не указываете список аргументов / обработчиков вашего обработчика событий), есть такие свойства, как currentTarget (элемент, в котором находится ваш обработчик) и srcElement (элемент, по которому вы щелкнули).

Краткий пример из старого кода:

tabEl.innerHTML = "<table onclick=\"tabEdit(event, "+tabName+", '"+elName+"')\"<tr>...

Здесь "Wired" - здесь должен работать табличный объект

function tabEdit(event, tabNm, elName) {
  var param = (function()
  {
    inputChange(event, tabNm, elName)
  });
  inp.onchange = param; /* here it is a local tabEdit variable - when param function
called event can be mouse click when pressing tab */

Мой вопрос может дать вам несколько подсказок IIFE-методы-утечки

Очень простой способ сделать что-то похожее с вашей существующей таблицей c.

document.getElementsByTagName("table")[0].onclick = function () {
  findParent(event.srcElement, "tr");
}
// find closest parentnode by tagname
function findParent(el, tag) {
    while( el && el.tagName && el.tagName !== tag.toUpperCase()) {
        console.log(el.parentNode.outerHTML
          .replace(/[\n\s]{2,}/g, '') // short result a bit
        );
        el = el.parentNode;
    }
    return el;
}
<table>
  <thead>
    <th>Accept</th>
    <th>Value</th>
  </thead>
  <tr><td>
    <a href="#">Push 1</a>
  </td><td>Val 1</td></tr>
  <tr><td>
    <a href="#">Push 2</a>
  </td><td>Val 2</td></tr>
  <tr><td>
    <a href="#">Push 3</a>
  </td><td>Val 3</td></tr>
</table>

А вот DOM Table build с нуля.

// find closest parentnode by tagname
function findParent(el, tag) {
    while( el && el.tagName && el.tagName !== tag.toUpperCase()) {
        console.log(el.parentNode.outerHTML);
        el = el.parentNode;
    }
    return el;
}

function buildTab() {
  var el0 = document.createElement('THEAD');
  var el1 = document.createElement('TH');
  el1.innerText = 'Accept';
  el0.appendChild(el1); // THEAD <- TH
  el1 = document.createElement('TH');
  el1.innerText = 'Value';
  el0.appendChild(el1); // THEAD <- TH
  el1 = document.createElement('TABLE');
  el1.appendChild(el0); // TABLE <- THEAD
  el0 = document.createElement('TBODY');
  el1.appendChild(el0);  // TABLE <- TBODY
  var keys = [1,2,3];
  for(var i in keys) {
    var el2 = document.createElement('TR');
    el0.appendChild(el2); // TBODY <- TR
    var el3 = document.createElement('TD');
    el2.appendChild(el3); // TR <- TD
    var el4 = document.createElement('A');
    el4.href='#';
    el4.innerText = 'Push ' + keys[i];
    el4.onclick = function () { findParent(this, 'TR') }
    el3.appendChild(el4); // TD <- A
    el3 = document.createElement('TD');
    el3.innerText = 'Val ' + keys[i];
    el2.appendChild(el3); // TR <- TD
    el0.appendChild(el2); // TBODY <- TR
  }
  document.body.appendChild(el1); // BODY <- TABLE
}
<body onload="buildTab()">
</body>
...