Mẹo và thủ thuật jQuery


507

Cú pháp

Lưu trữ dữ liệu

Tối ưu hóa

Điều khoản khác

Câu trả lời:


252

Tạo một phần tử HTML và giữ một tham chiếu

var newDiv = $("<div />");

newDiv.attr("id", "myNewDiv").appendTo("body");

/* Now whenever I want to append the new div I created, 
   I can just reference it from the "newDiv" variable */


Kiểm tra nếu một phần tử tồn tại

if ($("#someDiv").length)
{
    // It exists...
}


Viết bộ chọn của riêng bạn

$.extend($.expr[":"], {
    over100pixels: function (e)
    {
        return $(e).height() > 100;
    }
});

$(".box:over100pixels").click(function ()
{
    alert("The element you clicked is over 100 pixels height");
});

93
Viết các công cụ chọn của riêng bạn khá khó khăn
Hugoware

22
Ngoài ra, nếu có bất kỳ trợ giúp nào, bạn thực sự có thể thực hiện $ ("<div />") và đạt được điều tương tự như $ ("<div> </ div>")
Hugoware

4
Tôi yêu phần chọn mới, không biết về điều đó.
Pim Jager

5
Vì tôi chưa thể chỉnh sửa wiki cộng đồng: Kết hợp kiểm tra chuyển nhượng và kiểm tra tồn tại vớiif ((var someDiv = $("#someDiv")).length) { /* do stuff with someDiv... */ }
Ben Blank

4
@Ben: Lý do tôi tránh các thành ngữ như vậy trong JavaScript là vì tôi không muốn đưa ra ảo tưởng về someDivviệc bị giới hạn trong iftuyên bố, bởi vì nó không phải vậy; JavaScript chỉ hỗ trợ phạm vi chức năng
Andreas Grech

111

data()Phương pháp của jQuery rất hữu ích và không được nhiều người biết đến. Nó cho phép bạn liên kết dữ liệu với các thành phần DOM mà không cần sửa đổi DOM.


4
dữ liệu () thực sự là rất hữu ích.
Pim Jager

3
Tôi đã nhận thấy rằng nó không hoạt động với các phần tử mà không đặt ID.
Nhà tư tưởng

20
@Thinker: Vâng, đúng vậy.
Alex Barrett

Sử dụng dữ liệu () thay vì khai báo các biến js toàn cầu, imo.
Johan

95

Bộ lọc lồng

Bạn có thể lồng các bộ lọc (như nickf hiển thị ở đây ).

.filter(":not(:has(.selected))")

3
Mặc dù cẩn thận với điều này ...: đã thực hiện tìm kiếm toàn diện, vì vậy nó có thể khá tốn kém.
harpo

80

Tôi thực sự không phải là một fan hâm mộ của các $(document).ready(fn)phím tắt. Chắc chắn rằng nó cắt giảm mã nhưng nó cũng cắt giảm khả năng đọc của mã. Khi bạn nhìn thấy $(document).ready(...), bạn biết những gì bạn đang nhìn. $(...)được sử dụng trong quá nhiều cách khác để ngay lập tức có ý nghĩa.

Nếu bạn có nhiều khung công tác bạn có thể sử dụng jQuery.noConflict();như bạn nói, nhưng bạn cũng có thể gán một biến khác cho nó như thế này:

var $j = jQuery.noConflict();

$j("#myDiv").hide();

Rất hữu ích nếu bạn có một số khung có thể được thực hiện $x(...)theo các cuộc gọi theo kiểu.


1
@Oli: Giới thiệu về tài liệu đã sẵn sàng; bạn có một điểm Nhưng không bao giờ là ít hơn: đó là một mẹo / mẹo. Một mã mà tôi sử dụng trong tất cả các mã của mình hoàn toàn vì tôi nghĩ nó "có vẻ" tốt hơn. Một vấn đề về sở thích cá nhân, tôi đoán vậy :)
cllpse

Mỗi ngày tôi lội qua XML / XLS / XLST vô nghĩa, các trang web được viết với quá nhiều lớp trừu tượng, các hệ thống chuyển đổi dự phòng phức tạp trên các trang web sẽ không bao giờ vượt quá mức khiêm tốn của máy chủ ... và mọi người vẫn phàn nàn về sự khác biệt giữa $ ( <chuỗi>) & $ (<chức năng>). Khiến tôi muốn khóc :)
JoeBloggs

Khi tôi thấy $ (function () {...}) tôi biết chuyện gì đang xảy ra. Những thứ bình thường hơn nên ngắn hơn. Đó là lý do tại sao chúng ta biến các đoạn mã được gọi thường xuyên thành các hàm.
luikore

77

Ôi, đừng quên siêu dữ liệu jQuery ! Hàm data () rất tuyệt, nhưng nó phải được điền thông qua các lệnh gọi jQuery.

Thay vì phá vỡ sự tuân thủ của W3C với các thuộc tính thành phần tùy chỉnh, chẳng hạn như:

