似乎无法使用动态生成的元素ID

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了似乎无法使用动态生成的元素ID相关的知识,希望对你有一定的参考价值。

我想创建一个分层付费计算器实用程序。

在我的javascript文件中,我动态地将行和字段添加到我使用html创建的表中,该表来自我在文本输入字段中的名称列表。这些行包含一个名称标签列,一个用于输入总收入的文本输入列和一个计算的付费输出列。

我希望它能够在我对总收入列中的文本输入进行更改时自动更新计算的付费列。虽然我可以跟踪元素ID到calculatePay函数,但我似乎无法使用或设置它们的属性。我觉得他们并不是独一无二的。有任何想法吗?

顺便说一下,你必须立即点击更新按钮来运行Javascript。

编辑 - 根据建议做了一些更改。仍然似乎无法将变量传递给calculatePay函数,只需将它们转过来然后将它们吐回到我表的Pay列中。

编辑 - 已解决。问题是关闭,我起初并不理解,但这里很瘦。为了隔离变量的范围,以便它们不会在每次循环出现时重新编写,它们需要在每次循环迭代重新创建的函数内声明(因为Javascript范围是函数而不是代码块) )。注意事项 - 如果你只是在循环中间声明一个无名函数,这不起作用。您必须将其返回到变量(即var buildElement = function(){Yada Yada}();)。此外,在函数后添加()来执行它。

使用Javascript

function buildTable(){
  var artists = document.getElementById("artlist").value;
  var names = artists.split(",");
  var len = names.length;
  var ptable = document.getElementById("payTable");
  var rowLength = ptable.rows.length;
  for (i=0 ; i < len; i++){
   var buildElement = function(){
     var row = ptable.insertRow(rowLength);
     var nameCell = row.insertCell(0);
     var grossCell = row.insertCell(1);
     var payCell = row.insertCell(2);
     var grossText = document.createElement("input");
     grossText.type = "type";
     grossText.name = "gtext[]";
     grossText.id = "gross" + names[i];
     payCell.id = "pay" + names[i];
     grossText.onchange = function(){calculatePay(payCell.id, grossText.id);};
     grossCell.appendChild(grossText);
     nameCell.innerHTML = names[i];
    }();
  }
}
function resetTable(){
     var ptable = document.getElementById("payTable");
     var rowLength = ptable.rows.length;
     if (rowLength>2){

     for (p=rowLength; p>2; p--){
      ptable.deleteRow(2);
}
}
  buildTable();
}
    function calculatePay(target, gross) {
document.getElementById(target).innerHTML = document.getElementById(gross).value;
        }

HTML

  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <title></title>
    <script src="./js/script.js"></script>
    <link rel="stylesheet" href="./css/style.css" />
  </head>
  <body>
    <div>
      <table id="payTable">
        <tr>
        <th colspan=3 class="hdr">
        Calculator
        </th>
        </tr>
        <tr>
        <th class="hdr">
        Name
        </th>
        <th class="hdr">
        Gross
        </th>
        <th class="hdr">
        Pay
        </th>
        </tr>
      </table>
    </div>

    <div>
      <table>
        <tr>
        <th colspan=3 class="hdr">
        SETTINGS
        </th>
        </tr>
        <tr>
        <th colspan=3 class="hdr">
        Breakpoints
        </th>
        </tr>
        <tr>
        <td>Break 1 at $
        <input type="text" name="break1"   id="break1" value="300"/>
        </td>
        <td>
        </td>
        <td>Break 2 at $
        <input type="text" name="break2" id="break2" value="900"/>
        </td>
        </tr>
        <tr>
        <th colspan=3 class="hdr">
        Percentage levels
        </th>
        </tr>
        <tr>
        <td>
        Below break 1:
        <input type="text" size="4" name="per1" id="per1" value="50"/>%
        </td>
        <td>
        Between breaks 1 and 2:
        <input type="text" size="4" name="per2" id="per2" value="60"/>%
        </td>
        <td>
        Over break 2:
        <input type="text" size="4" name="per3" id="per3" value="70"/>%
        </td>
        </tr>
        <tr>
        <td>
        Artists:
        <input type="text" name="artlist" id="artlist" value="Brian,Eric,Christie,Cynthia,Shawn"/>
        </td>
        <td>
        </td>
        <td class="hdr">
        <button onclick="resetTable()">Update</button>
        </td>
      </tr>

    </div>
  </body>
