วิธีที่ดีที่สุดในการใช้ jQuery ที่โฮสต์อยู่ของ Google แต่กลับไปที่ห้องสมุดโฮสต์บน Google ล้มเหลว


1016

อะไรจะเป็นวิธีที่ดีในการพยายามโหลดjQuery ที่โฮสต์ที่ Google (หรือ libs ที่โฮสต์โดย Google อื่น ๆ ) แต่ให้โหลด jQuery ของฉันหากความพยายามของ Google ล้มเหลว

ฉันไม่ได้บอกว่า Google เป็นขุย มีหลายกรณีที่สำเนาของ Google ถูกบล็อก (ตัวอย่างเช่นในอิหร่าน)

ฉันจะตั้งเวลาและตรวจสอบวัตถุ jQuery ได้ไหม

สิ่งที่เป็นอันตรายของสำเนาทั้งสองผ่านมา?

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


แก้ไข: ส่วนนี้เพิ่ม ...

เนื่องจาก Google แนะนำให้ใช้ google.load เพื่อโหลด ajax libraries และทำการโทรกลับเมื่อเสร็จแล้วฉันสงสัยว่านี่เป็นกุญแจสำคัญในการทำให้เป็นอันดับปัญหานี้หรือไม่

ฉันรู้ว่ามันฟังดูบ้าไปแล้ว ฉันแค่พยายามคิดว่ามันสามารถทำได้ในลักษณะที่เชื่อถือได้หรือไม่


ปรับปรุง: jQuery ตอนนี้โฮสต์บน CDN ของ Microsoft

http://www.asp.net/ajax/cdn/


9
แน่นอนว่าคำตอบแรกคือ "อย่าใช้รุ่นที่โฮสต์บน google" :-)
Nosredna

7
แน่นอนว่าเป็นเพราะถ้าคุณต้องการโฮสต์เว็บไซต์ที่จริงจังคุณไม่ต้องพึ่งพาคนอื่นที่โฮสต์ไฟล์ของคุณ
ไบรอัน Migliorisi

6
@ ไบรอัน Migliorisi ฉันเดาว่า Twitter นั้นไม่ได้ร้ายแรงอะไร แต่ฉันยอมรับว่าพวกเขามีปัญหากับ Google เมื่อเดือนก่อนเมื่อ Google ลงไป
Ionuț G. Stan

18
ข้อดีของการใช้ Google หรือไม่สำหรับโฮสติ้ง JS lib นั้นเป็นสิ่งที่คู่ควร แต่มันถูกกล่าวถึงในกระทู้อื่น ๆ ฉันกำลังมองหาคำตอบทางเทคนิคเกี่ยวกับ JS fallback ในการโหลดล่าช้า
Nosredna

2
@Joe Chung: มีโอกาสถูกแคชในระบบของผู้ใช้เร่งการโหลดหน้าเว็บ ประหยัดแบนด์วิดธ์ของฉัน ใช้ CDN ของ Google อื่น ๆ
Nosredna

คำตอบ:


810

คุณสามารถทำได้เช่นนี้

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>

<script>
       window.jQuery || document.write('<script src="/path/to/your/jquery"><\/script>');
</script>

สิ่งนี้ควรอยู่ในหน้าของคุณ<head>และตัวจัดการเหตุการณ์ที่พร้อมใช้งาน jQuery ควรอยู่ใน<body>เพื่อหลีกเลี่ยงข้อผิดพลาด (แม้ว่าจะไม่ใช่ข้อพิสูจน์ที่ผิดพลาด!)

อีกเหตุผลหนึ่งที่ไม่ใช้jQuery ที่โฮสต์โดย Google คือในบางประเทศชื่อโดเมนของ Google ถูกแบน


35
การดาวน์โหลดจาวาสคริปต์ไม่ได้บล็อก (ซิงโครนัส) แล้วหรือยัง ดูเหมือนว่าฉันปัญหาสำเนาสองครั้งจึงจะไม่เป็นปัญหา
Matt Sherman

68
การดาวน์โหลด Javascript ควรจะมีการซิงโครไนซ์อยู่แล้วตามที่ Matt Sherman กล่าว ไม่เช่นนั้นจะเกิดปัญหามากมายหากหน้าพยายามเรียกใช้สคริปต์แบบอินไลน์ที่อ้างอิงกับไลบรารีที่ดาวน์โหลดมาเพียงครึ่งเดียวหรือส่วนขยายไลบรารีถูกดำเนินการโดยไม่มีห้องสมุดที่ดาวน์โหลดและดำเนินการอย่างเต็มที่ นั่นเป็นเหตุผลข้อหนึ่งที่ Yahoo YSlow แนะนำให้วางจาวาสคริปต์ที่ส่วนท้ายของหน้า เพื่อไม่ให้บล็อกการดาวน์โหลดองค์ประกอบของหน้าอื่น ๆ (รวมถึงสไตล์และรูปภาพ) อย่างน้อยที่สุดเบราว์เซอร์จะต้องชะลอการดำเนินการเพื่อให้เกิดขึ้นตามลำดับ
gapple

42
โปรแกรมฟิกซ์ขนาดเล็กจากตัวตรวจสอบความถูกต้อง: ไม่อนุญาตให้ใช้สตริง '</' ใน JavaScript เนื่องจากอาจตีความผิดว่าเป็นจุดสิ้นสุดของแท็กสคริปต์ (สัญกรณ์แท็กสั้น SGML) ทำ '<' + '/ script>' แทน ไชโย
Boldewyn

