2013-08-29 55 views
15

Tôi đang sử dụng jquery-ui Tabs và tôi đang gặp sự cố xảy ra khi một tab đã bị xóa. Tab dường như bị xóa, cùng với div nội dung của nó nhưng khi bạn xem xét heap trong Hồ sơ Chrome DevTools (sau khi tab đã bị xóa), bạn sẽ thấy rằng các yếu tố tab li và div vẫn còn hiện diện nhưng bị tách ra . Theo thời gian, việc thêm/xóa các tab lặp đi lặp lại làm cho các phần tử này tích lũy. Ví dụ, nếu bạn thêm một tab 10 lần, sẽ có 10 phần tử div tách ra và 10 yếu tố li tách ra hiển thị trong ảnh chụp đống:Dường như không dọn dẹp các phần tử DOM tách rời

Heap snapshot with detached elements

Tôi có quan điểm như sau:

TabLabel = Marionette.ItemView.extend({ 
    template: "#tab-label", 
    tagName: "li", 
    events: { 
     "click .ui-icon-close": "closeTab" 
    }, 
    closeTab: function(e) { 
     this.$el.contents().remove(); 
     this.model.collection.remove(this.model); 
     $("#main-container").tabs("refresh"); 
     this.close(); 
    } 
}); 

TabContainer = Marionette.ItemView.extend({ 
    template: "#tab-container", 
    tagName: "div", 
    onBeforeRender: function() { 
     this.$el.attr("id", "div-" + this.id); 
    }, 
    onClose: function() { 
     // This removes the region that contains the container 
     App.layout.removeRegion(this.containerRegion); 
    } 
}); 

TabLabels = Marionette.CollectionView.extend({ 
    tagName: "ul" 
}); 

TabContainers = Marionette.CollectionView.extend({ 
    tagName: "div" 
}); 

những quan điểm được khởi tạo như sau:

tabs = new TabsCollection(); // Create a new collection instance 

var tabLabelView = new TabLabels({ 
    itemView: TabLabel, 
    collection: tabs 
}); 

var tabContainerView = new TabContainers({ 
    itemView: TabContainer, 
    collection: tabs 
}); 

như bạn có thể thấy, quan điểm cả hai tham khảo bộ sưu tập cùng; mỗi mô hình trong bộ sưu tập có thể được cho là đại diện cho một tab duy nhất (nó chỉ xảy ra khi mô hình chứa thông tin cần thiết để đáp ứng các tab jquery-ui). Các quan điểm được hiển thị trong một khu vực thông qua Marionette.Layout ... khá chuẩn. Thêm tab được thực hiện bằng cách nhấp vào liên kết trong vùng chứa tab; tất cả điều này làm là thêm một mô hình khác vào bộ sưu tập và sau đó gọi các tab ("làm mới") trên vùng chứa chính, làm cho tab mới xuất hiện. Xóa tab được thực hiện bằng cách nhấp vào biểu tượng "X" ở góc trên bên phải của tab.

Tôi đã dành rất nhiều thời gian để theo dõi rò rỉ này và tôi không thể tìm ra nếu đó là vấn đề trong mã của tôi (cách tôi đóng dạng xem/mô hình/v.v. có lẽ?) Hoặc nếu đó là một vấn đề trong các plugin tab jquery-ui.

Suy nghĩ? Cảm ơn trước!

Cập nhật # 1 Theo yêu cầu, đây là jsfiddle trình bày sự cố - chỉ cần đóng các tab và bạn sẽ thấy các phần tử tách rời được bỏ lại phía sau.

Ngoài ra, một ảnh chụp màn hình:

enter image description here

Update # 2 này dường như là một sự rò rỉ trong các tab jquery-ui widget. Hành vi tương tự xảy ra trong widget demonstration trên trang web jquery-ui. Tôi đã thêm một vài tab và sau đó đóng chúng ra và chắc chắn đủ, họ vẫn kiên trì:

enter image description here

Tôi đã thử nghiệm này với các mới nhất (tại thời điểm viết bài này) phiên bản của jQuery UI (1.10.3) và phiên bản trước (1.10.2).

+0

Bạn có thể đăng jsfiddle thể hiện điều này không? – Rooster

+2

Tôi tự hỏi nếu vấn đề là xử lý sự kiện mà không phải là loại bỏ –

+0

@JaniHartikainen Tôi nghĩ rằng có thể là vấn đề, nhưng tôi đã cố gắng gọi hoán vị nhiều unbind() trong chức năng đóng và kết quả là như nhau. – musashiXXX

Trả lời

3

Vì vậy, tôi cuối cùng cố định vấn đề này (cách đây khá nhiều thời gian) bằng cách thực hiện hai điều:

  1. ditching jQueryUI ủng hộ Bootstrap
  2. Thay đổi chức năng closeTab (xem jsFiddle gốc) như sau :

    closeTab: function (e) { 
        e.stopPropagation(); 
        e.preventDefault(); 
        this.model.collection.remove(this.model); 
        this.close(); 
    } 
    

Trong đoạn đó, stopPropagation và preventDefault là thực sự những gì dừng lại yếu tố này từ còn lại tách rời (và tích lũy thêm/xóa tiếp theo) trong DOM. Tóm lại: vấn đề này được tạo ra bởi không gọi stopPropagation/preventDefault trên đối tượng sự kiện sau khi nó được kích hoạt. Tôi đã cập nhật jsFiddle để nó loại bỏ một cách chính xác các yếu tố tab và cho hậu thế, đây là một ảnh chụp màn hình của kết quả:

Updated jsFiddle

Như bạn có thể thấy, không ai trong số các yếu tố tab đang còn lại tách ra sau khi nhấp vào "X" để đóng chúng lại. Các phần tử tách rời duy nhất là các phần tử đến từ giao diện của jsFiddle.

3

Có lý do tại sao bạn sử dụng this.$el.contents().remove() thay vì this.$el.empty()?

Sử dụng this.$el.empty() trong đó jsFiddle của bạn dường như khắc phục NodeList tách rời.

Một vài bộ nhớ ghi chú hồ sơ:

  • hồ http://www.youtube.com/watch?v=L3ugr9BJqIs
  • Sử dụng 3 phương pháp chụp, 2 là không đủ. Điều đó nghĩa là gì?
    • Bắt đầu tươi, chế độ ẩn danh và làm mới
    • Take snapshot (buộc GC sẽ xảy ra mỗi khi bạn đưa ảnh chụp)
    • làm điều gì đó, hãy chụp (gc)
    • làm gì đó tương tự, lấy ảnh chụp (gc)
    • Hãy so sánh ảnh chụp 2 với ảnh chụp 1, tìm đồng bằng châu thổ với +
    • Chọn Tóm tắtđối tượng được phân bổ giữa Snapshots 1 và 2 cho ảnh chụp 3
    • Tìm nội dung bạn tìm thấy so sánh 2 và 1 không nên ở đó. Đây là những củ kiệu

Tôi đã tìm thấy trường hợp jQuery dường như Leek vì họ tiết kiệm đối tượng jQuery hiện tại .prevObject khi thực hiện một số hoạt động như gọi .add(). Có thể cuộc gọi đó đến .contents() làm một số phép thuật sôi nổi.

+0

Tôi đã thử nghiệm điều này, bằng cách sử dụng .empty() thay vì .contents(). remove() và kết quả là không may. – musashiXXX