<input 
  name="email" 
  validation="required" 
  validate="email" 
  minLength="7" 
  maxLength="30"/> 

Sử dụng siêu dữ liệu thay thế:

<input 
  name="email" 
  class="validation {validate: email, minLength: 2, maxLength: 50}" />

<script>
    jQuery('*[class=validation]').each(function () {
        var metadata = $(this).metadata();
        // etc.
    });
</script>

7
thuộc tính dữ liệu html5 làm cho vấn đề này ít hơn; có cuộc thảo luận về việc đưa nội tuyến dữ liệu html5 với hàm data () của jquery: forum.jquery.com/topic/ mẹo
Oskar Austegard

10
@Oskar - vâng, điều này đã được triển khai trong jQuery 1.4.3 - data-*các thuộc tính được tự động có sẵn thông qua các cuộc gọi đến.data()
nickf

73

Xử lý sự kiện trực tiếp

Đặt một trình xử lý sự kiện cho bất kỳ phần tử nào khớp với bộ chọn, ngay cả khi nó được thêm vào DOM sau khi tải trang ban đầu:

$('button.someClass').live('click', someFunction);

Điều này cho phép bạn tải nội dung qua ajax hoặc thêm chúng qua javascript và để các trình xử lý sự kiện được thiết lập đúng cho các thành phần đó một cách tự động.

Tương tự như vậy, để dừng việc xử lý sự kiện trực tiếp:

$('button.someClass').die('click', someFunction);

Những người xử lý sự kiện trực tiếp này có một vài hạn chế so với các sự kiện thông thường, nhưng chúng hoạt động rất tốt cho phần lớn các trường hợp.

Để biết thêm thông tin, xem Tài liệu jQuery .

CẬP NHẬT: live()die()không được dùng trong jQuery 1.7. Xem http://api.jquery.com/on/http://api.jquery.com/off/ để biết chức năng thay thế tương tự.

CẬP NHẬT2: live()đã bị phản đối từ lâu, ngay cả trước jQuery 1.7. Đối với các phiên bản jQuery 1.4.2+ trước 1.7 sử dụng delegate()undelegate(). Các live()ví dụ ( $('button.someClass').live('click', someFunction);) có thể được viết lại sử dụng delegate()như thế: $(document).delegate('button.someClass', 'click', someFunction);.


1
Vâng, tôi yêu những thứ sống mới. Lưu ý rằng nó chỉ hoạt động bắt đầu với jQuery 1.3.
Nosredna

4
+. Cảm ơn
Luke101

2
đối với bất kỳ người mới đến cuối bài viết này, bạn cũng có thể muốn xem ủy nhiệm (): api.jquery.com/delegate Tương tự như trực tiếp, nhưng hiệu quả hơn.
Oskar Austegard

2
Chỉ cần nhớ .live bong bóng lên cơ thể để sự kiện trực tiếp bị ràng buộc có thể được bắn. Nếu một cái gì đó trên đường hủy bỏ sự kiện đó, sự kiện trực tiếp sẽ không kích hoạt.
nickytonline

1
live () và die () là các phương thức không dùng nữa kể từ khi jQuery 1.7 phát hành ngày 3 tháng 11. Được thay thế bởi on (), api.jquery.com/on và off (), api.jquery.com/off
Johan

46

Thay thế các chức năng ẩn danh bằng các chức năng được đặt tên. Điều này thực sự thay thế bối cảnh jQuery, nhưng nó xuất hiện nhiều hơn khi sử dụng jQuery, do nó phụ thuộc vào các hàm gọi lại. Vấn đề tôi gặp phải với các hàm ẩn danh nội tuyến, là chúng khó gỡ lỗi hơn (dễ dàng hơn khi xem một bảng gọi với các hàm được đặt tên riêng biệt, thay vì 6 cấp độ "ẩn danh"), và thực tế là nhiều hàm ẩn danh trong cùng một Chuỗi jQuery có thể trở nên khó sử dụng để đọc và / hoặc duy trì. Ngoài ra, các chức năng ẩn danh thường không được sử dụng lại; mặt khác, việc khai báo các hàm có tên khuyến khích tôi viết mã có nhiều khả năng được sử dụng lại.

Sự minh họa; thay vì:

$('div').toggle(
    function(){
        // do something
    },
    function(){
        // do something else
    }
);

Tôi thích:

function onState(){
    // do something
}

function offState(){
    // do something else
}

$('div').toggle( offState, onState );

Thật không may, vì jQuery vượt qua mục tiêu sự kiện là this, bạn không thể có được OO "phù hợp" mà không sử dụng các bao vây. Tôi thường đi thỏa hiệp:$('div').click( function(e) { return self.onClick(e) } );
Ben Blank

3
Tôi xin lỗi Ben, nhưng tôi không thấy bình luận của bạn có liên quan đến bài viết của tôi như thế nào. Bạn có thể xây dựng? Bạn vẫn có thể sử dụng 'tự' (hoặc bất kỳ biến nào khác) bằng đề xuất của tôi; nó sẽ không thay đổi bất cứ điều gì cả
ken

