jquery和id选择器问题

时间:2017-08-25 18:37:40

标签: javascript jquery html random

我需要为页面上创建的某些按钮生成随机ID。我使用这个jquery创建按钮:

var btnId = 'delete-' + row.id;
$("<button/>", {
    'id': btnId,
    'html': $("<i></i>").addClass("ion-icon ion-btn ion-trash-a"),
    'class': 'btn btn-primary btn-md'
}).append(' Delete')

按钮ID的模板:

delete-$UUID,其中从数据库中检索$UUID

这很好用,在创建之后,我甚至可以使用jquery为每个按钮附加一个点击监听器:

$('button#' + btnId).click(function(e) { alert("Button clicked!"); });

情节变粗

现在,我决定不使用数据库行id,而是生成一个随机字符串用作按钮ID,所以我创建了这个函数:

function _randomString (min, max) {
    var text = "";
    var length = Math.floor(Math.random() * (max - min) + min);
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghijklmnopqrstuvwxyz0123456789";
    for (var i = 0; i < length; i++) {
        text += possible.charAt(Math.floor(Math.random() * possible.length));
    }
    return text;
}

,然后替换了像这样的按钮ID

var btnId = 'delete-' + _randomString(20, 30);

正如您所看到的,唯一不同的是$UUID被我创建的此函数的值替换。

高潮

现在当我使用jquery添加一个点击监听器(与上面相同的jquery)时,绑定停止了jquery。无论发生什么事情,jquery似乎都不想在使用这样的id创建时找到并将click侦听器绑定到按钮。

起初,我认为这可能是由于函数没有生成随机字符串,但我去了控制台,我使用了其中一个按钮生成的id,当我做$('copied-button-id').length时,我得到了1。很明显,jquery能够找到按钮 now ,但不是在创建按钮时,就像我使用数据库行id来创建按钮ID一样。

更奇怪的是,当我删除随机生成的字符串并将其替换为像sdfsdfsd这样的普通字符串时,即现在所有按钮都具有标识delete-sdfsdfsd,jquery找到并绑定到没有问题按钮。

在有人要求之前,我还仔细阅读了html元素的可接受ID,所以这不是问题。 What are valid values for the id attribute in HTML?

分辨率

这是我需要你帮助的地方。我想我真的很累或者其他什么,但你能看看我的功能并告诉我可能导致这个问题的原因。我已经消除了长度问题,因为我已经能够使用长度超过60个字符的ID并且它们都有效。 JQuery是否能够找到(或不找到)以这种方式创建的任何按钮,从而表现出未定义的行为?我是否表现出不确定的行为?我错过了什么?

欢迎任何帮助!

JQuery版本:2.1.4

MCVE:

&#13;
&#13;
$(function() {
  var numRows = 10;
  var $table = $('#db-table');
  for (var i = 0; i < numRows; i++) {
    $table.find('tbody').append("<tr/>");
    var name = _randomString(5, 10);
    var age = Math.floor(Math.random() * 25 + 5);
    var $row = $table.find('tbody tr:eq(' + i + ')');
    $row.append($("<td/>", {
      html: "<span>" + name + "</span>"
    })).append($("<td/>", {
      html: "<span>" + age + "</span>"
    })).append(_getButton({
      id: _randomString(20, 30)
    }));
  }
});

function _randomString(min, max) {
  var text = "";
  var length = Math.floor(Math.random() * (max - min) + min);
  var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghijklmnopqrstuvwxyz0123456789";
  for (var i = 0; i < length; i++) {
    text += possible.charAt(Math.floor(Math.random() * possible.length));
  }
  return text;
}

function _getButton(row) {
  var btnId = 'delete-' + row.id;
  var $btn = $("<button/>", {
    'id': btnId,
    'html': $("<i></i>").addClass("ion-icon ion-btn ion-trash-a"),
    'class': 'btn btn-primary btn-md'
  }).append(' Delete');

  $('button#' + btnId).click(function(e) {
    alert("You clicked a button!!");
  });

  return $btn.prop('outerHTML');
}
&#13;
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<div class="container">
  <div class="row">
    <table id="db-table" class="table-responsive">
      <thead>
        <tr>
          <th>Name</th>
          <th>Age</th>
          <th>Actions</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
  </div>
</div>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

根本不需要使用ID。只需使用CSS类,将click事件绑定到该类的所有按钮,如果您需要对与该按钮关联的行或数据执行特定操作,请在元素上使用html5 data标记,或者只使用$(this).find(...)$(this).closest(...)获取单击按钮时所需的任何信息。

同样,这里没有100%清楚用例,但仅仅是为了举例,假设你的按钮类是awesome-button

// Using $(document).on('click') instead of just
// $('.awesome-button').click() since you seem to be dynamically creating buttons.

$(document).on('click', '.awesome-button', function() {
  var row = $(this).closest('tr');

  // Now do whatever you want with the row...
  row.find('.something-obscure');

  // Or maybe your rows have data tags on them that need to go somewhere?
  someCrazyFunction(row.data('example'));

  // etc...
});

答案 1 :(得分:1)

您正在使用$("button#' + btnId)功能中的选择器_getButton()。但是该按钮不会附加到DOM,直到该函数返回并且按钮被传递给$row.append()

相反,只需绑定到元素本身,而不是使用选择器。 _getButton()需要返回元素本身,而不是outerHTML,因为这会丢失事件绑定。

&#13;
&#13;
$(function() {
  var numRows = 10;
  var $table = $('#db-table');
  for (var i = 0; i < numRows; i++) {
    $table.find('tbody').append("<tr/>");
    var name = _randomString(5, 10);
    var age = Math.floor(Math.random() * 25 + 5);
    var $row = $table.find('tbody tr:eq(' + i + ')');
    $row.append($("<td/>", {
      html: "<span>" + name + "</span>"
    })).append($("<td/>", {
      html: "<span>" + age + "</span>"
    })).append(_getButton({
      id: _randomString(20, 30)
    }));
  }
});

function _randomString(min, max) {
  var text = "";
  var length = Math.floor(Math.random() * (max - min) + min);
  var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZ-abcdefghijklmnopqrstuvwxyz0123456789";
  for (var i = 0; i < length; i++) {
    text += possible.charAt(Math.floor(Math.random() * possible.length));
  }
  return text;
}

function _getButton(row) {
  var btnId = 'delete-' + row.id;
  var $btn = $("<button/>", {
    'id': btnId,
    'html': $("<i></i>").addClass("ion-icon ion-btn ion-trash-a"),
    'class': 'btn btn-primary btn-md'
  }).append(' Delete');

  $btn.click(function(e) {
    alert("You clicked a button!!");
  });

  return $btn;
}
&#13;
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
<div class="container">
  <div class="row">
    <table id="db-table" class="table-responsive">
      <thead>
        <tr>
          <th>Name</th>
          <th>Age</th>
          <th>Actions</th>
        </tr>
      </thead>
      <tbody></tbody>
    </table>
  </div>
</div>
&#13;
&#13;
&#13;