2012-07-22 35 views
5

Giả sử tôi có yêu cầu sau: Thêm phần tử e vào phần tử có id "x" nếu phần tử như vậy tồn tại, nếu không hãy thêm e vào phần thân.Có cách nào thanh lịch để chọn một phần tử trong JQuery nếu một phần tử không tồn tại?

Trong DOM mức 0, tôi có thể viết:

var parent = document.getElementById("x") || document.body; 
parent.appendChild(e); 

Trong jQuery, sau đây không không công việc:

var parent = $("#x") || $("body"); 
parent.append(e); 

bởi vì nếu không có yếu tố với id x tồn tại, là người đầu tiên bậc hở trả về đối tượng jquery rỗng, với sự thật, không phải là giả, vì vậy, append không làm gì cả. Tôi thể, tuy nhiên, hãy viết:

var parent = $("#x")[0] || $("body")[0]; 
parent.appendChild(e); 

nhưng giải pháp này là hơi phiền phức vì lập chỉ mục đối tượng jQuery được tôi trở lại HTMLElements, vì vậy tôi phải sử dụng appendChild thay vì append. Trong khi điều này làm việc, tôi tự hỏi liệu sự pha trộn của các cấp là thích hợp hoặc chỉ định của thiết kế xấu.

Có cách nào để sử dụng first() không? Có lẽ tôi có thể tạo một đối tượng jQuery mà về cơ bản là một mảng có phần tử đầu tiên là div có id x và phần tử thứ hai là phần thân. Tôi biết tôi có thể làm điều này với các hình thức xây dựng jQuery mà mất một mảng phần tử, nhưng sau đó tôi trở lại với một pha trộn các cấp. Tôi cũng biết cách kiểm tra sự tồn tại của một phần tử có id x ($("#x").length), nhưng tôi không thể thấy cách này sẽ dẫn đến một cách thanh lịch cho cụm từ "phần tử có id x nếu nó tồn tại, khác với phần thân."

Công thức như vậy có tồn tại không?

Trả lời

2

Thay vì sử dụng jQuery để chọn một thành phần, bạn có thể sử dụng nó để quấn mẹ đẻ DOM gọi:

$(document.getElementById("foo") || document.body) 

Nó không phải chính xác tao nhã (hoặc thực sự thậm chí sử dụng jQuery), cũng không phải một kỹ thuật được áp dụng phổ biến, nhưng bạn sẽ kết thúc với một cái gì đó bạn có thể thêm vào (và phải chịu một jQuery gọi tương đối rẻ tiền chỉ một lần).

Bạn sẽ không thể sử dụng first() - ví dụ, $("#foo, body").first(); - bởi vì thứ tự mà nó trả về lựa chọn các yếu tố được dựa trên thứ tự DOM, không chọn trật tự (nhờ, @muistooshort)

+0

Ooh, điều này là khá, mặc dù - trừ khi jQuery làm việc một số phép thuật thực sự nghiêm trọng ở đây - nó có nhược điểm hiệu suất của việc lựa chọn * tất cả * các yếu tố trước khi trở về đầu tiên thay vì ngắn mạch. Tuy nhiên, nếu chúng ta quan tâm đến mức độ hiệu suất đó, chúng ta thực sự không nên sử dụng jQuery ngay từ đầu. – Matchu

+3

Không, điều này sẽ không hoạt động vì ["Thứ tự của các phần tử DOM trong đối tượng jQuery được trả về có thể không giống nhau, vì chúng sẽ theo thứ tự tài liệu."] (Http://api.jquery.com/multiple- bộ chọn /), ví dụ: http://jsfiddle.net/ambiguous/edYY6/. Điều này sẽ cung cấp cho bạn '' mọi lúc. –

+0

Đồng ý rằng điều này là rất tốt đẹp. Chúng tôi không sao với một trong số chúng mặc dù (hoặc phải là), bởi vì cái đầu tiên có một id, nên là duy nhất trên trang, và thứ hai là ** phần tử body **. Chỉ nên có một trong số này trong HTML. –

3

Thành thực mà nói, tôi không thực sự nghĩ rằng đây là cực kỳ chi tiết:

var parent = $('#x'); 
if(parent.length == 0) parent = $('body'); 

Và mục đích của nó cũng khá rõ ràng. Bạn thậm chí có thể quấn nó trong một hàm nếu thành ngữ này xuất hiện rất nhiều.

Ngoài ra, đây là một hình thức ternary rằng chỉ bắn mỗi truy vấn một lần (mặc dù đó là một sự đánh đổi về khả năng đọc):

var parent = (x = $('#header')).length ? x : $('body'); 
+2

Bạn cũng có thể sử dụng độ dài '$ (" # x "). $ ("# x"): $ ("nội dung") '. –

+0

Cảm ơn bạn đã trả lời nhanh. Tôi cảm thấy xấu khi yêu cầu một lớp lót (quá phổ biến trên SO, tôi biết !!) nhưng tôi đã rất ngạc nhiên khi DOM cấp 0 có một công thức ngắn gọn thì có lẽ jquery nên. :) –

+0

@RayToal: thêm một lớp lót hoạt động tốt, mặc dù nó ít rõ ràng hơn.Tôi vẫn sẽ bỏ phiếu để làm cho nó một dòng bằng cách gói phiên bản hai dòng trong một chức năng, đặc biệt là nếu nó đi lên rất nhiều ... nhưng nếu nó chỉ được sử dụng một lần, sau đó meh. – Matchu

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