Yeh, Ben, chính xác thì ý anh là gì!?
James

2
Tôi phải đề cập đến: luôn luôn biến lông và các hàm trong không gian tên không nằm trong root !!
jmav

45

Xác định các thuộc tính khi tạo phần tử

Trong jQuery 1.4, bạn có thể sử dụng một đối tượng bằng chữ để xác định các thuộc tính khi bạn tạo một phần tử:

var e = $("<a />", { href: "#", class: "a-class another-class", title: "..." });

... Bạn thậm chí có thể thêm kiểu:

$("<a />", {
    ...
    css: {
        color: "#FF0000",
        display: "block"
    }
});

Đây là một liên kết đến các tài liệu .


43

thay vì sử dụng một bí danh khác cho đối tượng jQuery (khi sử dụng noConflict), tôi luôn viết mã jQuery của mình bằng cách gói tất cả trong một bao đóng. Điều này có thể được thực hiện trong hàm document. Yet:

var $ = someOtherFunction(); // from a different library

jQuery(function($) {
    if ($ instanceOf jQuery) {
        alert("$ is the jQuery object!");
    }
});

Ngoài ra, bạn có thể làm như thế này:

(function($) {
    $('...').etc()    // whatever jQuery code you want
})(jQuery);

Tôi thấy đây là di động nhất. Tôi đã làm việc trên một trang web sử dụng đồng thời cả Prototype và jQuery và các kỹ thuật này đã tránh được tất cả các xung đột.


Ví dụ thứ hai là tốt đẹp cho đôi mắt :)
cllpse

25
Mặc dù có một sự khác biệt, ví dụ đầu tiên sẽ đợi sự kiện document. Yet () phát sinh, trong khi ví dụ thứ hai sẽ không xảy ra.
SamBeran

1
@SamBeran: Đúng, ví dụ thứ hai sẽ chạy ngay lập tức; tuy nhiên, nếu bạn đang gói một đối tượng bằng chữ, bạn có thể sử dụng $ (tài liệu). yet (...) bên trong đối tượng bằng chữ có nghĩa là bạn có thể chỉ định khi nào bạn muốn chạy từng đoạn mã.
Wil Moore III

4
instanceOfsẽ không làm việc, chỉ instanceof. Và dù sao nó cũng không hoạt động, vì jQuery instanceof jQuerysẽ trở lại false. $ == jQuerylà cách chính xác để làm điều đó.
nyuszika7h

@ Nyuszika7H: Vâng, bạn đúng, nhưng đó không thực sự là điểm của ví dụ mã.
nickf

39

Kiểm tra chỉ số

jQuery có .index nhưng thật khó sử dụng, vì bạn cần danh sách các phần tử và chuyển vào phần tử bạn muốn chỉ mục của:

var index = e.g $('#ul>li').index( liDomObject );

Sau đây là dễ dàng hơn nhiều:

Nếu bạn muốn biết chỉ mục của một thành phần trong một tập hợp (ví dụ: các mục danh sách) trong danh sách không có thứ tự:

$("ul > li").click(function () {
    var index = $(this).prevAll().length;
});

Điều gì sai với phương thức index ()? Nó đã ở trong lõi từ 1,2 ít nhất. docs.jquery.com/Core/index
ken

Ok, vâng, tôi đã chơi trò bênh vực của quỷ, vì khi tôi xem lại chỉ số của jQuery () tôi nhận ra rằng đó là một nỗi đau ở mông. Cảm ơn bạn đã làm rõ!
ken

4
Điều này thật tuyệt, nhưng điều quan trọng cần biết là nó không hoạt động hoàn toàn đúng nếu bạn có anh chị em trước đó không phải là một phần của lựa chọn.
TM.

2
Tôi khá chắc chắn kể từ jQuery 1.4, bạn chỉ có thể sử dụng index()và lấy chỉ mục từ cha mẹ của nó.
alex

@alex - chắc chắn, nhưng lưu ý ngày của bài đăng này - đó là 5 tháng trước khi phát hành 1.4!
redsapes

23

Viết tắt cho sự kiện đã sẵn sàng

Cách rõ ràng và dài dòng:

$(document).ready(function ()
{
    // ...
});

Tốc ký:

$(function ()
{
    // ...
});

22

Trên hàm jQuery lõi, chỉ định tham số ngữ cảnh bên cạnh tham số bộ chọn. Việc chỉ định tham số ngữ cảnh cho phép jQuery bắt đầu từ một nhánh sâu hơn trong DOM, thay vì từ gốc DOM. Đưa ra một DOM đủ lớn, việc chỉ định tham số ngữ cảnh sẽ chuyển thành tăng hiệu suất.

Ví dụ: Tìm tất cả các đầu vào của loại radio trong mẫu đầu tiên trong tài liệu.

$("input:radio", document.forms[0]);

Tham khảo: http://docs.jquery.com/Core/jQuery#expressioncontext


