เคล็ดลับและเทคนิค jQuery


507

วากยสัมพันธ์

การจัดเก็บข้อมูล

การเพิ่มประสิทธิภาพ

เบ็ดเตล็ด

คำตอบ:


252

การสร้างองค์ประกอบ HTML และการอ้างอิง

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 */


ตรวจสอบว่ามีองค์ประกอบอยู่หรือไม่

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


เขียนตัวเลือกของคุณเอง

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

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

93
การเขียนตัวเลือกของคุณเองนั้นค่อนข้างเรียบเนียน
Hugoware

22
นอกจากนี้หากมีความช่วยเหลือคุณสามารถทำ $ ("<div />") และทำสิ่งเดียวกันกับ $ ("<div> </div>")
Hugoware

4
ฉันชอบส่วนตัวเลือกใหม่ไม่รู้เรื่องนั้น
Pim Jager

5
เนื่องจากฉันยังไม่สามารถแก้ไขวิกิชุมชน: รวมการมอบหมายและการตรวจสอบการมีอยู่กับif ((var someDiv = $("#someDiv")).length) { /* do stuff with someDiv... */ }
Ben Blank

4
@Ben: เหตุผลที่ฉันหลีกเลี่ยงสำนวนเช่นนั้นใน JavaScript คือเพราะฉันไม่ต้องการให้ภาพลวงตาของsomeDivการถูกกำหนดขอบเขตในifคำสั่งเพราะมันไม่ได้; JavaScript รองรับขอบเขตฟังก์ชั่นเท่านั้น
Andreas Grech

111

data()วิธีการของ jQuery นั้นมีประโยชน์และไม่เป็นที่รู้จัก จะช่วยให้คุณผูกข้อมูลกับองค์ประกอบ DOM โดยไม่ต้องแก้ไข DOM


4
data () เป็นประโยชน์อย่างมาก
Pim Jager

3
ฉันสังเกตเห็นว่ามันไม่ทำงานกับองค์ประกอบที่ไม่มีรหัสประจำตัว
นักคิด

20
@ นักคิด: ใช่มันเป็นเช่นนั้น
Alex Barrett

ใช้ data () แทนการประกาศตัวแปร js ทั่วโลก imo
Johan


80

ฉันไม่ใช่แฟนของ$(document).ready(fn)ทางลัดจริงๆ แน่นอนว่ามันลดรหัส แต่ยังลดความสามารถในการอ่านของรหัสได้อีกด้วย เมื่อคุณเห็น$(document).ready(...)คุณจะรู้ว่าคุณกำลังมองอะไรอยู่ $(...)มีการใช้ในวิธีอื่น ๆ อีกมากมายเกินกว่าที่จะเข้าใจได้ทันที

หากคุณมีหลายเฟรมเวิร์กคุณสามารถใช้jQuery.noConflict();ตามที่คุณพูดได้ แต่คุณยังสามารถกำหนดตัวแปรอื่นให้กับมันดังนี้:

var $j = jQuery.noConflict();

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

มีประโยชน์มากถ้าคุณมีเฟรมเวิร์กต่าง ๆ ที่สามารถนำไปต้มกับการ$x(...)เรียกแบบ


1
@Oli: เกี่ยวกับเอกสารแบบย่อ คุณมีประเด็น แต่ไม่เคยน้อย: มันเป็นเคล็ดลับ / เคล็ดลับ หนึ่งที่ฉันใช้ในรหัสของฉันหมดจดเพราะฉันคิดว่ามัน "ดู" ดีกว่า เรื่องของการตั้งค่าส่วนตัวผมคิดว่า :)
cllpse

ทุกวันที่ฉันลุยผ่าน XML / XLS / XLST ที่ไม่มีจุดหมายไซต์ที่เขียนด้วยเลเยอร์ที่เป็นนามธรรมมากเกินไประบบที่ล้มเหลวที่ซับซ้อนบนไซต์ที่จะไม่เจริญเกินความถ่อมตัวของเซิร์ฟเวอร์ ... และคนก็บ่นเกี่ยวกับความแตกต่างระหว่าง $ ( <string>) & $ (<function>) ทำให้ฉันอยากร้องไห้ :)
JoeBloggs

เมื่อฉันเห็น $ (function () {... }) ฉันรู้ว่าเกิดอะไรขึ้น สิ่งที่ปกติมากขึ้นควรสั้นลง นั่นเป็นเหตุผลที่เราเปลี่ยนรหัสที่เรียกว่าชิ้นส่วนโค้ดเป็นฟังก์ชัน
luikore

77

โอ้โหอย่าลืมjQuery metadata ! ฟังก์ชั่น data () ยอดเยี่ยม แต่จะต้องมีการเติมข้อมูลผ่านการโทร jQuery

แทนที่จะทำลายการปฏิบัติตาม W3C ด้วยแอตทริบิวต์องค์ประกอบที่กำหนดเองเช่น:

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

ใช้ข้อมูลเมตาแทน:

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

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