8
ตัวอย่างนี้จะไม่ทำงาน 1) หากห้องสมุด Google ajax ไม่สามารถใช้ได้ก็จะต้องหมดเวลาก่อนที่จะล้มเหลว อาจใช้เวลาสักครู่ ในการทดสอบการยกเลิกการเชื่อมต่อคอมพิวเตอร์ของฉันจากเครือข่ายมันเพิ่งลองและลองและลองและไม่หมดเวลา 2) ถ้า (! jQuery) จะโยนข้อผิดพลาดเพราะ jQuery ไม่ได้ถูกกำหนดดังนั้น Javascript จะไม่ทราบว่าจะทำอย่างไรกับมัน
RedWolves

32
เพื่อทดสอบว่ามีการโหลด jQuery หรือไม่ (! window.jQuery) ทำงานได้ดีและย่อมาจากการตรวจสอบ typeof
Jörn Zaefferer

335

วิธีที่ง่ายที่สุดและสะอาดที่สุดในการทำเช่นนี้:

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="path/to/your/jquery"><\/script>')</script>

1
@jpp ไม่ได้สำหรับXHTML 1.0และHTML 4.01
BenjaminRH

5
ผู้คนยังคงขอร้องให้ฉันลบtype="text/javascript"ส่วนต่างๆออกไปดังนั้นสำหรับคนที่เขียน html สำหรับเบราว์เซอร์รุ่นเก่าโปรดทราบว่าตอนนี้คุณจะต้องเพิ่มสิ่งต่อไปนี้
BenjaminRH

6
@BenjaminRH: type="text/javascript"ก็ไม่จำเป็นในเบราว์เซอร์รุ่นเก่าด้วยเช่นกันเนื่องจากมีค่าเริ่มต้นเป็น Javascript ทั้งหมด เบราว์เซอร์รุ่นเก่าจริงๆมองไปที่languageแอตทริบิวต์; แต่ถึงอย่างนั้น Javascript ก็เป็นค่าเริ่มต้นหากไม่มีแอตทริบิวต์
Martijn

1
@Martijn แต่ฉันชอบตราการตรวจสอบความมันวาว :)
BenjaminRH

3
@ โทรจันเป็นไปได้ทั้งหมดเพียงแค่วางสาย โปรดทราบว่า ณ จุดนี้คุณกำลังเปิดโฮสต์การเชื่อมต่อใหม่ดังนั้นการวางท่อ HTTP อาจจะเร็วกว่า ... <script src="//cdn1.com/jquery.js"></script> <script>window.jQuery || document.write('<script src="//cdn2.com/jquery.js"><\/script>')</script> <script>window.jQuery || document.write('<script src="local/jquery.js"><\/script>')</script>
Tom McKenzie

76

ดูเหมือนว่าจะใช้งานได้สำหรับฉัน:

<html>
<head>
<script type="text/javascript" src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
// has the google object loaded?
if (window.google && window.google.load) {
    google.load("jquery", "1.3.2");
} else {
    document.write('<script type="text/javascript" src="http://joecrawford.com/jquery-1.3.2.min.js"><\/script>');
}
window.onload = function() {
    $('#test').css({'border':'2px solid #f00'});
};
</script>
</head>
<body>
    <p id="test">hello jQuery</p>
</body>
</html>

วิธีการทำงานคือการใช้googleวัตถุที่เรียกhttp://www.google.com/jsapiโหลดไปยังwindowวัตถุ หากวัตถุนั้นไม่มีอยู่เรากำลังสมมติว่าการเข้าถึง Google ล้มเหลว document.writeหากเป็นกรณีที่เราโหลดสำเนาท้องถิ่นโดยใช้ (ฉันใช้เซิร์ฟเวอร์ของตัวเองในกรณีนี้โปรดใช้ของคุณเองเพื่อทดสอบสิ่งนี้)

ฉันยังทดสอบการมีอยู่ของwindow.google.load- ฉันยังสามารถtypeofตรวจสอบเพื่อดูว่าสิ่งต่าง ๆ เป็นวัตถุหรือฟังก์ชั่นตามความเหมาะสม แต่ฉันคิดว่านี่เป็นกลอุบาย

นี่เป็นเพียงตรรกะการโหลดเนื่องจากการไฮไลต์โค้ดดูเหมือนจะล้มเหลวเนื่องจากฉันโพสต์หน้า HTML ทั้งหมดที่ฉันทดสอบ:

if (window.google && window.google.load) {
    google.load("jquery", "1.3.2");
} else {
    document.write('<script type="text/javascript" src="http://joecrawford.com/jquery-1.3.2.min.js"><\/script>');
}

แม้ว่าฉันต้องบอกว่าฉันไม่แน่ใจว่าหากนี่เป็นข้อกังวลสำหรับผู้เยี่ยมชมไซต์ของคุณคุณควรเล่นซอกับAPI ของ Google AJAX ไลบรารีทั้งหมด

สนุกจริง : ฉันพยายามเริ่มใช้ try..catch block สำหรับสิ่งนี้ในเวอร์ชันต่างๆ แต่ไม่สามารถหาชุดค่าผสมที่สะอาดเท่านี้ได้ ฉันสนใจที่จะเห็นการใช้งานอื่น ๆ ของความคิดนี้เป็นเพียงการออกกำลังกาย


1
อะไรคือข้อดีของการใช้ google.load ในสถานการณ์นี้แทนที่จะโหลด ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js โดยตรงเหมือน Rony แนะนำ? ฉันเดาว่าการโหลดมันจะจับปัญหาโดยตรงกับห้องสมุดที่ถูกลบด้วย (ถ้า Google หยุดให้บริการ JQuery 1.3.2) นอกจากนี้เวอร์ชันเครือข่ายของ Rony ยังพบปัญหาเครือข่ายหลังจากที่ www.google.com/jsapi ถูกเรียกมาแล้วโดยเฉพาะอย่างยิ่งเมื่อ jsapi ถูกโหลดจากแคช? หนึ่งอาจต้องใช้การเรียกกลับของ google.load เพื่อให้แน่ใจ (หรืออาจมีค่าตอบแทนที่จะรวม google.load ใน if (.. ))
Arjan