</html>
答案

问题是关闭,我起初并不理解,但这里很瘦。为了隔离变量的范围,以便它们不会在每次循环出现时重新编写,它们需要在每次循环迭代重新创建的函数内声明(因为javascript范围是函数而不是代码块) )。注意事项 - 如果你只是在循环中间声明一个无名函数,这不起作用。您必须将其返回到变量(即“var buildElement = function(){Yada Yada}();”)。另外,在函数add()之后执行它。

使用Javascript

function buildTable(){
  var artists = document.getElementById("artlist").value;
  var names = artists.split(",");
  var len = names.length;
  var ptable = document.getElementById("payTable");
  var rowLength = ptable.rows.length;
  for (i=0 ; i < len; i++){
   var buildElement = function(){
     var row = ptable.insertRow(rowLength);
     var nameCell = row.insertCell(0);
     var grossCell = row.insertCell(1);
     var payCell = row.insertCell(2);
     var grossText = document.createElement("input");
     grossText.type = "type";
     grossText.name = "gtext[]";
     grossText.id = "gross" + names[i];
     payCell.id = "pay" + names[i];
     grossText.onchange = function(){calculatePay(payCell.id, grossText.id);};
     grossCell.appendChild(grossText);
     nameCell.innerHTML = names[i];
    }();
  }
}
function resetTable(){
     var ptable = document.getElementById("payTable");
     var rowLength = ptable.rows.length;
     if (rowLength>2){

     for (p=rowLength; p>2; p--){
      ptable.deleteRow(2);
}
}
  buildTable();
}
    function calculatePay(target, gross) {
document.getElementById(target).innerHTML = document.getElementById(gross).value;
        }

HTML

  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
        "http://www.w3.org/TR/html4/loose.dtd">
<html>
  <head>
    <title></title>
    <script src="./js/script.js"></script>
    <link rel="stylesheet" href="./css/style.css" />
  </head>
  <body>
    <div>
      <table id="payTable">
        <tr>
        <th colspan=3 class="hdr">
        Calculator
        </th>
        </tr>
        <tr>
        <th class="hdr">
        Name
        </th>
        <th class="hdr">
        Gross
        </th>
        <th class="hdr">
        Pay
        </th>
        </tr>
      </table>
    </div>

    <div>
      <table>
        <tr>
        <th colspan=3 class="hdr">
        SETTINGS
        </th>
        </tr>
        <tr>
        <th colspan=3 class="hdr">
        Breakpoints
        </th>
        </tr>
        <tr>
        <td>Break 1 at $
        <input type="text" name="break1"   id="break1" value="300"/>
        </td>
        <td>
        </td>
        <td>Break 2 at $
        <input type="text" name="break2" id="break2" value="900"/>
        </td>
        </tr>
        <tr>
        <th colspan=3 class="hdr">
        Percentage levels
        </th>
        </tr>
        <tr>
        <td>
        Below break 1:
        <input type="text" size="4" name="per1" id="per1" value="50"/>%
        </td>
        <td>
        Between breaks 1 and 2:
        <input type="text" size="4" name="per2" id="per2" value="60"/>%
        </td>
        <td>
        Over break 2:
        <input type="text" size="4" name="per3" id="per3" value="70"/>%
        </td>
        </tr>
        <tr>
        <td>
        Artists:
        <input type="text" name="artlist" id="artlist" value="Brian,Eric,Christie,Cynthia,Shawn"/>
        </td>
        <td>
        </td>
        <td class="hdr">
        <button onclick="resetTable()">Update</button>
        </td>
      </tr>

    </div>
  </body>
</html>

以上是关于似乎无法使用动态生成的元素ID的主要内容,如果未能解决你的问题,请参考以下文章

如何将我的jQuery插件应用于动态创建的元素

AngularJS 动态元素 ID 和 DOM 访问

OnSaveInstaceState 和动态生成的布局和片段

在 ViewPager 中使用视图创建动态片段

使用 javascript 访问动态生成的 HTML 元素的 id 时获取 null

片段中的按钮自定义视图