重新加载Jquery .on事件处理程序

时间:2018-10-03 17:02:26

标签: javascript jquery html

我有一个带有输入的表。用户可以开始输入文字,并且JQuery脚本(https://jqueryui.com/autocomplete/#multiple)会自动完成用户文本。

用户还可以使用简单的JavaScript createElement和innerHTML函数将新输入添加到表中。

当用户添加新输入时,问题就出现了,因为JQuery没有注册新输入,因此它不将事件处理程序附加到自动完成用户文本上

一种可行的解决方案(但我无法使其正常工作)是JQuery .delegate()函数。

编辑(添加的源代码):

https://jsfiddle.net/j8rz7s1q/7/ Can't get the code to format correctly from jsfiddle

3 个答案:

答案 0 :(得分:2)

来自http://api.jquery.com/on/

  

委派的事件处理程序具有可以处理的优点   来自后代元素的事件,这些事件在以下位置添加到文档中   稍后。通过选择在附加委托事件处理程序时可以保证存在的元素,可以使用委托事件来避免频繁附加和删除事件处理程序的需要。

然后,您只需要更改以下示例以匹配您拥有的元素:

$( "#dataTable tbody" ).on( "click", "tr", function() {
  console.log( $( this ).text() );
});

答案 1 :(得分:2)

您需要使用委托事件来处理新添加的元素

类似:

$(document).on("keydown", "tr input", function() {})

答案 2 :(得分:1)

通常,将事件绑定到尚不存在的元素上是通过委派来进行的,在绑定中,您绑定到父元素上,并依赖于绑定后创建的任何子对象上的事件,然后通过冒泡到父元素来工作。可以调用回调。

对于jQuery UI Autocomplete插件,是通过其实现的接口将自动完成功能应用于元素来实现的,该接口对要使用的元素进行自己的绑定。

在这种情况下,要添加新的DOM元素,我们定义一个函数来处理将自动完成功能绑定到传递给它的任何元素,并更新创建新元素的代码,以在创建后调用该函数以应用自动完成绑定。

https://jsfiddle.net/j8rz7s1q/16中对此进行了有效演示,并在此处重复:

<!DOCTYPE html>
<html>

  <head>
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
  </head>

  <body>

    <button onClick="addInputs();" id="button1">Add input</button>
    <p>
      The first input works. The autocomplete works completely but when you add new inputs the new inputs doesn't register to the event handler.
    </p>
    <div>

      <div class="LightBox-box-content">
        <table>
          <tbody class="addInput">
            <tr>
              <td>
                <input type="text" class="input1">
              </td>
            </tr>
          </tbody>
        </table>
      </div>

    </div>

    <script>
      $(function() {
        var availableTags = [
          "Yes", "No",
        ];

        function split(val) {
          return val.split(/,\s*/);
        }

        function extractLast(term) {
          return split(term).pop();
        }

        window.setupAutocomplete = function($obj) {
          return $obj
            // don't navigate away from the field on tab when selecting an item
            .on("keydown", function(event) {
              if (event.keyCode === $.ui.keyCode.TAB &&
                $(this).autocomplete("instance").menu.active) {
                event.preventDefault();
              }
            })
            .autocomplete({
              minLength: 0,
              source: function(request, response) {
                // delegate back to autocomplete, but extract the last term
                response($.ui.autocomplete.filter(
                  availableTags, extractLast(request.term)));
              },
              focus: function() {
                // prevent value inserted on focus
                return false;
              },
              select: function(event, ui) {
                var terms = split(this.value);
                // remove the current input
                terms.pop();
                // add the selected item
                terms.push(ui.item.value);
                // add placeholder to get the comma-and-space at the end
                terms.push("");
                this.value = terms.join("");


                return false;
              }
            });
        };
        
        setupAutocomplete($(".input1"));
      });

    </script>

    <script>
      function addInputs() {
        var div = document.createElement('tr');
        div.innerHTML = '<tr>\
  <td>\
      <input type="text" class="input1">\
  </td>\
  </tr>';
  
  			setupAutocomplete($('input', div));
  
        document.getElementsByClassName('addInput')[0].appendChild(div);
      }

    </script>

  </body>

</html>