【问题标题】:Avoid binding multiple events on element避免在元素上绑定多个事件
【发布时间】:2019-02-15 08:56:40
【问题描述】:

我正在通过 ajax 在我的 .net 项目中获取 cshtml,在成功将数据绑定到 dom 后,使用导出到 excel 功能在其上初始化数据表,

但是当您多次获取数据时(用户使用文件管理器),数据表每次都会绑定(附加)事件到导出按钮,并且用户最终会一次下载多个 Excel 文件。

我已经用datagetCSHTML 方法复制了cshtmlajax 方法。

重现问题的步骤。

  1. 点击获取数据按钮。
  2. 点击导出数据按钮(只会下载一个文件)。
  3. 回到第1步和第2步,在不刷新浏览器选项卡的情况下重复此操作,最终会一键下载多个excel文件。

我试过.off().unbind().bind(),但没有帮助。

var data = '<table id="example"><thead><tr><th>Name</th><th>Position</th><th>Office</th><th>Age</th><th>Start date</th></tr></thead><tbody><tr><td>Airi Satou</td><td>Accountant</td><td>Tokyo</td><td>33</td><td>2008/11/28</td></tr><tr><td>Angelica Ramos</td><td>Chief Executive Officer (CEO)</td><td>London</td><td>47</td><td>2009/10/09</td></tr><tr><td>Ashton Cox</td><td>Junior Technical Author</td><td>San Francisco</td><td>66</td><td>2009/01/12</td></tr><tr><td>Bradley Greer</td><td>Software Engineer</td><td>London</td><td>41</td><td>2012/10/13</td></tr><tr><td>Brenden Wagner</td><td>Software Engineer</td><td>San Francisco</td><td>28</td><td>2011/06/07</td></tr><tr><td>Brielle Williamson</td><td>Integration Specialist</td><td>New York</td><td>61</td><td>2012/12/02</td></tr><tr><td>Bruno Nash</td><td>Software Engineer</td><td>London</td><td>38</td><td>2011/05/03</td></tr><tr><td>Caesar Vance</td><td>Pre-Sales Support</td><td>New York</td><td>21</td><td>2011/12/12</td></tr><tr><td>Cara Stevens</td><td>Sales Assistant</td><td>New York</td><td>46</td><td>2011/12/06</td></tr><tr><td>Cedric Kelly</td><td>Senior Javascript Developer</td><td>Edinburgh</td><td>22</td><td>2012/03/29</td></tr></tbody></table>'