10
Một lưu ý: $(document.forms[0]).find('input:radio')làm điều tương tự. Nếu bạn nhìn vào nguồn jQuery, bạn sẽ thấy: nếu bạn truyền tham số thứ hai cho $nó, nó sẽ thực sự gọi .find().
nyuszika7h

Thế còn ... $('form:first input:radio')?
daGrevis

Paul Irish đã chỉ ra trong paulirish.com/2009/perf (bắt đầu từ slide 17) rằng làm điều này là "ngược" từ quan điểm dễ đọc. Như @ Nyuszika7H đã chỉ ra, nó sử dụng .find () bên trong và $ (document.forms [0]). Find ('input: radio') rất dễ đọc, so với việc đặt bối cảnh vào bộ chọn ban đầu.
LocalPCGuy

21

Không chỉ jQuery thực sự mà tôi đã tạo một cầu nối nhỏ đẹp cho jQuery và MS AJAX:

Sys.UI.Control.prototype.j = function Sys$UI$Control$j(){
  return $('#' + this.get_id());
}

Thật tuyệt nếu bạn đang làm nhiều ASP.NET AJAX, vì jQuery được MS hỗ trợ giờ đây có một cây cầu đẹp có nghĩa là thực hiện các thao tác jQuery rất dễ dàng:

$get('#myControl').j().hide();

Vì vậy, ví dụ trên không phải là tuyệt vời, nhưng nếu bạn đang viết các điều khiển máy chủ ASP.NET AJAX, giúp dễ dàng có jQuery trong triển khai kiểm soát phía máy khách của bạn.


Thư viện máy khách ajax có cung cấp cách tìm kiếm kiểm soát theo Id gốc mà bạn đã gán (theo mã phía sau)
Chris S

this .get_id () sẽ trả về cho bạn ID của điều khiển trong phạm vi máy khách. ID do máy chủ chỉ định không liên quan vì ID khách hàng được tạo tùy thuộc vào hierachy cha mẹ
Aaron Powell

20

Tối ưu hóa hiệu suất của các bộ chọn phức tạp

Truy vấn một tập hợp con của DOM khi sử dụng các bộ chọn phức tạp giúp cải thiện đáng kể hiệu năng:

var subset = $("");

$("input[value^='']", subset);

7
Chỉ khi tập hợp con đó được lưu trữ / lưu trữ.
Dykam

6
Điều đó không khác nhiều so với $ (""). Find ("input [value ^ = '']")
Chad Moran

1
@Dykam: trong trường hợp mã ví dụ của tôi. Nhưng quan điểm của bạn vẫn còn hiệu lực.
cllpse

4
@Chad, nó thực sự giống hệt và ánh xạ tới chức năng bạn đã viết
Mike Robinson

19

Nói về Mẹo và Thủ thuật và cũng như một số hướng dẫn. Tôi tìm thấy một loạt các hướng dẫn (Dòng jQuery dành cho người mới bắt đầu tuyệt đối Dòng video trực tuyến) của Jeffery Way là RẤT GIÚP.

Nó nhắm mục tiêu đến những nhà phát triển mới biết về jQuery. Anh ấy chỉ ra cách tạo ra nhiều thứ hay ho với jQuery, như hoạt hình, Tạo và xóa các thành phần và hơn thế nữa ...

Tôi học được rất nhiều từ nó. Anh ấy cho thấy cách dễ dàng sử dụng jQuery. Bây giờ tôi yêu nó và tôi có thể đọc và hiểu bất kỳ tập lệnh jQuery nào ngay cả khi nó phức tạp.

Đây là một ví dụ tôi thích " Thay đổi kích thước văn bản "

1- jQuery ...

<script language="javascript" type="text/javascript">
    $(function() {
        $('a').click(function() {
            var originalSize = $('p').css('font-size'); // get the font size 
            var number = parseFloat(originalSize, 10); // that method will chop off any integer from the specified variable "originalSize"
            var unitOfMeasure = originalSize.slice(-2);// store the unit of measure, Pixle or Inch

            $('p').css('font-size', number / 1.2 + unitOfMeasure);
            if(this.id == 'larger'){$('p').css('font-size', number * 1.2 + unitOfMeasure);}// figure out which element is triggered
         });        
     });
</script>

2- Tạo kiểu CSS ...