7
แอตทริบิวต์ข้อมูล html5 ทำให้ปัญหานี้น้อยลง มีการพูดคุยกันอย่างไม่หยุดหย่อนในการนำคุณลักษณะของข้อมูล html5 แบบอินไลน์พร้อมกับฟังก์ชั่น data ของ jquery (): forum.jquery.com/topic/ …
Oskar Austegard

10
@Oskar - yep สิ่งนี้ได้ถูกนำมาใช้ใน jQuery 1.4.3 - data-*คุณลักษณะจะพร้อมใช้งานโดยอัตโนมัติผ่านการเรียกไปที่.data()
nickf

73

ตัวจัดการเหตุการณ์สด

ตั้งค่าตัวจัดการเหตุการณ์สำหรับองค์ประกอบใด ๆที่ตรงกับตัวเลือกแม้ว่าจะได้รับการเพิ่มใน DOM หลังจากโหลดหน้าเริ่มต้น:

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

สิ่งนี้จะช่วยให้คุณสามารถโหลดเนื้อหาผ่าน ajax หรือเพิ่มผ่าน javascript และตั้งค่าตัวจัดการเหตุการณ์ให้ถูกต้องสำหรับองค์ประกอบเหล่านั้นโดยอัตโนมัติ

ในทำนองเดียวกันเมื่อต้องการหยุดการจัดการเหตุการณ์สด:

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

ตัวจัดการเหตุการณ์สดเหล่านี้มีข้อ จำกัด เล็กน้อยเมื่อเทียบกับเหตุการณ์ปกติ แต่ก็ใช้งานได้ดีสำหรับกรณีส่วนใหญ่

สำหรับข้อมูลเพิ่มเติมโปรดดูที่เอกสาร jQuery

อัปเดต: live()และdie()เลิกใช้แล้วใน jQuery 1.7 ดูhttp://api.jquery.com/on/และhttp://api.jquery.com/off/สำหรับฟังก์ชั่นการเปลี่ยนที่คล้ายกัน

UPDATE2: live()เลิกใช้มานานแม้กระทั่งก่อน jQuery 1.7 สำหรับรุ่น jQuery 1.4.2+ ก่อน 1.7 การใช้งานและdelegate() undelegate()live()ตัวอย่าง ( $('button.someClass').live('click', someFunction);) สามารถเขียนใหม่โดยใช้ที่ต้องการที่:delegate()$(document).delegate('button.someClass', 'click', someFunction);


1
ใช่ฉันรักสิ่งสดใหม่ โปรดทราบว่าใช้งานได้เริ่มต้นด้วย jQuery 1.3 เท่านั้น
Nosredna

4
+ 1.. คุณช่วยฉันได้มากจากอาการปวดหัวใจ .. ฉันเพิ่งอ่านรายการของคุณและในขณะที่ฉันกำลังพักการแก้ปัญหาทำไมงานของฉันถึงไม่ยิง ขอบคุณ
Luke101

2
สำหรับผู้มาสายคนอื่น ๆ ในบทความนี้คุณอาจต้องการดูผู้แทน (): api.jquery.com/delegate คล้ายกับการถ่ายทอดสด แต่มีประสิทธิภาพมากขึ้น
Oskar Austegard

2
เพียงแค่จำ. live bubble ขึ้นสู่ร่างกายเพื่อให้เหตุการณ์สดที่ถูกผูกไว้สามารถยิงได้ หากมีบางสิ่งในระหว่างที่ยกเลิกกิจกรรมนั้นเหตุการณ์สดจะไม่เริ่มขึ้น
nickytonline

1
สด () และตาย () เป็นวิธีการคัดค้านตั้งแต่ jQuery 1.7 ปล่อยตัวพฤศจิกายน 3 ถูกแทนที่ด้วยเมื่อ (), api.jquery.com/onและ off (), api.jquery.com/off
Johan

46

แทนที่ฟังก์ชั่นที่ไม่ระบุชื่อด้วยฟังก์ชั่นที่มีชื่อ นี่ยิ่งทำให้บริบท jQuery เป็นจริงมากขึ้น แต่มันเข้ามาเล่นมากขึ้นดูเหมือนว่าเมื่อใช้ jQuery เนื่องจากพึ่งพาฟังก์ชั่นการโทรกลับ ปัญหาที่ฉันมีกับฟังก์ชั่นไม่ระบุชื่อแบบอินไลน์คือพวกเขายากที่จะดีบั๊ก (ง่ายกว่ามากที่จะดู callstack ด้วยฟังก์ชั่นที่มีชื่อชัดเจนแทนที่จะเป็น "นิรนาม" 6 ระดับ) และความจริงที่ว่า jQuery-chain สามารถกลายเป็นไม่สะดวกในการอ่านและ / หรือบำรุงรักษา นอกจากนี้ฟังก์ชั่นที่ไม่ระบุชื่อมักจะไม่ถูกใช้ซ้ำ ในทางกลับกันการประกาศฟังก์ชั่นที่มีชื่อสนับสนุนให้ฉันเขียนโค้ดที่มีแนวโน้มที่จะถูกใช้ซ้ำ