หากมีการทดสอบการมีอยู่ของ Google.com เราสามารถทำการโทรผ่านเครือข่ายหรือตรวจสอบว่ามีวัตถุ "ผู้รักษาประตู" อยู่หรือไม่ สิ่งที่ฉันทำคือการตรวจสอบวัตถุ google และฟังก์ชั่น "โหลด" หากทั้งสองอย่างนั้นล้มเหลวไม่มี google และฉันต้องการเวอร์ชันท้องถิ่น เวอร์ชันของ Rony นั้นละเว้น URL www.google.com/jsapi ทั้งหมดดังนั้นฉันจึงไม่แน่ใจว่าทำไมคุณถึงระบุว่าจะมีการดึงข้อมูล
artlung

ในที่สุดสิ่งที่จำเป็นต้องมีก็คือโหลด jquery library ห้องสมุด Google ใด ๆ ไม่ใช่ข้อกำหนด ในคำตอบของ Rony ใคร ๆ ก็รู้ว่าการโหลดจาก Google (หรือแคช) สำเร็จหรือไม่ แต่ในการตรวจสอบของคุณสำหรับ "ถ้า (window.google && window.google.load)" ห้องสมุด jquery ยังคงไม่โหลด การโหลดไลบรารี jquery จริงไม่ได้รับการตรวจสอบความถูกต้อง?
Arjan

อาฉันเห็นว่าฉันทำให้เกิดความสับสน "เวอร์ชันเครือข่ายของ Rony สังเกตเห็นปัญหาเครือข่ายหลังจากที่ www.google.com/jsapi ดึงข้อมูลแล้ว" ควรอ่านได้ดีกว่า: "เวอร์ชันของคุณไม่สังเกตเห็นปัญหาเครือข่ายหลังจากที่ www.google.com/jsapi เรียกใช้แล้ว"
Arjan

2
เราเพิ่งเปลี่ยนมาใช้ Google เป็นโฮสต์ jQuery ของเรา หากเราได้รับรายงานข้อผิดพลาดจากผู้ใช้ที่ถูกปิดกั้นฉันจะใช้คำตอบของคุณในการกำหนดรหัสลูกค้าของเราใหม่ คำตอบที่ดี!
Jarrod Dixon

30

หากคุณมี modernizr.js ฝังอยู่ในไซต์ของคุณคุณสามารถใช้ yepnope.js ในตัวเพื่อโหลดสคริปต์ของคุณแบบอะซิงโครนัส - ในหมู่ jQuery (พร้อมทางเลือก)

Modernizr.load([{
    load : '//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js'
},{
    test : window.jQuery,
    nope : 'path/to/local/jquery-1.7.2.min.js',
    both : ['myscript.js', 'another-script.js'],
    complete : function () {
        MyApp.init();
    }
}]);

สิ่งนี้โหลด jQuery จาก Google-cdn หลังจากนั้นก็ทำการตรวจสอบถ้าโหลด jQuery สำเร็จ ถ้าไม่ใช่ ("ไม่") เวอร์ชั่นโลคัลจะถูกโหลด นอกจากนี้สคริปต์ส่วนบุคคลของคุณจะถูกโหลด - "ทั้งคู่" บ่งชี้ว่ากระบวนการโหลดจะเริ่มต้นเป็นอิสระจากผลของการทดสอบ

เมื่อกระบวนการโหลดทั้งหมดเสร็จสมบูรณ์ฟังก์ชันจะถูกดำเนินการในกรณี 'MyApp.init'

ฉันชอบการโหลดสคริปต์แบบอะซิงโครนัสโดยส่วนตัวนี้ และเมื่อฉันใช้การทดสอบคุณสมบัติที่ทันสมัยโดย modernizr เมื่อสร้างเว็บไซต์ฉันฝังมันไว้บนเว็บไซต์แล้ว ดังนั้นจึงไม่มีค่าใช้จ่าย


2
ฉันคิดว่าคุณขาดคำถามไปแล้ว - คุณจะโหลด moernizr script จาก CDN ได้อย่างไร?
George Filippakos

2
ฉันไม่แนะนำให้โหลด Modernizr จาก CDN หนึ่งควรจะได้รับการกำหนดเองที่เล็กที่สุดจาก modernizr.com
Emanuel Kluge

2
ดังนั้นตัวเลือกนี้จะได้รับ +16 เมื่อเทียบกับ 500 / 200+ ตัวเลือกอื่น ๆ จะได้รับ แต่ฟังดูดีทีเดียว มันไม่ได้เป็นที่นิยมเนื่องจากอาศัย Modernizer? ฉันยังใช้ Modernizer ในเว็บไซต์ของเราอยู่ดีดังนั้นถ้านี่ดีกว่าคำตอบอื่น ๆ มีคนบอกฉันได้ไหม ฉันค่อนข้างใหม่สำหรับ JQuery ดังนั้นการชี้แจงจึงเป็นที่นิยม
redfox05

2
นี่เป็นตัวเลือกที่ดีจริงๆในช่วงเวลาของคำตอบ แต่ในปี 2558 yepnope.jsเลิกใช้แล้ว ดูstackoverflow.com/questions/33986561/…
Obmerk Kronen

Modernizr ถูกสร้างขึ้นเพื่อแก้ปัญหาเช่นเดียวกับคำถามนี้ +1
Carlos Quijano

21