<style type="text/css" >
body{ margin-left:300px;text-align:center; width:700px; background-color:#666666;}
.box {width:500px; text-align:justify; padding:5px; font-family:verdana; font-size:11px; color:#0033FF; background-color:#FFFFCC;}
</style>

2- HTML ...

<div class="box">
    <a href="#" id="larger">Larger</a> | 
    <a href="#" id="Smaller">Smaller</a>
    <p>
    In todays video tutorial, Ill show you how to resize text every time an associated anchor tag is clicked. Well be examining the slice”, parseFloat”, and CSS Javascript/jQuery methods. 
    </p>
</div>

Rất khuyến khích những hướng dẫn này ...

http://blog.themeforest.net/screencasts/jquery-for-absolute-beginners-video-series/


19

Hàm không đồng bộ mỗi ()

Nếu bạn có các tài liệu thực sự phức tạp khi chạy chức năng jquery Each () sẽ khóa trình duyệt trong quá trình lặp và / hoặc Internet Explorer bật lên thông báo ' bạn có muốn tiếp tục chạy tập lệnh này không, giải pháp này sẽ tiết kiệm trong ngày.

jQuery.forEach = function (in_array, in_pause_ms, in_callback)
{
    if (!in_array.length) return; // make sure array was sent

    var i = 0; // starting index

    bgEach(); // call the function

    function bgEach()
    {
        if (in_callback.call(in_array[i], i, in_array[i]) !== false)
        {
            i++; // move to next item

            if (i < in_array.length) setTimeout(bgEach, in_pause_ms);
        }
    }

    return in_array; // returns array
};


jQuery.fn.forEach = function (in_callback, in_optional_pause_ms)
{
    if (!in_optional_pause_ms) in_optional_pause_ms = 10; // default

    return jQuery.forEach(this, in_optional_pause_ms, in_callback); // run it
};


Cách đầu tiên bạn có thể sử dụng nó giống như mỗi ():

$('your_selector').forEach( function() {} );

Một tham số thứ 2 tùy chọn cho phép bạn chỉ định tốc độ / chậm trễ trong việc giữa lặp mà có thể hữu ích cho hình ảnh động ( ví dụ sau sẽ đợi 1 giây ở giữa lặp ):

$('your_selector').forEach( function() {}, 1000 );

Hãy nhớ rằng vì điều này hoạt động không đồng bộ, bạn không thể dựa vào các lần lặp để hoàn thành trước dòng mã tiếp theo, ví dụ:

$('your_selector').forEach( function() {}, 500 );
// next lines of code will run before above code is complete


Tôi đã viết điều này cho một dự án nội bộ, và trong khi tôi chắc chắn rằng nó có thể được cải thiện, nó đã làm việc cho những gì chúng tôi cần, vì vậy hy vọng một số bạn thấy nó hữu ích. Cảm ơn -


18

Cú pháp tốc ký cú pháp - Lưu trữ bộ sưu tập đối tượng và thực thi các lệnh trên một dòng:

Thay vì:

var jQueryCollection = $("");

jQueryCollection.command().command();

Tôi làm:

var jQueryCollection = $("").command().command();

Một trường hợp sử dụng hơi "thực" có thể là một cái gì đó dọc theo những dòng này:

var cache = $("#container div.usehovereffect").mouseover(function ()
{
    cache.removeClass("hover").filter(this).addClass("hover");
});

4
tốt hơn là đặt tham chiếu $ (cái này) vào một biến cục bộ, bởi vì bạn sẽ có một điểm nhấn nhỏ ở đây, bởi vì nó sẽ mất nhiều thời gian hơn ...
Sander Versluys

4
Trong trường hợp này (không có ý định chơi chữ) tôi chỉ sử dụng "cái này" một lần. Không cần bộ nhớ đệm.
cllpse

1
Một mẹo nhỏ. Mặc dù trong trường hợp này có thể không có vấn đề gì khi thực hiện các thay đổi bổ sung cho DOM. Ví dụ, nói rằng phần tử bạn đang di chuột qua đã có lớp "di chuột". Bạn sẽ loại bỏ lớp này và thêm lại nó. Bạn có thể nhận được xung quanh đó với $(this).siblings().removeClass("hover"). Tôi biết điều này nghe có vẻ như là một việc nhỏ nhưng mỗi khi bạn thay đổi DOM, việc vẽ lại trình duyệt khác có thể được kích hoạt. Các khả năng khác bao gồm các sự kiện được đính kèm với DOMAttrModified hoặc các lớp thay đổi chiều cao của phần tử có thể kích hoạt các trình lắng nghe sự kiện "thay đổi kích thước" khác.
gradbot

1
Nếu bạn muốn sử dụng bộ đệm và giảm thiểu thay đổi DOM, bạn có thể thực hiện việc này. cache.not(this).removeClass("hover")
gradbot

@gradbot: Tôi không hiểu hai bình luận cuối cùng của bạn. Bạn có thể mở rộng?
Randomblue

15

Tôi thích khai báo một $thisbiến ở đầu các hàm ẩn danh, vì vậy tôi biết tôi có thể tham chiếu một jQueried này.

Thích như vậy:

$('a').each(function() {
    var $this = $(this);

    // Other code
});

12
Tôi sử dụng "cái đó" thay thế :)
cllpse

2
ROA: Vâng, đó sẽ là axit :) Bạn cũng có thể sử dụng argument.callee để kích hoạt chức năng ẩn danh để tham chiếu chính nó
JoeBloggs

5
Joe - chỉ cần ngẩng cao đầu, callee sẽ biến mất với ECMAScript 5 và chế độ nghiêm ngặt. Xem: ejohn.org/blog/ecmascript-5-strict-mode-json-and-more
Mike Robinson