ภาพประกอบ; แทน:

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

ฉันชอบ:

function onState(){
    // do something
}

function offState(){
    // do something else
}

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

น่าเสียดายเนื่องจาก jQuery ส่งผ่านเป้าหมายเหตุการณ์เนื่องจากthisคุณไม่สามารถรับ OO ที่ "เหมาะสม" โดยไม่ต้องใช้สิ่งที่แนบมา ฉันมักจะไปสำหรับการประนีประนอม:$('div').click( function(e) { return self.onClick(e) } );
เบน Blank

3
ฉันขอโทษเบ็น แต่ฉันไม่เห็นว่าความคิดเห็นของคุณมีความเกี่ยวข้องกับโพสต์ของฉันอย่างไร คุณสามารถทำอย่างละเอียด? คุณยังสามารถใช้ 'ตัวเอง' (หรือตัวแปรอื่น ๆ ) โดยใช้คำแนะนำของฉัน; มันจะไม่เปลี่ยนแปลงสิ่งใดเลย
ken

ใช่เบ็นคุณหมายถึงอะไรกันแน่!
James

2
ฉันต้องพูดถึง: ตัวแปรที่ทำจากขนสัตว์และฟังก์ชั่นใน namespace ไม่ได้อยู่ในรูทเสมอ !!
jmav

45

การกำหนดคุณสมบัติที่การสร้างองค์ประกอบ

ใน jQuery 1.4 คุณสามารถใช้วัตถุตามตัวอักษรเพื่อกำหนดคุณสมบัติเมื่อคุณสร้างองค์ประกอบ:

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

... คุณสามารถเพิ่มสไตล์:

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

นี่คือการเชื่อมโยงไปยังเอกสาร


43

แทนที่จะใช้นามแฝงที่แตกต่างกันสำหรับวัตถุ jQuery (เมื่อใช้ noConflict) ฉันมักจะเขียนรหัส jQuery ของฉันโดยห่อมันทั้งหมดในการปิด สามารถทำได้ในฟังก์ชั่น document.ready:

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

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

หรือคุณสามารถทำสิ่งนี้ได้:

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

ฉันคิดว่านี่เป็นอุปกรณ์พกพาที่ดีที่สุด ฉันทำงานบนไซต์ที่ใช้ทั้ง Prototype และ jQuery พร้อมกันและเทคนิคเหล่านี้ได้หลีกเลี่ยงความขัดแย้งทั้งหมด


ตัวอย่างที่สองคือ nice'r สำหรับดวงตา :)
cllpse

25
มีความแตกต่างแม้ว่าตัวอย่างแรกจะรอให้เหตุการณ์ document.ready () ลั่นขณะที่สองจะไม่ทำงาน
SamBeran

1
@ SamBeran: จริงตัวอย่างที่สองจะทำงานทันที อย่างไรก็ตามหากคุณกำลังล้อมวัตถุ - ตัวอักษรคุณสามารถใช้ $ (เอกสาร). ready (... ) ภายในวัตถุ - ตัวอักษรซึ่งหมายความว่าคุณสามารถระบุเมื่อคุณต้องการเรียกใช้รหัสแต่ละชิ้น
Wil Moore III

4
instanceOfinstanceofจะไม่ทำงานเท่านั้น และมันจะไม่ทำงานต่อไปเพราะจะกลับมาjQuery instanceof jQuery เป็นวิธีที่ถูกต้องที่จะทำ false$ == jQuery
nyuszika7h

@ Nyuszika7H: ใช่คุณพูดถูก แต่นั่นไม่ใช่จุดตัวอย่างรหัสจริงๆ
nickf

39

ตรวจสอบดัชนี

jQuery มี. index แต่มันเป็นความเจ็บปวดที่จะใช้ตามที่คุณต้องการรายการองค์ประกอบและส่งผ่านองค์ประกอบที่คุณต้องการดัชนีของ:

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

ต่อไปนี้ง่ายกว่ามาก:

หากคุณต้องการทราบดัชนีขององค์ประกอบภายในชุด (เช่นรายการในรายการ) ภายในรายการที่ไม่เรียงลำดับ:

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

มีอะไรผิดปกติกับวิธีการ core index ()? มันอยู่ในแกนตั้งแต่ 1.2 อย่างน้อย docs.jquery.com/Core/index
ken

ตกลงใช่ฉันเล่นเป็นทนายของมารบ้างเพราะเมื่อฉันทบทวนดัชนีของ jQuery () ฉันรู้ว่ามันเป็นความเจ็บปวดในก้น ขอขอบคุณสำหรับการชี้แจง!
เคน

4
นี่มันเจ๋ง แต่สำคัญที่ต้องรู้ว่ามันไม่ได้ผลนักถ้าคุณมีพี่น้องก่อนหน้านี้ที่ไม่ได้เป็นส่วนหนึ่งของการคัดเลือก
TM