มีวิธีแก้ปัญหาที่ยอดเยี่ยมอยู่ที่นี่ แต่ฉันจะเอาอีกหนึ่งขั้นเกี่ยวกับไฟล์โลคอล

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

เหตุผลของฉันคือฉันต้องการที่จะมีบางส่วนของจิตใจเมื่อมันมาถึงการติดตามสิ่งที่ฉันโหลดจาก Google กับสิ่งที่ฉันมีในเซิร์ฟเวอร์ท้องถิ่น หากฉันต้องการเปลี่ยนรุ่นฉันจะต้องซิงค์สำเนาในเครื่องของฉันกับสิ่งที่ฉันพยายามโหลดจาก Google ในสภาพแวดล้อมที่มีนักพัฒนาหลายคนฉันคิดว่าวิธีที่ดีที่สุดคือการทำให้กระบวนการนี้เป็นแบบอัตโนมัติเพื่อให้ทุกคนต้องทำคือเปลี่ยนหมายเลขเวอร์ชันในไฟล์กำหนดค่า

นี่คือวิธีแก้ปัญหาที่เสนอของฉันที่ควรทำงานในทฤษฎี:

  • ในไฟล์การกำหนดค่าแอปพลิเคชันฉันจะเก็บ 3 สิ่ง: URL แบบสัมบูรณ์สำหรับไลบรารี URL สำหรับ JavaScript API และหมายเลขเวอร์ชัน
  • เขียนคลาสที่รับเนื้อหาไฟล์ของไลบรารี (รับ URL จากแอป config) เก็บไว้ในแหล่งข้อมูลของฉันด้วยชื่อและหมายเลขรุ่น
  • เขียน handler ซึ่งดึงไฟล์โลคัลของฉันออกจาก db และแคชไฟล์จนกว่าหมายเลขเวอร์ชันจะเปลี่ยน
  • หากมีการเปลี่ยนแปลง (ในการกำหนดค่าแอพของฉัน) คลาสของฉันจะดึงเนื้อหาไฟล์ตามหมายเลขเวอร์ชันบันทึกเป็นเรกคอร์ดใหม่ในแหล่งข้อมูลของฉันจากนั้นตัวจัดการจะเตะเข้าและรับเวอร์ชันใหม่

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

ทุกคนคิดอย่างไร อาจเป็นเพราะ overkill แต่อาจเป็นวิธีที่ยอดเยี่ยมในการบำรุงรักษาไลบรารี AJAX ของคุณ

ลูกโอ๊ก


หากคุณกำลังทำทุกอย่างที่ทำงานเพียงเพื่อ jQuery แล้วฉันจะบอกว่ามันเกินความจริง อย่างไรก็ตามหากคุณมีส่วนประกอบเหล่านี้อยู่แล้วสำหรับแอปอื่น ๆ ของคุณ (เช่นถ้าคุณโหลดสคริปต์จากฐานข้อมูล) แล้วมันก็ดูดีทีเดียว
Michael Haren

1
+1 สำหรับการถี่ถ้วนและแปลกใหม่แม้ว่าฉันจะไม่เชื่อว่าผลประโยชน์จะพิสูจน์เวลา dev และความซับซ้อน
Cory House

20
if (typeof jQuery == 'undefined') {
// or if ( ! window.jQuery)
// or if ( ! 'jQuery' in window)
// or if ( ! window.hasOwnProperty('jQuery'))    

  var script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = '/libs/jquery.js';

  var scriptHook = document.getElementsByTagName('script')[0];
  scriptHook.parentNode.insertBefore(script, scriptHook);

}

หลังจากคุณพยายามรวมสำเนาของ Google จาก CDN

ใน HTML5 คุณไม่จำเป็นต้องตั้งค่า typeแอตทริบิวต์

คุณยังสามารถใช้ ...

window.jQuery || document.write('<script src="/libs/jquery.js"><\/script>');

2
+1 ดูสะอาดกว่า มีการพิมพ์ผิดเล็กน้อยที่ด้านบนซึ่งฉันไม่สามารถล้างได้เนื่องจากวงเล็บปิดสองอันที่เล็กกว่าหลังจาก 'ไม่ได้กำหนด'
naveen

1
ตัวเลือกแรกหลีกเลี่ยงการเตือน Chrome[Violation] Avoid using document.write().
Bob Stein

ตัวเลือกแรกน่าเสียดายที่ไม่ปรากฏว่าโหลดพร้อมกัน ตัวเลือกที่สองไม่
Bob Stein

10

คุณอาจต้องการใช้ไฟล์ในเครื่องของคุณเป็นทางเลือกสุดท้าย

ดูเหมือนว่าตอนนี้ CDN ของ jQuery เองไม่รองรับ https หากเป็นเช่นนั้นคุณอาจต้องการโหลดจากที่นั่นก่อน

ดังนั้นนี่คือลำดับ: Google CDN => Microsoft CDN => สำเนาในเครื่องของคุณ

<!-- load jQuery from Google's CDN -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script> 
<!-- fallback to Microsoft's Ajax CDN -->
<script> window.jQuery || document.write('<script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.8.3.min.js">\x3C/script>')</script> 
<!-- fallback to local file -->
<script> window.jQuery || document.write('<script src="Assets/jquery-1.8.3.min.js">\x3C/script>')</script> 

มีความต้องการมากกว่าหนึ่งทางเลือกหรือไม่? หากทั้งคู่เป็นผู้ใช้ออฟไลน์จะต้องรอเป็นเวลาหนึ่งนาทีก่อนที่จะเห็นเว็บไซต์ของคุณ
George Filippakos

1
สคริปต์ใช้เวลาในการโหลดไม่ถึง 1 นาที
Edward Olamisan

