2012-04-11 54 views
16

Tôi đã thấy nhiều cuộc thảo luận về cách nhanh nhất để chọn phần tử con đầu tiên bằng jQuery. Có thể được mong đợi, thuộc tính firstChild DOM gốc nhanh hơn nhiều so với sử dụng bộ chọn jQuery hoặc kết hợp các bộ chọn - xem http://jsperf.com/jquery-first-child-selection-performance/6. Điều này thường không phải là vấn đề - hoặc nó đang được sử dụng ở một nơi mà hiệu suất không phải là một vấn đề lớn, hoặc thật dễ dàng để chỉ truy cập vào phần tử DOM và sử dụng thuộc tính .firstChild của nó. Tuy nhiên, có một vài vấn đề với điều này:Tại sao jQuery không cung cấp phương thức .firstChild?

  • firstChild có thể trở lại một văn bản hoặc comment nút, chứ không phải là một yếu tố, như một selector jQuery sẽ trở
  • Nếu tôi cần phải chọn đứa con đầu lòng của nhiều yếu tố , Tôi phải sử dụng bộ chọn chậm hoặc chuyển sang nhiều công việc phụ lặp qua các phần tử DOM, thêm chúng vào bộ sưu tập, sau đó đưa chúng trở lại đối tượng jQuery.

Dường như với tôi rằng chi phí thêm phương thức firstChild vào thư viện jQuery cốt lõi sẽ nhỏ hơn nhiều so với lợi ích. Tôi đã bắn của riêng tôi tại tạo ra một phương pháp như vậy để sử dụng riêng của tôi:

$.fn.firstChild = function() { 
    var ret = []; 

    this.each(function() { 
     var el = this.firstChild; 

     //the DOM firstChild property could return a text node or comment instead of an element 
     while (el && el.nodeType != 1) 
      el = el.nextSibling; 

     if (el) ret.push(el); 
    }); 

    //maintain jQuery chaining and end() functionality 
    return this.pushStack(ret); 
}; 

Trong các bài kiểm tra tôi tạo tại http://jsperf.com/jquery-multiple-first-child-selection, chức năng này thực hiện nhanh hơn so với bất kỳ lựa chọn nào khác hơn năm lần. Các bài kiểm tra được dựa trên các bài kiểm tra được đề cập ở trên, nhưng đang chọn các con đầu tiên của nhiều phần tử, chứ không phải là một phần tử đơn lẻ.

Có điều gì tôi thiếu không? Một kỹ thuật mà tôi nên sử dụng? Hay đây có phải là vấn đề không nên lo lắng? Có một lý do để không bao gồm một chức năng như thế này trong jQuery?

Trả lời

12

"Tại sao jQuery không cung cấp phương thức .firstChild?"

Tính năng leo, rất có thể.

Nó có thể được thực hiện với các phương pháp khác như bạn đã nêu, và nếu hiệu suất là một mối quan tâm, bạn có thể mở rộng jQuery cho nhu cầu cụ thể như bạn đã làm.


Bạn có thể cải thiện hiệu suất trong mã của bạn nhiều hơn một chút ...

$.fn.firstChild = function() { 
    var ret = []; 
    // use a for loop 
    for (var i = 0, len = this.length; i < len; i++) { 
     var this_el = this[i], 
      el = this_el.firstElementChild; // try firstElementChild first 
     if (!el) { 
      el = this_el.firstChild; 
      while (el && el.nodeType != 1) 
       el = el.nextSibling; 
     } 
     if (el) ret.push(el); 
    } 
    //maintain jQuery chaining and end() functionality 
    return this.pushStack(ret); 
}; 
+2

+1, tôi không biết về firstElementChild. Đối với tò mò, tôi tìm thấy một biểu đồ hỗ trợ trình duyệt ở đây: http://www.quirksmode.org/dom/w3c_traversal.html – undefined

+1

Tôi cũng nên đề cập đến rằng tôi đã thêm hàm firstChild được cải thiện vào các trường hợp kiểm tra jsperf được liên kết ở trên. – undefined

+0

Mọi người phát điên vì tôi ... :) hãy kiểm tra [this] (http://meta.stackexchange.com/q/129306/173320). – gdoron

0

Đối với các trường hợp yếu tố duy nhất bạn có thể sử dụng

$('.test > eq(0)') 

mà dường như gần như phù hợp với bạn trong tốc độ ..

http://jsperf.com/jquery-multiple-first-child-selection/2

+2

Nó nhanh vì nó là một bộ chọn không hợp lệ, vì vậy nó không thực sự làm bất kỳ lựa chọn DOM nào.Bộ chọn hợp lệ là ': eq (0)', cụ thể cho Sizzle, và sẽ chậm, đặc biệt là xem xét mà không có bất kỳ bộ chọn nào khác trước ':', bạn đang thực hiện '*: eq (0)' một cách hiệu quả, sẽ chọn tất cả các phần tử trong DOM, xem chúng có ở chỉ mục '0' hay không, sau đó xem liệu bố mẹ của chúng có' .test' hay không. –

+1

@amnotiam lol .. chết tiệt, tôi đã bỏ lỡ điều đó ... và tôi nghĩ tôi đã làm một việc gì đó và cố gắng cải thiện nó ... * cười *. Cảm ơn cho những người đứng đầu lên. –

+0

Bạn được chào đón. :) –

Các vấn đề liên quan