@Joe Bạn có thể đặt tên cho nó, hãy cảnh giác với những điều kỳ quặc của IE .
alex

Một ví dụ tuyệt vời về việc sử dụng $ ở đầu tên biến để chỉ ra biến đối tượng jQuery so với biến tiêu chuẩn. Bằng cách thêm nó vào đầu của bất kỳ biến nào đang lưu trữ một đối tượng jQuery, bạn ngay lập tức biết bằng cách nhìn vào nó rằng bạn có thể thực hiện các hàm jQuery trên biến đó. Làm cho mã dễ đọc hơn nhiều ngay lập tức.
LocalPCGuy

14

Lưu các đối tượng jQuery trong các biến để sử dụng lại

Lưu một đối tượng jQuery vào một biến cho phép bạn sử dụng lại nó mà không phải tìm kiếm lại qua DOM để tìm thấy nó.

(Như @Louis đã đề xuất, bây giờ tôi sử dụng $ để chỉ ra rằng một biến chứa một đối tượng jQuery.)

// Bad: searching the DOM multiple times for the same elements
$('div.foo').each...
$('div.foo').each...

// Better: saving that search for re-use
var $foos = $('div.foo');
$foos.each...
$foos.each...

Ví dụ phức tạp hơn, giả sử bạn có một danh sách thực phẩm trong cửa hàng và bạn muốn chỉ hiển thị những thực phẩm phù hợp với tiêu chí của người dùng. Bạn có một biểu mẫu với các hộp kiểm, mỗi hộp chứa một tiêu chí. Các hộp kiểm có tên như organiclowfat, và các sản phẩm có các lớp tương ứng - .organic, v.v.

var $allFoods, $matchingFoods;
$allFoods = $('div.food');

Bây giờ bạn có thể tiếp tục làm việc với đối tượng jQuery đó. Mỗi khi hộp kiểm được nhấp (để kiểm tra hoặc bỏ chọn), hãy bắt đầu từ danh sách thực phẩm chính và lọc xuống dựa trên các hộp được chọn:

// Whenever a checkbox in the form is clicked (to check or uncheck)...
$someForm.find('input:checkbox').click(function(){

  // Start out assuming all foods should be showing
  // (in case a checkbox was just unchecked)
  var $matchingFoods = $allFoods;

  // Go through all the checked boxes and keep only the foods with
  // a matching class 
  this.closest('form').find("input:checked").each(function() {  
     $matchingFoods = $matchingFoods.filter("." + $(this).attr("name")); 
  });

  // Hide any foods that don't match the criteria
  $allFoods.not($matchingFoods).hide();
});

8
Quy ước đặt tên của tôi là có một $ở phía trước. ví dụvar $allItems = ...
Louis

6
@Lavinski - Tôi nghĩ ý tưởng là $chỉ ra rằng đây là một đối tượng jQuery, điều này sẽ giúp dễ dàng phân biệt trực quan với các biến khác.
Nathan Long

@Louis - Tôi đã thông qua quy ước của bạn và sẽ cập nhật câu trả lời của tôi cho phù hợp. :)
Nathan Long

11

Có vẻ như hầu hết các mẹo thú vị và quan trọng đã được đề cập, vì vậy đây chỉ là một bổ sung nhỏ.

Mẹo nhỏ là hàm jQuery.each (object, callback) . Mọi người có lẽ đang sử dụng jQuery.each (gọi lại) để lặp lại chính đối tượng jQuery vì nó là tự nhiên. Hàm tiện ích jQuery.each (object, callback) lặp lại trên các đối tượng và mảng. Trong một thời gian dài, bằng cách nào đó tôi đã không thấy nó có thể là gì ngoài một cú pháp khác (tôi không ngại viết tất cả các vòng lặp thời trang), và tôi hơi xấu hổ khi tôi nhận ra sức mạnh chính của nó chỉ gần đây.

Vấn đề là vì phần thân của vòng lặp trong jQuery.each (đối tượng, gọi lại) là một hàm , nên bạn nhận được một phạm vi mới mỗi lần trong vòng lặp, điều này đặc biệt thuận tiện khi bạn tạo các bao đóng trong vòng lặp.

Nói cách khác, một lỗi phổ biến điển hình là làm một việc như:

var functions = [];
var someArray = [1, 2, 3];
for (var i = 0; i < someArray.length; i++) {
    functions.push(function() { alert(someArray[i]) });
}

Bây giờ, khi bạn gọi các hàm trong functionsmảng, bạn sẽ nhận được cảnh báo ba lần với nội dung undefinedrất có thể không phải là những gì bạn muốn. Vấn đề là chỉ có một biến ivà cả ba lần đóng đều đề cập đến nó. Khi vòng lặp kết thúc, giá trị cuối cùng ilà 3 và someArrary[3]undefined. Bạn có thể làm việc xung quanh nó bằng cách gọi một chức năng khác sẽ tạo ra sự đóng cửa cho bạn. Hoặc bạn sử dụng tiện ích jQuery mà về cơ bản nó sẽ làm điều đó cho bạn:

var functions = [];
var someArray = [1, 2, 3];
$.each(someArray, function(item) {
    functions.push(function() { alert(item) });
});

Bây giờ, khi bạn gọi các chức năng, bạn nhận được ba cảnh báo với nội dung 1, 2 và 3 như mong đợi.

Nói chung, không có gì bạn không thể tự làm, nhưng thật tuyệt khi có.


11

Truy cập các hàm jQuery như một mảng

Thêm / xóa một lớp dựa trên boolean ...

function changeState(b)
{
    $("selector")[b ? "addClass" : "removeClass"]("name of the class");
}

Là phiên bản ngắn hơn của ...

function changeState(b)
{
    if (b)
    {
        $("selector").addClass("name of the class");
    }
    else
    {
        $("selector").removeClass("name of the class");
    }
}

Không có nhiều trường hợp sử dụng cho việc này. Tuy nhiên; Tôi nghĩ nó gọn gàng :)


Cập nhật

Chỉ trong trường hợp bạn không phải là kiểu đọc bình luận, ThiefMaster chỉ ra rằng toggleClass chấp nhận giá trị boolean , xác định xem một lớp nên được thêm hoặc xóa. Theo như mã ví dụ của tôi ở trên, đây sẽ là cách tiếp cận tốt nhất ...

$('selector').toggleClass('name_of_the_class', true/false);

2
Điều này rất gọn gàng và có một số cách sử dụng thú vị, nhưng nó không có gì cụ thể đối với jQuery cả ... đây chỉ là điều bạn có thể làm trên bất kỳ đối tượng JavaScript nào.
TM.

1
Cảm ơn :) ... Đó là JavaScript cơ bản; vâng Nhưng tôi sẽ tranh luận rằng jQuery là JavaScript. Tôi không khẳng định rằng đây là đặc trưng của jQuery.
cllpse

7
Trong trường hợp cụ thể này, bạn thực sự muốn sử dụng $('selector').toggleClass('name_of_the_class', b);mặc dù.
ThiefMaster

9

Cập nhật:

Chỉ cần bao gồm tập lệnh này trên trang web và bạn sẽ nhận được bảng điều khiển Fireorms bật lên để gỡ lỗi trong bất kỳ trình duyệt nào. Không hoàn toàn đầy đủ tính năng nhưng nó vẫn khá hữu ích! Hãy nhớ loại bỏ nó khi bạn đã hoàn tất.

<script type='text/javascript' src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>

Kiểm tra liên kết này:

Từ thủ thuật CSS

Cập nhật: Tôi tìm thấy một cái gì đó mới; đó là Hotbox JQuery.

Hộp thư đến của JQuery

Google lưu trữ một số thư viện JavaScript trên Google Code. Tải nó từ đó giúp tiết kiệm băng thông và tải nhanh vì nó đã được lưu vào bộ nhớ cache.

<script src="http://www.google.com/jsapi"></script>  
<script type="text/javascript">  

    // Load jQuery  
    google.load("jquery", "1.2.6");  

    google.setOnLoadCallback(function() {  
        // Your code goes here.  
    });  

</script>

Hoặc là

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script>

Bạn cũng có thể sử dụng điều này để biết khi nào một hình ảnh được tải đầy đủ.

$('#myImage').attr('src', 'image.jpg').load(function() {  
    alert('Image Loaded');  
});

"Console.info" của fireorms, mà bạn có thể sử dụng để kết xuất các thông điệp và biến vào màn hình mà không phải sử dụng các hộp cảnh báo. "console.time" cho phép bạn dễ dàng thiết lập bộ đếm thời gian để bọc một loạt mã và xem nó mất bao lâu.

console.time('create list');

for (i = 0; i < 1000; i++) {
    var myList = $('.myList');
    myList.append('This is list item ' + i);
}

console.timeEnd('create list');

ppl ở Iran không thể thấy các trang web được tải bằng google api. trong thực tế google đã hạn chế người Iran truy cập mã google. vì vậy -1
Alireza Eliaderani

Tôi chỉ phát hiện ra rằng bạn có thể sử dụng firebird trong bất kỳ trình duyệt nào. Thật tuyệt vời.
Tebo

9

Sử dụng các phương thức lọc qua các bộ chọn giả khi có thể để jQuery có thể sử dụng querySelectorAll (nhanh hơn nhiều so với sizzle). Hãy xem xét bộ chọn này:

$('.class:first')

Lựa chọn tương tự có thể được thực hiện bằng cách sử dụng:

$('.class').eq(0)

Cái nào phải nhanh hơn vì lựa chọn ban đầu của '. Class' tương thích với QSA


@ Nyuszika7H Tôi nghĩ bạn đang thiếu điểm. Vấn đề là QSA không thể tối ưu hóa hầu hết các bộ chọn giả, do đó $ ('. Class: eq (0)') sẽ chậm hơn $ ('. Class'). Eq (0).
Ralph Holzmann

9

Loại bỏ các yếu tố khỏi bộ sưu tập và bảo tồn tính chuỗi