2
ฉันค่อนข้างมั่นใจตั้งแต่ jQuery 1.4 คุณสามารถใช้index()และรับดัชนีจากพาเรนต์
alex

@alex - แน่นอน แต่โปรดทราบวันที่ของโพสต์นี้ - มันเป็นเวลา 5 เดือนก่อนการเปิดตัว 1.4
redsquare

23

จดชวเลขสำหรับเหตุการณ์ที่พร้อม

วิธีที่ชัดเจนและ verbose:

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

จดชวเลข:

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

22

บนฟังก์ชัน core jQuery ให้ระบุพารามิเตอร์บริบทเพิ่มเติมจากพารามิเตอร์ตัวเลือก การระบุพารามิเตอร์บริบทอนุญาตให้ jQuery เริ่มต้นจากสาขาที่ลึกกว่าใน DOM ไม่ใช่จากรูท DOM ได้รับ DOM ที่มีขนาดใหญ่เพียงพอการระบุพารามิเตอร์บริบทควรแปลเป็นผลการดำเนินงานที่เพิ่มขึ้น

ตัวอย่าง: ค้นหาอินพุตทั้งหมดของชนิดวิทยุภายในฟอร์มแรกในเอกสาร

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

การอ้างอิง: http://docs.jquery.com/Core/jQuery#expressioncontext


10
หมายเหตุ: $(document.forms[0]).find('input:radio')ทำสิ่งเดียวกัน หากคุณดูที่แหล่ง jQuery คุณจะเห็น: หากคุณส่งพารามิเตอร์ตัวที่สองให้กับ$มันจะเป็นการเรียกจริง.find()
nyuszika7h

สิ่งที่เกี่ยวกับ ... $('form:first input:radio')?
daGrevis

Paul Irish ชี้ให้เห็นในpaulirish.com/2009/perf (เริ่มที่สไลด์ 17) ว่าการทำเช่นนี้คือ "ย้อนกลับ" จากมุมมองที่สามารถอ่านได้ ดังที่ @ Nyuszika7H ชี้ให้เห็นมันใช้. find () ภายในและ $ (document.forms [0]). find ('input: radio') นั้นอ่านง่ายมากเมื่อเทียบกับการใส่บริบทในตัวเลือกเริ่มต้น
LocalPCGuy

21

ไม่ใช่แค่ jQuery เท่านั้น แต่ฉันสร้างสะพานเล็ก ๆ สำหรับ jQuery และ MS AJAX:

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

เป็นเรื่องที่ดีมากถ้าคุณทำ ASP.NET AJAX จำนวนมากเนื่องจาก jQuery ได้รับการสนับสนุนโดย MS ขณะนี้มีบริดจ์ที่ดีหมายความว่าง่ายต่อการดำเนินการ jQuery:

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

ตัวอย่างข้างต้นไม่ดี แต่ถ้าคุณเขียนตัวควบคุมเซิร์ฟเวอร์ ASP.NET AJAX ทำให้ง่ายต่อการมี jQuery ในการใช้งานการควบคุมฝั่งไคลเอ็นต์ของคุณ


ห้องสมุด clientside อาแจ็กซ์ไม่ให้วิธีการในการหาการควบคุมตามหมายเลขเดิมที่คุณได้รับมอบหมาย (ในที่อยู่เบื้องหลังรหัส)
คริส S

this.get_id () จะส่งคืน ID ของการควบคุมในขอบเขตลูกค้า ID ที่ระบุโดยเซิร์ฟเวอร์นั้นไม่เกี่ยวข้องเนื่องจาก ID ไคลเอ็นต์ถูกสร้างขึ้นตามลำดับของผู้ปกครอง cotrol
Aaron Powell

20

ปรับแต่งประสิทธิภาพของตัวเลือกที่ซับซ้อน

สอบถามเซ็ตย่อยของ DOM เมื่อใช้ตัวเลือกที่ซับซ้อนช่วยปรับปรุงประสิทธิภาพอย่างมาก:

var subset = $("");

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

7
เฉพาะในกรณีที่ชุดย่อยนั้นถูกแคช / บันทึกไว้
Dykam

6
นั่นไม่แตกต่างจาก $ ("") เท่าไร find ("input [value ^ = '']")
Chad Moran

1
@Dykam: ซึ่งเป็นในกรณีของรหัสตัวอย่างของฉัน แต่ประเด็นของคุณยังคงใช้ได้
cllpse

4
@Chad มันเหมือนจริงและแมปไปยังฟังก์ชั่นที่คุณเขียน
Mike Robinson

19

การพูดถึงเคล็ดลับและลูกเล่นรวมทั้งแบบฝึกหัดบางอย่าง ฉันพบชุดบทช่วยสอนเหล่านี้ ( “ jQuery for Absolute Beginners” ชุดวิดีโอ)โดยJeffery Wayเป็นประโยชน์อย่างมาก