@ geo1701 และ Edward ไม่มีความจำเป็นอะไรเลยสำหรับบุคคลที่สาม แม้แต่ทางเลือกหนึ่งที่ยังไม่ได้พิสูจน์ความน่าเชื่อถือ หาก Google API ไม่ทำงานฉันยังไม่เห็นการรับประกันใด ๆ ว่าความพยายามครั้งแรกจะล้มเหลวเลย ฉันประสบสถานการณ์กรณีที่ CDN ไม่เคยโหลดไม่โหลดถือหน้าจากการเรนเดอร์ตามที่กล่าวไว้ที่นี่: stevesouders.com/blog/2013/03/18/http-archive-jquery/
hexalys

6

โหลด jQuery รุ่นล่าสุด / แบบมีเงื่อนไขและทางเลือกสำรอง:

<!--[if lt IE 9]>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
    <script>window.jQuery || document.write('<script src="/public/vendor/jquery-legacy/dist/jquery.min.js">\x3C/script>')</script>
<![endif]-->
<!--[if gte IE 9]><!-->
    <script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
    <script>window.jQuery || document.write('<script src="/public/vendor/jquery/dist/jquery.min.js">\x3C/script>')</script>
<!--<![endif]-->

สิ่งนี้ไม่เข้ากันข้ามเบราว์เซอร์
Josh Habdas

จอชใช่มันเป็น
neiker

5
  • ขั้นตอนที่ 1: jQuery โหลดไม่สำเร็จหรือไม่ (ตรวจสอบjQueryตัวแปร)

วิธีตรวจสอบตัวแปรที่ไม่ได้กำหนดใน JavaScript

  • ขั้นตอนที่ 2: นำเข้าไฟล์จาวาสคริปต์ (ข้อมูลสำรอง) แบบไดนามิก

ฉันจะรวมไฟล์ JavaScript ในไฟล์ JavaScript อื่นได้อย่างไร



4

นี่คือคำอธิบายที่ดีเกี่ยวกับเรื่องนี้!

ยังดำเนินการโหลดล่าช้าและหมดเวลา!

http://happyworm.com/blog/2010/01/28/a-simple-and-robust-cdn-failover-for-jquery-14-in-one-line/


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

@cale_b คุณล้อเล่นไหม? คำตอบนี้มีอายุมากกว่า 7 ปีดังนั้นความคิดเห็นดังกล่าวจึงไม่รับประกัน
Stuart.Sklinar

ใช่มันเป็นคำตอบเก่า แม้ว่าข้อเสนอแนะของพวกเขาจะถูกต้อง คำตอบที่เป็นเพียงการเชื่อมโยงที่อื่นเป็นผู้สมัครเพื่อลบ ผู้อ่านเพิ่มเติม: meta.stackoverflow.com/q/8259
Rob

ฉันเห็นด้วยอย่างยิ่งฉันจะดูแลคำแนะนำตัวเอง - แต่มันไม่มีประโยชน์ที่จะบอกว่า 7 ปีต่อมา ควรมีการกลั่นกรองแบบนั้นเมื่อ 7 ปีที่แล้วไม่ใช่ 7 ปีต่อมา
Stuart.Sklinar

1
@ Stuart.Sklinar - ถ้าฉันเห็นมันเมื่อ 7 ปีที่แล้วฉันจะได้ :) ฉันพบว่าตัวเองกำลังทำการวิจัยและเห็นสิ่งนี้เป็นครั้งแรก ขออภัยที่ทำให้คุณผิดหวัง - ฉันคิดว่างานของเราใน SO นั้นจะต้องเป็นผู้ดูแลไซต์ซึ่งบางครั้งหมายถึงการแสดงความคิดเห็นแก้ไขหรือปรับปรุงคำถามหรือคำตอบเก่า ...
random_user_name

4

สำหรับผู้ที่ใช้ ASP.NET MVC 5 ให้เพิ่มรหัสนี้ใน BundleConfig.cs ของคุณเพื่อเปิดใช้งาน CDN สำหรับ jquery:

bundles.UseCdn = true;
Bundle jqueryBundle = new ScriptBundle("~/bundles/jquery", "//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js").Include("~/Scripts/jquery-{version}.js");
jqueryBundle.CdnFallbackExpression = "window.jQuery";
bundles.Add(jqueryBundle);

4

UPDATE:
คำตอบนี้กลายเป็นผิด โปรดดูความคิดเห็นสำหรับคำอธิบายที่แท้จริง


คำถามส่วนใหญ่ของคุณได้รับคำตอบแล้ว แต่สำหรับส่วนสุดท้าย:

สิ่งที่เป็นอันตรายของสำเนาทั้งสองผ่านมา?

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


5
ที่จริงแล้วการโหลด jQuery สองครั้งอาจทำให้เกิดปัญหามากมายตามคำถามนี้
ShadowCat7

ทำไมคุณไม่ทดสอบด้วยตัวเองและโหลด jquery library ด้วยตนเองสองครั้ง จากนั้นคำตอบจะถูกเปิดเผย
luke_mclachlan

ทำไมมันผิดอย่างนั้นเหรอ? @ ShadowCat7 คุณจะเจาะจงมากขึ้นเกี่ยวกับปัญหาที่เกิดขึ้นได้ไหม? ปัญหาเดียวที่ฉันเห็นชัดเจนในคำถามที่คุณเชื่อมโยงคือ "การล้างปลั๊กอินที่โหลดก่อนหน้านี้ทั้งหมด" แต่นั่นไม่ควรใช้กับการโหลดไฟล์ jQuery เดียวกันสองครั้งย้อนหลังไปด้านหลังใช่ไหม ผมถามเพราะการแก้ปัญหาอื่น ๆ ที่นี่เพื่อสำรองในประเทศจะซับซ้อนมากและ document.write ถูกกล่าวหาเป็นความชั่วร้ายในบางสถานที่
Bob Stein

