2

我試圖創建我自己的使用jQuery插件,可以用來設置使用單個命令這樣的jQuery移動對話框的處理程序避免jQuery Mobile的內存泄漏:$('#dialog').setup_dialog({ callback: callback_function });從瓶蓋

然而,我的處理程序有一個相當明顯的內存泄漏是由於它關閉:

$.fn.setup_dialog = function(options) { 
    var settings = $.extend({ 
     callback : 0 
    }, options); 
    var that = this; 

    return this.live('pagebeforeshow', function(event, ui) { 
     console.log("outside"); 
     $('form', that).submit(function(e) { 
      var $inputs = $('form :input', that); // get all form inputs 

      var values = {}; 
      $inputs.each(function() { 
       values[this.name] = $(this).val(); 
      }); 

      that.dialog('close'); 

      if (settings.callback && typeof(settings.callback) === "function") { 
       $('#'+ui.prevPage[0].id).live('pagebeforeshow', function() { 
        settings.callback(values, that); 
        console.log("inside"); 
       }); 
      } 

      return e.preventDefault(); 
     }); 
    }); 
}; /* setup_dialog */ 

如果運行上面的代碼,你會看到「內部」和「外部」印第一次,然後三次(兩次從單一提交) ,然後六次(單次提交三次)等。

代碼的意圖是當事件處理程序出現時將事件處理程序附加到jQuery Mobile對話框中,以捕獲表單提交,收集所有表單值,然後將它們傳遞給將修改原始頁面的回調函數發起了對話)。

請注意,由於jQuery Mobile使用AJAX在頁面之間切換的方式,我需要使用.live綁定事件(.bind或.one不起作用)。

任何想法如何避免事件積累(也許清理代碼)?

+0

這不是真的很重要,因爲你沒有對'submit'事件處理函數的返回值做任何事情,但是如果你返回'e.preventDefault()'它實際上並不返回任何東西。 – Jasper

回答

0

的解決方案似乎是以下幾點:

$.fn.setup_dialog = function(options) { 
    var settings = $.extend({ 
     callback : 0 
    }, options); 
    var that = this; var values = {}; var submitted = 0; 

    this.on('pageinit', function(event, ui) { 
     $('form', that).submit(function(e) { 
      var $inputs = $('form :input', that); // get all form inputs 
      submitted = 1; 

      $inputs.each(function() { 
       values[this.name] = $(this).val(); 
      }); 

      that.dialog('close'); 

      return e.preventDefault(); 
     }); 

     $('.cancel-button', that).click(function() { 
      submitted = 0; 
     }); 
    }); 

    this.on('pagebeforehide', function(event, ui) { 
     if (submitted && settings.callback && typeof(settings.callback) === "function") { 
      settings.callback(values, that); 
     } 
    }); 
}; /* setup_dialog */ 

有多種方式做到這一點,包括創建一個封閉和調用$('#'+ui.prevPage[0].id).die().live('pagebeforeshow', function() {

不相信這是最好的解決方案,所以我很樂意聽到一些更好的想法。

0

您正在綁定其他事件處理程序中的事件處理程序。而外部事件處理程序不是唯一的事件(它們會多次出現),這意味着您的內部事件處理程序不止一次地被綁定。

一個很好的解決方法是從pagebeforeshow事件處理程序刪除submit事件處理程序,並將其放置在一個pagecreatepageinit事件處理程序(這些都是獨一無二的,只按對話框運行一次)。

如果你想保持當前的邏輯那麼你可以取消綁定事件處理程序,當他們跑,這樣你就不會被堆疊多個事件處理程序做同樣的事情:

$.fn.setup_dialog = function(options) { 
    var settings = $.extend({ 
     callback : 0 
    }, options); 
    var that = this; 

    return this.live('pagebeforeshow', function(event, ui) { 
     console.log("outside"); 
     $('form', that).submit(function(e) { 
      var $inputs = $('form :input', that); // get all form inputs 

      var values = {}; 
      $inputs.each(function() { 
       values[this.name] = $(this).val(); 
      }); 

      that.dialog('close'); 

      if (settings.callback && typeof(settings.callback) === "function") { 
       $('#'+ui.prevPage[0].id).live('pagebeforeshow', function() { 
        settings.callback(values, that); 
        console.log("inside"); 

        $(this).die('pagebeforeshow');//NEW, unbind the pagebeforeshow event handler for this element 
                //since it will be bound the next time the dialog is shown anyway 
       }); 
      } 

      $(this).die('submit');//NEW, unbind the submit event handler for this form 
            //since it will be bound the next time the dialog is shown anyway 

      return e.preventDefault(); 
     }); 
    }); 
}; /* setup_dialog */ 

這裏是文檔爲.die()http://api.jquery.com/die/

+0

我曾嘗試.die()以及您的代碼,但不幸的是,我仍然遇到同樣的問題。注意:我註釋了整個.submit()事件處理程序,並且「外部」仍然在我的控制檯中積累(1,3,6等)。也許我應該注意到,我在相應對話框頁面底部的

  • 11. 瓶,從AJAX
  • 12. 燒瓶不寧從燒瓶SQLAlchemy的
  • 13. 從webapp2將燒瓶
  • 14. 瓶:從非標準位置
  • 15. 從瓶中讀取uwsgi_param
  • 16. 如何從瓶功能
  • 17. 從燒瓶內訪問mysql
  • 18. 瓶 - 從字典打印值
  • 19. Retriving JSON從瓶端點
  • 20. 燒瓶中:從與產量
  • 21. 蟒蛇瓶「從package.module」錯誤
  • 22. 從瓶子排除URL
  • 23. 從瓶子返回window.close()?
  • 24. 燒瓶WTF validate_on_submit()是我用的燒瓶WTF從未執行
  • 25. 從靜態目錄以外的瓶子提供瓶子文件
  • 26. mod_speling內部重定向,或如何處理與瓶蓋的mod_rewrite
  • 27. uWSGI:覆蓋燒瓶/ python中的默認harakiri持續時間
  • 28. 你如何爲瓶,如果你覆蓋默認提供靜態?
  • 29. Linux遠程服務器瓶蓋生產部署
  • 30. 瓶蓋生產部署:遷移不起作用