มันกำหนดเป้าหมายนักพัฒนาผู้ที่ยังใหม่กับ jQuery เขาแสดงวิธีการสร้างสิ่งดีๆมากมายด้วย jQuery เช่นภาพเคลื่อนไหวการสร้างและการลบองค์ประกอบและอื่น ๆ ...

ฉันเรียนรู้อะไรมากมายจากมัน เขาแสดงให้เห็นว่าการใช้ jQuery ง่ายเพียงใด ตอนนี้ฉันรักมันและฉันสามารถอ่านและเข้าใจสคริปต์ jQuery ใด ๆ แม้ว่ามันจะซับซ้อน

นี่คือตัวอย่างหนึ่งที่ฉันชอบ "การปรับขนาดข้อความ "

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>

สไตล์ CSS 2 ...

<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>

ขอแนะนำบทเรียนเหล่านี้ ...

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


19

ไม่ตรงกันแต่ละฟังก์ชั่น ()

หากคุณมีเอกสารที่ซับซ้อนจริงๆที่เรียกใช้ jQuery แต่ละฟังก์ชัน()จะล็อคเบราว์เซอร์ในระหว่างการทำซ้ำและ / หรือ Internet Explorer จะปรากฏข้อความ ' คุณต้องการเรียกใช้สคริปต์นี้ต่อไปหรือไม่ ' โซลูชันนี้จะบันทึกวัน

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
};


วิธีแรกที่คุณสามารถใช้มันก็เหมือนกัน ():

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

พารามิเตอร์ 2 ตัวเลือกให้คุณสามารถระบุความเร็ว / ความล่าช้าในระหว่างการทำซ้ำซึ่งอาจจะเป็นประโยชน์สำหรับภาพเคลื่อนไหว ( ตัวอย่างต่อไปนี้จะรอ 1 วินาทีในระหว่างการทำซ้ำ ):

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

โปรดจำไว้ว่าเนื่องจากสิ่งนี้ทำงานแบบอะซิงโครนัสคุณไม่สามารถพึ่งพาการวนซ้ำเพื่อทำให้สมบูรณ์ก่อนหน้าบรรทัดถัดไปของโค้ดตัวอย่างเช่น

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


ฉันเขียนสิ่งนี้สำหรับโครงการภายในและในขณะที่ฉันมั่นใจว่าจะสามารถปรับปรุงได้มันทำงานได้ตามที่เราต้องการดังนั้นหวังว่าบางท่านจะเห็นว่ามีประโยชน์ ขอบคุณ -


18

Synthactic shorthand-sugar-things - แคชการรวบรวมวัตถุและรันคำสั่งในหนึ่งบรรทัด:

แทน:

var jQueryCollection = $("");

jQueryCollection.command().command();

ฉันทำ:

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

กรณีการใช้งาน "ของจริง" ค่อนข้างจะเป็นสิ่งที่ตามสาย:

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

4
ดีกว่าที่จะใส่ $ (นี้) อ้างอิงในตัวแปรท้องถิ่นเพราะคุณ wil ใช้เวลาเล็กน้อย perfomance กดที่นี่เพราะมันจะใช้เวลาเล็ก ๆ น้อย ๆ อีกต่อไป ...
Sander Versluys

4
ในกรณีนี้ (ไม่มีการเล่นสำนวน) ฉันใช้ "นี่" เพียงครั้งเดียว ไม่ต้องแค
cllpse

1
เคล็ดลับเล็ก ๆ แม้ว่ามันจะไม่สำคัญในกรณีนี้ แต่ก็เป็นความคิดที่ดีที่จะทำการเปลี่ยนแปลงเพิ่มเติมใน DOM พูดเช่นองค์ประกอบที่คุณวางตัวอยู่เหนือมีคลาส "โฮเวอร์" คุณจะลบชั้นนี้และเพิ่มอีกครั้ง $(this).siblings().removeClass("hover")คุณจะได้รับรอบว่า ฉันรู้ว่ามันฟังดูเล็ก ๆ น้อย ๆ แต่ทุกครั้งที่คุณเปลี่ยน DOM เบราว์เซอร์อื่นอาจมีการเรียกใช้การวาดใหม่ ความเป็นไปได้อื่น ๆ ได้แก่ เหตุการณ์ที่แนบกับ DOMAttrModified หรือคลาสที่เปลี่ยนความสูงขององค์ประกอบ
gradbot

1
หากคุณต้องการใช้แคชและลดการเปลี่ยนแปลง DOM คุณสามารถทำได้ cache.not(this).removeClass("hover")
gradbot

@gradbot: ฉันไม่เข้าใจความคิดเห็นสองรายการสุดท้ายของคุณ คุณสามารถขยายหรือไม่
Randomblue

15

ฉันชอบประกาศ$thisตัวแปรที่จุดเริ่มต้นของฟังก์ชั่นที่ไม่ระบุชื่อดังนั้นฉันรู้ว่าฉันสามารถอ้างอิง jQueried นี้