2

ฉันสร้าง Gist ที่ควรโหลด jQuery แบบไดนามิกหากยังไม่ได้โหลดและหากแหล่งที่มาล้มเหลวมันจะดำเนินต่อไปในทางเลือก (เย็บต่อกันจากคำตอบมากมาย): https://gist.github.com/tigerhawkvok/9673154

โปรดทราบฉันวางแผนที่จะทำให้ Gist อัพเดท แต่ไม่ใช่คำตอบนี้สำหรับสิ่งที่คุ้มค่า!

/* See https://gist.github.com/tigerhawkvok/9673154 for the latest version */
function cascadeJQLoad(i) { // Use alternate CDNs where appropriate to load jQuery
    if (typeof(i) != "number") i = 0;
    // the actual paths to your jQuery CDNs
    var jq_paths = [
        "ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js",
        "ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.0.min.js"
    ];
    // Paths to your libraries that require jQuery
    var dependent_libraries = [
        "js/c.js"
    ];
    if (window.jQuery === undefined && i < jq_paths.length) {
        i++;
        loadJQ(jq_paths[i], i, dependent_libraries);
    }
    if (window.jQuery === undefined && i == jq_paths.length) {
        // jQuery failed to load
        // Insert your handler here
    }
}

/***
 * You shouldn't have to modify anything below here
 ***/

function loadJQ(jq_path, i, libs) { //load jQuery if it isn't already
    if (typeof(jq_path) == "undefined") return false;
    if (typeof(i) != "number") i = 1;
    var loadNextJQ = function() {
        var src = 'https:' == location.protocol ? 'https' : 'http';
        var script_url = src + '://' + jq_path;
        loadJS(script_url, function() {
            if (window.jQuery === undefined) cascadeJQLoad(i);
        });
    }
    window.onload = function() {
        if (window.jQuery === undefined) loadNextJQ();
        else {
            // Load libraries that rely on jQuery
            if (typeof(libs) == "object") {
                $.each(libs, function() {
                    loadJS(this.toString());
                });
            }
        }
    }
    if (i > 0) loadNextJQ();
}

function loadJS(src, callback) {
    var s = document.createElement('script');
    s.src = src;
    s.async = true;
    s.onreadystatechange = s.onload = function() {
        var state = s.readyState;
        try {
            if (!callback.done && (!state || /loaded|complete/.test(state))) {
                callback.done = true;
                callback();
            }
        } catch (e) {
            // do nothing, no callback function passed
        }
    };
    s.onerror = function() {
        try {
            if (!callback.done) {
                callback.done = true;
                callback();
            }
        } catch (e) {
            // do nothing, no callback function passed
        }
    }
    document.getElementsByTagName('head')[0].appendChild(s);
}

/*
 * The part that actually calls above
 */

if (window.readyState) { //older microsoft browsers
    window.onreadystatechange = function() {
        if (this.readyState == 'complete' || this.readyState == 'loaded') {
            cascadeJQLoad();
        }
    }
} else { //modern browsers
    cascadeJQLoad();
}

2

Google Hosted jQuery

  • หากคุณสนใจเกี่ยวกับเบราว์เซอร์รุ่นเก่าซึ่งเป็นรุ่นหลักของ IE ก่อน IE9 นี่เป็นรุ่น jQuery ที่เข้ากันได้อย่างกว้างขวางที่สุด
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
  • หากคุณไม่สนใจ oldie ตัวนี้จะเล็กและเร็วขึ้น:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>

แผนสำรอง / ทางเลือก!

  • ไม่ว่าจะด้วยวิธีใดคุณควรใช้ทางเลือกกลับสู่ท้องถิ่นในกรณีที่ Google CDN ล้มเหลว (ไม่น่าเป็นไปได้) หรือถูกบล็อกในสถานที่ที่ผู้ใช้ของคุณเข้าถึงเว็บไซต์ของคุณ (มีโอกาสมากขึ้นเล็กน้อย) เช่นอิหร่านหรือจีนบางครั้ง
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>if (!window.jQuery) { document.write('<script src="/path/to/your/jquery"><\/script>'); }
</script>

การอ้างอิง: http://websitespeedoptimizations.com/ContentDeliveryNetworkPost.aspx


หมายเหตุการโหลดสคริปต์ผ่านโปรโตคอลที่ไม่ปลอดภัยจะเปิดเวกเตอร์การโจมตี XSS
Josh Habdas

2

ฉันคิดว่ามันน่าจะรอดจาก <ไปยัง \ x3C สุดท้ายเป็นสตริง เมื่อเบราว์เซอร์เห็นจะถือว่านี่เป็นจุดสิ้นสุดของบล็อกสคริปต์ (เนื่องจาก parser HTML ไม่มีความคิดเกี่ยวกับ JavaScript จึงไม่สามารถแยกความแตกต่างระหว่างสิ่งที่เพิ่งปรากฏในสตริงและสิ่งที่จริงหมายถึงการสิ้นสุดสคริปต์ ธาตุ). ดังนั้นการปรากฏตัวอักษรใน JavaScript ที่อยู่ในหน้า HTML จะ (ในกรณีที่ดีที่สุด) ทำให้เกิดข้อผิดพลาดและ (ในกรณีที่เลวร้ายที่สุด) เป็นช่องโหว่ความปลอดภัยขนาดใหญ่

<script src="https://ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min.js"></script>
<script>window.jQuery || document.write('<script src="js/jquery-2.0.0.min.js">\x3C/script>')</script>