Hãy xem xét những điều sau đây:

<ul>
    <li>One</li>
    <li>Two</li>
    <li>Three</li>
    <li>Four</li>
    <li>Five</li>
</ul>


$("li").filter(function()
{
    var text = $(this).text();

    // return true: keep current element in the collection
    if (text === "One" || text === "Two") return true;

    // return false: remove current element from the collection
    return false;
}).each(function ()
{
    // this will alert: "One" and "Two"       
    alert($(this).text());
});

Các filter()chức năng loại bỏ các yếu tố từ các đối tượng jQuery. Trong trường hợp này: Tất cả các phần tử li không chứa văn bản "Một" hoặc "Hai" sẽ bị xóa.


Có đơn giản hơn không khi chỉ sử dụng "từng" và di chuyển thay đổi lề trong công tắc?
DisgruntledGoat

Cập nhật câu trả lời của tôi. Xin vui lòng cho tôi biết nếu tôi làm cho mình rõ ràng (er)
cllpse

Điều này thực sự XÓA các yếu tố li? Nó dường như cảnh báo với một danh sách các yếu tố được lọc.
Cheeso

1
Hàm bộ lọc loại bỏ các phần tử khỏi bộ sưu tập bên trong đối tượng jQuery. Nó không ảnh hưởng đến DOM.
cllpse

6
Trong chức năng lọc của bạn, bạn có thể chỉ cần viết: return !! $ (this) .text (). Match (/ One | Two /); ;)
Vincent

8

Thay đổi loại phần tử đầu vào

Tôi gặp phải vấn đề này khi tôi đang cố gắng thay đổi loại phần tử đầu vào đã được gắn vào DOM. Bạn phải sao chép phần tử hiện có, chèn nó trước phần tử cũ và sau đó xóa phần tử cũ. Nếu không, nó không hoạt động:

var oldButton = jQuery("#Submit");
var newButton = oldButton.clone();

newButton.attr("type", "button");
newButton.attr("id", "newSubmit");
newButton.insertBefore(oldButton);
oldButton.remove();
newButton.attr("id", "Submit");

7

Việc sử dụng hợp lý các tập lệnh jQuery của bên thứ ba, chẳng hạn như xác thực trường biểu mẫu hoặc phân tích cú pháp url. Thật đáng để xem những gì về bạn sẽ biết khi bạn gặp phải một yêu cầu JavaScript tiếp theo.


7

Ngắt dòng và chuỗi

Khi kết nối nhiều cuộc gọi trên bộ sưu tập ...

$("a").hide().addClass().fadeIn().hide();

Bạn có thể tăng khả năng đọc với ngắt dòng. Như thế này:

$("a")
.hide()
.addClass()
.fadeIn()
.hide();

4
Trong trường hợp này, lần đầu tiên dễ đọc hơn, nhưng vâng, có một số trường hợp khi ngắt dòng tăng khả năng đọc.
nyuszika7h

7

Sử dụng .stop (đúng, đúng) khi kích hoạt hoạt ảnh sẽ ngăn không cho nó lặp lại hoạt hình. Điều này đặc biệt hữu ích cho hoạt hình cuộn qua.

$("#someElement").hover(function(){
    $("div.desc", this).stop(true,true).fadeIn();
},function(){
    $("div.desc", this).fadeOut();
});

7

Sử dụng các hàm ẩn danh tự thực hiện trong một cuộc gọi phương thức như .append()để lặp qua một cái gì đó. I E:

$("<ul>").append((function ()
{
    var data = ["0", "1", "2", "3", "4", "5", "6"],
        output = $("<div>"),
        x = -1,
        y = data.length;

    while (++x < y) output.append("<li>" + info[x] + "</li>");

    return output.children();
}()));

Tôi sử dụng điều này để lặp đi lặp lại qua những thứ sẽ lớn và không thoải mái để thoát ra khỏi chuỗi của tôi để xây dựng.


5

Hỗ trợ thuộc tính dữ liệu HTML5, trên steroid!

Các chức năng dữ liệu đã được đề cập trước đó. Với nó, bạn có thể liên kết dữ liệu với các thành phần DOM.

Gần đây, nhóm jQuery đã thêm hỗ trợ cho các thuộc tính dữ liệu tùy chỉnh HTML5 * . Và như thể điều đó là không đủ; họ đã cung cấp chức năng dữ liệu bằng steroid, điều đó có nghĩa là bạn có thể lưu trữ các đối tượng phức tạp dưới dạng JSON, trực tiếp trong đánh dấu của bạn.

HTML:

<p data-xyz = '{"str": "hi there", "int": 2, "obj": { "arr": [1, 2, 3] } }' />


JavaScript:

var data = $("p").data("xyz");

data.str // "hi there"
typeof data.str // "string"

data.int + 2 // 4
typeof data.int // "number"

data.obj.arr.join(" + ") + " = 6" // "1 + 2 + 3 = 6"
typeof data.obj.arr // "object" ... Gobbles! Errrghh!
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.