ชอบมาก

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

    // Other code
});

12
ผมใช้ "ว่า" แทน :)
cllpse

2
ROA: ใช่แล้วนั่นจะเป็นกรด :) คุณยังสามารถใช้อาร์กิวเมนต์
callee

5
โจ - แค่หัวค่ำผู้คนจะไปด้วย ECMAScript 5 และโหมดเข้มงวด ดู: ejohn.org/blog/ecmascript-5-strict-mode-json-and-more
Mike Robinson

@ Joe คุณสามารถให้มันชื่อเพียงแค่ต้องระวังนิสัยใจคอของ IE
alex

ตัวอย่างที่ดีของการใช้ $ ที่จุดเริ่มต้นของชื่อตัวแปรเพื่อระบุตัวแปรวัตถุ jQuery เมื่อเปรียบเทียบกับตัวแปรมาตรฐาน โดยการเพิ่มเข้าไปที่จุดเริ่มต้นของตัวแปรใด ๆ ที่กำลังแคชวัตถุ jQuery คุณจะรู้ได้ทันทีด้วยการดูว่าคุณสามารถทำหน้าที่ jQuery บนตัวแปรได้ ทำให้โค้ดอ่านได้มากขึ้นในทันที
LocalPCGuy

14

บันทึก jQuery Objects ใน Variables เพื่อใช้ซ้ำ

การบันทึกออบเจ็กต์ jQuery เป็นตัวแปรช่วยให้คุณสามารถนำกลับมาใช้ใหม่ได้โดยไม่ต้องค้นหาผ่าน DOM เพื่อค้นหา

(ตามที่ @Louis แนะนำตอนนี้ฉันใช้ $ เพื่อระบุว่าตัวแปรถือวัตถุ 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...

เป็นตัวอย่างที่ซับซ้อนมากขึ้นสมมติว่าคุณมีรายการอาหารในร้านค้าและคุณต้องการแสดงเฉพาะอาหารที่ตรงกับเกณฑ์ของผู้ใช้ คุณมีฟอร์มที่มีช่องทำเครื่องหมายแต่ละอันมีเกณฑ์ ช่องทำเครื่องหมายมีชื่อเหมือนorganicและlowfatและผลิตภัณฑ์มีคลาสที่สอดคล้องกัน - .organicและอื่น ๆ

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

ตอนนี้คุณสามารถทำงานกับวัตถุ jQuery ต่อไปได้ ทุกครั้งที่มีการคลิกช่องทำเครื่องหมาย (เพื่อทำเครื่องหมายหรือยกเลิกการเลือก) ให้เริ่มจากรายการอาหารหลักและกรองตามกล่องที่เลือก:

// 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
แบบแผนการตั้งชื่อของฉันคือการมี$ด้านหน้า เช่นvar $allItems = ...
หลุยส์

6
@Lavinski - ฉันคิดว่าความคิดคือการ$ระบุว่านี่เป็นวัตถุ jQuery ซึ่งจะทำให้ง่ายต่อการเห็นความแตกต่างจากตัวแปรอื่น ๆ
Nathan Long

@Louis - ตั้งแต่ฉันได้รับรองการประชุมของคุณและจะอัปเดตคำตอบของฉันตาม :)
นาธานลอง

11

ดูเหมือนว่าเคล็ดลับที่สำคัญและน่าสนใจส่วนใหญ่ได้ถูกกล่าวถึงไปแล้วดังนั้นนี่จึงเป็นเพียงส่วนเสริมเล็กน้อย

เคล็ดลับเล็ก ๆ คือฟังก์ชั่นjQuery.each (object, callback) ทุกคนน่าจะใช้ฟังก์ชัน jQuery.each (callback)เพื่อวนซ้ำวัตถุ jQuery เพราะมันเป็นเรื่องธรรมดา ฟังก์ชันยูทิลิตี้ jQuery.each (object, callback) จะวนซ้ำวัตถุและอาร์เรย์ เป็นเวลานานฉันไม่เห็นว่ามันจะเป็นอะไรที่แตกต่างจากไวยากรณ์ที่แตกต่างกัน (ฉันไม่รังเกียจที่จะเขียนลูปที่ล้าสมัยทั้งหมด) และฉันรู้สึกละอายใจเล็กน้อยที่ฉันตระหนักถึงความแข็งแกร่งหลักของมันเมื่อเร็ว ๆ นี้

สิ่งนี้คือเนื่องจากเนื้อความของลูปใน jQuery.each (object, callback) เป็นฟังก์ชั่นคุณจะได้รับขอบเขตใหม่ทุกครั้งในลูปซึ่งสะดวกมากเป็นพิเศษเมื่อคุณสร้างการปิดในลูป

กล่าวอีกนัยหนึ่งข้อผิดพลาดทั่วไปทั่วไปคือการทำสิ่งที่ชอบ:

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