function getCSHTML() {
  $("#masterPage").html(data);

  $('#example').DataTable({
    dom: 'Bfrtip',
    buttons: [
      'copy', 'csv', 'excel', 'pdf', 'print'
    ],
    "initComplete": function() {
      var $buttons = $('.dt-buttons').hide();
      if ($('#exportLink').length > 0) {
        $('#exportLink').on('change', function() {
          var btnClass = $(this).find(":selected")[0].id ?
            '.buttons-' + $(this).find(":selected")[0].id :
            null;
          if (btnClass) $buttons.find(btnClass).click();
        })
      }
      $('#exportToExcel').on('click', function() {
        $('.buttons-excel').click()
      })
    },
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
<link rel="stylesheet" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
<script src="https://cdn.datatables.net/buttons/1.5.2/js/dataTables.buttons.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.5.2/js/buttons.flash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
<script src="https://cdn.datatables.net/buttons/1.5.2/js/buttons.html5.min.js"></script>
<script src="https://cdn.datatables.net/buttons/1.5.2/js/buttons.print.min.js"></script>

<button onclick="getCSHTML()">Get Data</button>
<button id="exportToExcel">Export Data</button>

<div id="masterPage"></div>

【问题讨论】:

    标签: javascript jquery html css datatables


    【解决方案1】:

    你需要unbind在你的函数开始时使用这一行

    $("#exportToExcel").unbind("click")
    

    例子:

    var data = '<table id="example"><thead><tr><th>Name</th><th>Position</th><th>Office</th><th>Age</th><th>Start date</th></tr></thead><tbody><tr><td>Airi Satou</td><td>Accountant</td><td>Tokyo</td><td>33</td><td>2008/11/28</td></tr><tr><td>Angelica Ramos</td><td>Chief Executive Officer (CEO)</td><td>London</td><td>47</td><td>2009/10/09</td></tr><tr><td>Ashton Cox</td><td>Junior Technical Author</td><td>San Francisco</td><td>66</td><td>2009/01/12</td></tr><tr><td>Bradley Greer</td><td>Software Engineer</td><td>London</td><td>41</td><td>2012/10/13</td></tr><tr><td>Brenden Wagner</td><td>Software Engineer</td><td>San Francisco</td><td>28</td><td>2011/06/07</td></tr><tr><td>Brielle Williamson</td><td>Integration Specialist</td><td>New York</td><td>61</td><td>2012/12/02</td></tr><tr><td>Bruno Nash</td><td>Software Engineer</td><td>London</td><td>38</td><td>2011/05/03</td></tr><tr><td>Caesar Vance</td><td>Pre-Sales Support</td><td>New York</td><td>21</td><td>2011/12/12</td></tr><tr><td>Cara Stevens</td><td>Sales Assistant</td><td>New York</td><td>46</td><td>2011/12/06</td></tr><tr><td>Cedric Kelly</td><td>Senior Javascript Developer</td><td>Edinburgh</td><td>22</td><td>2012/03/29</td></tr></tbody></table>'
    
    function getCSHTML() {
      $("#masterPage").html(data);
    
      $("#exportToExcel").unbind("click"); // unbind here
    
      $('#example').DataTable({
        dom: 'Bfrtip',
        buttons: [
          'copy', 'csv', 'excel', 'pdf', 'print'
        ],
        "initComplete": function() {
          var $buttons = $('.dt-buttons').hide();
          if ($('#exportLink').length > 0) {
            $('#exportLink').on('change', function(e) {
              var btnClass = $(this).find(":selected")[0].id ?
                '.buttons-' + $(this).find(":selected")[0].id :
                null;
              if (btnClass) $buttons.find(btnClass).click();
            })
          }
          $('#exportToExcel').on('click', function(e) {
            $('.buttons-excel').click()
          })
        },
      });
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <script src="https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js"></script>
    <link rel="stylesheet" href="https://cdn.datatables.net/1.10.19/css/jquery.dataTables.min.css">
    <script src="https://cdn.datatables.net/buttons/1.5.2/js/dataTables.buttons.min.js"></script>
    <script src="https://cdn.datatables.net/buttons/1.5.2/js/buttons.flash.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.1.3/jszip.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/pdfmake.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.36/vfs_fonts.js"></script>
    <script src="https://cdn.datatables.net/buttons/1.5.2/js/buttons.html5.min.js"></script>
    <script src="https://cdn.datatables.net/buttons/1.5.2/js/buttons.print.min.js"></script>
    
    <button onclick="getCSHTML()">Get Data</button>
    <button id="exportToExcel">Export Data</button>
    
    <div id="masterPage"></div>

    【讨论】:

      【解决方案2】:

      尝试将导出功能移到 initComplete 之外,它的工作原理就像一个魅力

      【讨论】:

      • 我不能,我需要将事件附加到 table init 上的按钮。
      • 但是为什么;导出按钮是动态生成的
      • @AbhishekPandey 即使你能解决问题,这是一个未经测试的无效答案。
      • @IslamElshobokshy 完全正确
      • @irfandar 我需要在每次数据表启动时绑定它,如果我将它移到初始化之外,它只会在页面重新加载时绑定。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-25
      • 1970-01-01
      • 2015-04-05
      • 2013-04-05
      • 2016-07-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多