2
if (typeof jQuery == 'undefined')) { ...

หรือ

if(!window.jQuery){

จะไม่ทำงานหากไม่ได้โหลดเวอร์ชัน cdn เนื่องจากเบราว์เซอร์จะทำงานผ่านเงื่อนไขนี้และในระหว่างนั้นยังคงดาวน์โหลด javascripts ที่เหลือซึ่งต้องการ jQuery และส่งคืนข้อผิดพลาด วิธีแก้ไขคือโหลดสคริปต์ผ่านเงื่อนไขนั้น

    <script src="http://WRONGPATH.code.jquery.com/jquery-1.4.2.min.js" type="text/javascript"></script><!--  WRONGPATH for test-->
  <script type="text/javascript">
  function loadCDN_or_local(){
    if(!window.jQuery){//jQuery not loaded, take a local copy of jQuery and then my scripts
      var scripts=['local_copy_jquery.js','my_javascripts.js'];
      for(var i=0;i<scripts.length;i++){
      scri=document.getElementsByTagName('head')[0].appendChild(document.createElement('script'));
      scri.type='text/javascript';
      scri.src=scripts[i];
    }
  }
  else{// jQuery loaded can load my scripts
    var s=document.getElementsByTagName('head')[0].appendChild(document.createElement('script'));
    s.type='text/javascript';
    s.src='my_javascripts.js';
  }
  }
  window.onload=function(){loadCDN_or_local();};
  </script>

ฉันพบปัญหาหนึ่งในการทดสอบสคริปต์ใน Google Chrome - การแคช ดังนั้นสำหรับการทดสอบในพื้นที่เพียงแค่แทนที่ src ในส่วนอื่นด้วย s.src = 'my_javascripts.js' + '?' + Math.floor (Math.random () * 10001);
Mirek Komárek

คำตอบของ Alexจะไม่ทำงานหากไม่ได้โหลด cdn version เพราะเบราว์เซอร์จะทำงานผ่านเงื่อนไขนี้และในระหว่างนั้นยังคงดาวน์โหลด javascripts ที่เหลือซึ่งต้องการ jquery และส่งคืนข้อผิดพลาด ->ไฟล์ JavaScript ที่ดาวน์โหลดจะปิดกั้นรหัสถัดไป ดังนั้นจึงไม่เป็นปัญหา
alex

2

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

<script src="https://pagecdn.io/lib/jquery/3.2.1/jquery.min.js"></script>
<script>
   window.jQuery || document.write('<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"><\/script>');
</script>

1

ใช้ไวยากรณ์ของมีดโกนใน ASP.NET รหัสนี้ให้การสนับสนุนทางเลือกและทำงานกับรากเสมือน:

@{var jQueryPath = Url.Content("~/Scripts/jquery-1.7.1.min.js");}
<script type="text/javascript">
    if (typeof jQuery == 'undefined')
        document.write(unescape("%3Cscript src='@jQueryPath' type='text/javascript'%3E%3C/script%3E"));
</script>

หรือสร้างผู้ช่วย ( ภาพรวมผู้ช่วย ):

@helper CdnScript(string script, string cdnPath, string test) {
    @Html.Raw("<script src=\"http://ajax.aspnetcdn.com/" + cdnPath + "/" + script + "\" type=\"text/javascript\"></script>" +
        "<script type=\"text/javascript\">" + test + " || document.write(unescape(\"%3Cscript src='" + Url.Content("~/Scripts/" + script) + "' type='text/javascript'%3E%3C/script%3E\"));</script>")
}

และใช้มันเช่นนี้

@CdnScript("jquery-1.7.1.min.js", "ajax/jQuery", "window.jQuery")
@CdnScript("jquery.validate.min.js", "ajax/jquery.validate/1.9", "jQuery.fn.validate")

ฉันไม่เคยกังวลเกี่ยวกับมีดโกน แต่ดูเหมือน obfuscator ยกเว้นว่ามันทำให้รหัสยาวมากกว่าสั้น (มันยาวเป็นสองเท่านี้ )
maaartinus

@maaartinus: นั่นไม่ใช่การเปรียบเทียบแอปเปิ้ลกับแอปเปิ้ล คำตอบของ BenjaminRH ที่คุณอ้างถึงนั้นมีไว้สำหรับสคริปต์ที่โฮสต์โดย CDN กับCdnScriptผู้ช่วยที่คุณต้องการเพียงหนึ่งบรรทัดของรหัสต่อสคริปต์ ยิ่งคุณมีสคริปต์มากเท่าใดก็ยิ่งได้รับผลตอบแทนมากเท่านั้น
Edward Brey

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

@maaartinus: เนื่องจากการโหลดสคริปต์ CDN แต่ละครั้งอาจล้มเหลวอย่างอิสระคุณต้องตรวจสอบแต่ละการโหลดแยกกัน ไม่มีวิธีที่เชื่อถือได้ของการตรวจสอบ CDN เดียวตามด้วยการโหลดสคริปต์ทั้งหมดจาก CDN กับภายใน
Edward Brey

กรณีที่กังวลกับฉันคือความล้มเหลวของไซต์ CDN ที่นำไปสู่การรอเวลาสำหรับการโหลดจำนวนมาก try { for (Script s : ...) cdnLoad(s); } catch (...) { for (Script s : ...) ownLoad(s); }ดังนั้นผมจึงต้องการที่จะมีสิ่งที่ต้องการ การแปลสิ่งนี้ให้กลายifเป็นฝันร้าย
maaartinus

1

แม้ว่าการเขียนdocument.write("<script></script>")จะง่ายกว่าสำหรับ jQuery backoff แต่ Chrome ก็มีข้อผิดพลาดในการตรวจสอบความถูกต้องในกรณีนั้น ดังนั้นฉันชอบทำลายคำว่า "script" ดังนั้นจึงปลอดภัยกว่าที่กล่าวข้างต้น

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.1.min.js"></script>
<script>if (typeof jQuery === "undefined") {
   window.jqFallback = true;
   document.write("<scr"+"ipt src='http://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js'></scr"+"ipt>");
} </script>

สำหรับปัญหาในระยะยาวจะเป็นการดีกว่าถ้าจะบันทึก JQuery fallbacks ในรหัสด้านบนหาก CDN แรกไม่พร้อมใช้งาน JQuery จะถูกโหลดจาก CDN อื่น แต่คุณอาจต้องการทราบว่า CDN ที่ผิดพลาดและลบออกอย่างถาวร (กรณีนี้เป็นกรณีพิเศษมาก) นอกจากนี้ยังเป็นการดีกว่าที่จะบันทึกปัญหาทางเลือก ดังนั้นคุณสามารถส่งกรณีที่ผิดพลาดด้วย AJAX เนื่องจาก JQuery ไม่ได้ถูกกำหนดคุณควรใช้ vanilla javascript สำหรับคำขอ AJAX

<script type="text/javascript">
    if (typeof jQuery === 'undefined' || window.jqFallback == true) {
        // XMLHttpRequest for IE7+, Firefox, Chrome, Opera, Safari
        // ActiveXObject for IE6, IE5
        var xmlhttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
        var url = window.jqFallback == true ? "/yourUrl/" : "/yourUrl2/";
        xmlhttp.open("POST", url, true);
        xmlhttp.send();
    }
</script>

1

การไม่สามารถโหลดทรัพยากรจากแหล่งข้อมูลภายนอกที่อยู่นอกเหนือการควบคุมของคุณนั้นเป็นเรื่องยาก การมองหาฟังก์ชั่นที่หายไปนั้นผิดพลาดอย่างสิ้นเชิงเพื่อหลีกเลี่ยงการหมดเวลาตามที่อธิบายไว้ในที่นี้: http://www.tech-101.com/support/topic/4499-issues-using-a-cdn/


0

อีกทางเลือกหนึ่งที่แทนที่ajax.googleapis.comด้วยcdnjs.cloudflare.com :

(function (doc, $)
{
    'use strict';

    if (typeof $ === 'undefined')
    {
        var script = doc.querySelector('script[src*="jquery.min.js"]'),
            src = script.src.replace('ajax.googleapis.com', 'cdnjs.cloudflare.com');

        script.parentNode.removeChild(script);
        doc.write('<script src="' + src + '"></script>');
    }
})(document, window.jQuery || window.Zepto);
  • คุณสามารถใช้เวอร์ชัน jQuery ได้โดยระบุในสตริง
  • เหมาะสำหรับการจัดการสินทรัพย์ที่ไม่สามารถใช้ HTML snips ได้
  • ผ่านการทดสอบในป่า - ทำงานได้อย่างสมบูรณ์แบบสำหรับผู้ใช้จากประเทศจีน

คุณสามารถอธิบายอย่างละเอียดในข้อความต่อไปนี้: "คุณไม่ต้องสนใจเกี่ยวกับรุ่น jQuery"?
Josh Habdas

รุ่นนี้เป็นส่วนหนึ่งของ URL ที่ไม่น่าสนใจสำหรับวิธีการนี้ ... jquery / 3.xx / jquery.min.js
redaxmedia

1
นั่นมีโอกาสที่จะทำให้เกิดการแตกเมื่อ jQuery revs เป็นเวอร์ชัน 4 และแนะนำการเปลี่ยนแปลงที่เข้ากันไม่ได้ย้อนหลังหรือไม่?
Josh Habdas

-1 เพราะนั่นจะทำให้เกิดการแตกถ้า jQuery แนะนำการเปลี่ยนแปลงที่สำคัญที่สคริปต์ของคุณยังไม่สนับสนุนเว้นแต่ว่ามีการระบุรุ่น
Lookaji

@lookaji ฉันคิดว่าคุณไม่เข้าใจทางเลือก มันจะแทนที่โดเมนที่โฮสต์และไม่ได้สัมผัสชื่อไฟล์ / รุ่นเลย
redaxmedia

0

คุณสามารถใช้รหัสเช่น:

<script type="text/javascript" src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>window.jQuery || document.write('<script type="text/javascript" src="./scripts/jquery.min.js">\x3C/script>')</script>

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

  • basket.js
  • RequireJS
  • yepnope

ตัวอย่าง:

basket.js ฉันคิดว่าตัวแปรที่ดีที่สุดสำหรับตอนนี้ จะแคชสคริปต์ของคุณใน localStorage ซึ่งจะเพิ่มความเร็วในการโหลดครั้งต่อไป การโทรที่ง่ายที่สุด:

basket.require({ url: '/path/to/jquery.js' });

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

basket
    .require({ url: '/path/to/jquery.js' })
    .then(function () {
        // Success
    }, function (error) {
        // There was an error fetching the script
        // Try to load jquery from the next cdn
    });

RequireJS

requirejs.config({
    enforceDefine: true,
    paths: {
        jquery: [
            '//ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min',
            //If the CDN location fails, load from this location
            'js/jquery-2.0.0.min'
        ]
    }
});

//Later
require(['jquery'], function ($) {
});

yepnope

yepnope([{
  load: 'http://ajax.aspnetcdn.com/ajax/jquery/jquery-2.0.0.min.js',
  complete: function () {
    if (!window.jQuery) {
      yepnope('js/jquery-2.0.0.min.js');
    }
  }
}]);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.