ตอนนี้เมื่อคุณเรียกใช้ฟังก์ชั่นในfunctionsอาร์เรย์คุณจะได้รับการแจ้งเตือนสามครั้งด้วยเนื้อหาundefinedที่ไม่น่าจะเป็นสิ่งที่คุณต้องการ ปัญหาคือมีตัวแปรเพียงตัวเดียวiและการปิดทั้งสามอ้างถึงมัน เมื่อวงเสร็จสิ้นค่าสุดท้ายของi3 และเป็นsomeArrary[3] undefinedคุณสามารถหลีกเลี่ยงได้โดยการเรียกฟังก์ชั่นอื่นซึ่งจะสร้างการปิดสำหรับคุณ หรือคุณใช้ยูทิลิตี jQuery ซึ่งโดยพื้นฐานแล้วมันจะทำเพื่อคุณ:

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

ตอนนี้เมื่อคุณเรียกใช้ฟังก์ชั่นคุณจะได้รับการแจ้งเตือนสามครั้งด้วยเนื้อหา 1, 2 และ 3 ตามที่คาดไว้

โดยทั่วไปแล้วมันเป็นอะไรที่คุณไม่สามารถทำเองได้ แต่มันก็ดีที่มี


11

เข้าถึงฟังก์ชัน jQuery ตามที่คุณต้องการในอาร์เรย์

เพิ่ม / ลบคลาสที่ยึดตามบูลีน ...

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

เป็นรุ่นที่สั้นกว่าของ ...

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

ไม่ว่าจะมีหลายกรณีสำหรับการใช้งานนี้ แต่ถึงอย่างไร; ฉันคิดว่ามันเรียบร้อย :)


ปรับปรุง

ในกรณีที่คุณไม่ใช่ประเภทการอ่านความคิดเห็น ThiefMaster ชี้ให้เห็นว่าtoggleClass ยอมรับค่าบูลีนซึ่งกำหนดว่าควรเพิ่มหรือลบคลาสหรือไม่ ดังนั้นเท่าที่โค้ดตัวอย่างของฉันไปมันจะเป็นวิธีที่ดีที่สุด ...

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

2
นี่เป็นระเบียบและมีการใช้งานที่น่าสนใจ แต่ก็ไม่ได้มีอะไรเฉพาะเจาะจงกับ jQuery เลย ... นี่เป็นสิ่งที่คุณสามารถทำได้บนวัตถุ JavaScript ใด ๆ
TM

1
ขอบคุณ :) ... มันเป็นจาวาสคริปต์พื้นฐาน ใช่. แต่ฉันจะยืนยันว่า jQuery เป็น JavaScript ฉันไม่ได้อ้างว่านี่เป็นเฉพาะ jQuery
cllpse

7
ในกรณีเฉพาะนี้คุณต้องการใช้$('selector').toggleClass('name_of_the_class', b);จริงๆ
ThiefMaster

9

ปรับปรุง:

เพียงรวมสคริปต์นี้ไว้ในเว็บไซต์และคุณจะได้รับคอนโซล Firebug ที่ปรากฏขึ้นเพื่อการดีบักในเบราว์เซอร์ใด ๆ คุณสมบัติไม่เต็มค่อนข้าง แต่ก็ยังมีประโยชน์อยู่! อย่าลืมลบมันเมื่อคุณทำเสร็จแล้ว

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

ลองลิงค์นี้:

จาก CSS Tricks

อัปเดต: ฉันพบสิ่งใหม่ มันคือ JQuery Hotbox

JQuery Hotbox

Google โฮสต์ห้องสมุด JavaScript หลายแห่งใน Google Code การโหลดจากที่นั่นจะช่วยประหยัดแบนด์วิดท์และโหลดได้อย่างรวดเร็วเพราะถูกแคชไว้แล้ว

<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>

หรือ

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

คุณยังสามารถใช้สิ่งนี้เพื่อบอกว่าเมื่อใดที่ภาพเต็ม

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

"console.info" ของ firebug ซึ่งคุณสามารถใช้เพื่อถ่ายโอนข้อความและตัวแปรไปยังหน้าจอโดยไม่ต้องใช้กล่องเตือน "console.time" ช่วยให้คุณสามารถตั้งค่าตัวจับเวลาเพื่อห่อโค้ดได้อย่างง่ายดายและดูว่าต้องใช้เวลานานแค่ไหน

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 ในอิหร่านไม่เห็นหน้าเว็บที่โหลดด้วย google api อันที่จริง google มีข้อ จำกัด ของชาวอิหร่านในการเข้าถึงรหัส Google ดังนั้น -1
Alireza Eliaderani

ฉันเพิ่งค้นพบว่าคุณสามารถใช้ firebug ในเบราว์เซอร์ใดก็ได้ ที่น่ากลัว.
Tebo

9

ใช้วิธีการกรองผ่านตัวเลือกหลอกหากเป็นไปได้ดังนั้น jQuery สามารถใช้ querySelectorAll (ซึ่งเร็วกว่าเสียงดังฉ่า) พิจารณาตัวเลือกนี้:

$('.class:first')

การเลือกเดียวกันสามารถทำได้โดยใช้:

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

ซึ่งจะต้องเร็วกว่าเพราะการเลือกเริ่มต้นของ '.class' นั้นเข้ากันได้กับ QSA


@ Nyuszika7H ฉันคิดว่าคุณไม่มีจุด ประเด็นก็คือว่า QSA ไม่สามารถเพิ่มประสิทธิภาพตัวเลือกหลอกที่สุดดังนั้น $ ('. class: eq (0)') จะช้ากว่า $ ('. class'). eq (0)
Ralph Holzmann

9

ลบองค์ประกอบออกจากคอลเลกชันและรักษาความสามารถในการโซ่

พิจารณาสิ่งต่อไปนี้:

<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());
});

filter()ฟังก์ชั่นเอาองค์ประกอบจากวัตถุ jQuery ในกรณีนี้: องค์ประกอบ li ทั้งหมดที่ไม่มีข้อความ "หนึ่ง" หรือ "สอง" จะถูกลบออก


มันง่ายกว่าหรือไม่ที่จะใช้ "แต่ละ" และย้ายการเปลี่ยนแปลงระยะขอบภายในสวิตช์?
DisgruntledGoat

อัปเดตคำตอบของฉัน กรุณาแจ้งให้เราทราบว่าถ้าฉันทำให้ตัวเองล้าง (ER)
cllpse

สิ่งนี้ลบองค์ประกอบ li จริงๆได้หรือไม่? ดูเหมือนว่าจะแจ้งเตือนด้วยรายการองค์ประกอบที่ถูกกรอง
Cheeso

1
ฟังก์ชั่นตัวกรองลบองค์ประกอบออกจากคอลเลกชันภายในวัตถุ jQuery มันไม่ส่งผลกระทบต่อ DOM
cllpse

6
ในฟังก์ชันตัวกรองของคุณคุณสามารถเขียน: return !! $ (this) .text (). match (/ One | Two /); ;)
Vincent

8

การเปลี่ยนประเภทขององค์ประกอบอินพุต

ฉันพบปัญหานี้เมื่อฉันพยายามเปลี่ยนประเภทขององค์ประกอบอินพุตที่เชื่อมต่อกับ DOM แล้ว คุณต้องโคลนองค์ประกอบที่มีอยู่แทรกไว้ก่อนองค์ประกอบเก่าแล้วลบองค์ประกอบเก่า มิฉะนั้นมันจะไม่ทำงาน:

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

การใช้สคริปต์ jQuery ของบุคคลที่สามอย่างมีเหตุผลเช่นการตรวจสอบความถูกต้องของเขตข้อมูลฟอร์มหรือการแยกวิเคราะห์ URL คุณควรรู้ว่าจะต้องทำอย่างไรเมื่อคุณพบข้อกำหนด JavaScript ครั้งต่อไป


7

ตัวแบ่งบรรทัดและความสามารถในการโซ่

เมื่อผูกสายหลายคอลเลกชัน ...

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

คุณสามารถเพิ่มความสามารถในการอ่านด้วยการแบ่งบรรทัด แบบนี้:

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

4
ในกรณีนี้กรณีแรกสามารถอ่านได้มากกว่า แต่มีบางกรณีที่ตัวแบ่งบรรทัดเพิ่มการอ่าน
nyuszika7h

7

ใช้. stop (จริง, จริง) เมื่อเรียกภาพเคลื่อนไหวป้องกันไม่ให้ภาพเคลื่อนไหวซ้ำ สิ่งนี้มีประโยชน์อย่างยิ่งสำหรับภาพเคลื่อนไหวแบบโรลโอเวอร์

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

7

การใช้ฟังก์ชั่นที่ไม่ระบุชื่อดำเนินการด้วยตนเองในการเรียกใช้เมธอดเช่น.append()ทำซ้ำผ่านบางสิ่ง IE:

$("<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();
}()));

ฉันใช้สิ่งนี้เพื่อย้ำผ่านสิ่งต่าง ๆ ที่จะมีขนาดใหญ่และอึดอัดที่จะแยกออกจากการผูกมัดของฉันที่จะสร้าง


5

สนับสนุนคุณลักษณะข้อมูล HTML5 บนสเตียรอยด์!

ฟังก์ชั่นข้อมูลที่ได้รับการกล่าวถึงก่อน ด้วยคุณสามารถเชื่อมโยงข้อมูลกับองค์ประกอบ DOM

เมื่อเร็ว ๆ นี้ทีม jQuery ได้เพิ่มการสนับสนุนสำหรับHTML5 แอตทริบิวต์ และราวกับว่ายังไม่พอ พวกมันบังคับให้ฟีดข้อมูลทำงานด้วยสเตอรอยด์ซึ่งหมายความว่าคุณสามารถเก็บวัตถุที่ซับซ้อนในรูปแบบของ JSON ได้โดยตรงในมาร์กอัปของคุณ

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!
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.