จะแทรกแท็ก <script> แบบไดนามิกผ่าน jQuery หลังจากโหลดหน้าได้อย่างไร


102

ฉันมีปัญหาในการทำงาน ก่อนอื่นฉันลองตั้งแท็กสคริปต์ของฉันเป็นสตริงจากนั้นใช้ jquery replaceWith () เพื่อเพิ่มลงในเอกสารหลังจากโหลดหน้า:

var a = '<script type="text/javascript">some script here</script>';
$('#someelement').replaceWith(a);

แต่ฉันพบข้อผิดพลาดเกี่ยวกับสตริงลิเทอรัลในตัวแปรนั้น จากนั้นฉันลองเข้ารหัสสตริงเช่น:

var a = '&left;script type="text/javascript"&gt;some script here&lt;\/script&gt;';

แต่การส่งไปยังreplaceWith()เอาต์พุตสตริงนั้นไปยังเบราว์เซอร์

ใครช่วยแจ้งให้เราทราบได้ไหมว่าคุณจะเพิ่ม<script>แท็กแบบไดนามิกลงในเบราว์เซอร์หลังการโหลดหน้าเว็บโดยใช้ jQuery ได้อย่างไร


คุณช่วยอธิบายได้ไหมว่าคุณกำลังพยายามทำอะไรอยู่โดยการเพิ่ม<script>แท็กในเอกสาร
Pointy

คำตอบของ @ Rocket นั้นดีที่สุด แต่ถ้าคุณต้องการเพิ่มสคริปต์แบบอินไลน์จากสตริงคุณก็แค่ส่งมันไปยังeval()ฟังก์ชัน แต่การใช้eval()เกือบตลอดเวลาชี้ให้เห็นว่ามีวิธีที่ดีกว่าในการทำสิ่งที่คุณพยายามทำ
นิค

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

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

1
ทำไมไม่นำเข้าแท็กเหล่านั้นใน<iframe>องค์ประกอบ คุณสามารถเลื่อนการตั้งค่า<iframe>URL ได้จนกว่าคุณจะพร้อม
Pointy

คำตอบ:


103

คุณสามารถใส่สคริปต์ลงในไฟล์แยกต่างหากจากนั้นใช้$.getScriptเพื่อโหลดและเรียกใช้

ตัวอย่าง:

$.getScript("test.js", function(){
    alert("Running test.js");
});

2
ขอบคุณ แต่จะติดไว้ใน DOM หรือไม่? ฉันตระหนักดีว่าฉันได้ทิ้งข้อมูลสำคัญนั้นไปแล้วซึ่งฉันต้องการให้แท็กสคริปต์ถูกแทรกลงใน DOM โดยได้รับการประเมินซึ่งจะส่งคืนโค้ดโฆษณาของบุคคลที่สามเพื่อแสดงบนไซต์ของเราใน <div> เฉพาะ
ดั๊ก

1
$.getScriptจะโหลดไฟล์. js ผ่าน AJAX และเรียกใช้งาน สคริปต์ไม่จำเป็นต้องอยู่ใน DOM จึงจะสามารถเข้าถึง div บนเพจของคุณได้
Rocket Hazmat

6
แต่ด้วยสคริปต์ที่จะต้องอยู่ในโดเมนเดียวกันหรือทั้งจำทั้งโดเมนระยะไกลและเบราว์เซอร์จะต้องสนับสนุน$.getScript() CORS
hippietrail

14
@hippietrail ที่จริงไม่จริง เพียงแค่แทรกแท็กสคริปต์ ol ธรรมดาซึ่งไม่ต้องใช้ CORS หรือโดเมนเดียวกัน ฉันใช้สิ่งนี้เพื่อย่อโค้ดในการโหลด Google Analytics เป็นต้นและมันก็โหลดได้ดี เบื้องหลังของโค้ด jquery จริงที่รันนั้นค่อนข้างคล้ายกับข้อมูลโค้ด GA
Chris Moschini

39
เนื่องจากคำตอบจาก @hippietrail จะดึงดูดความสนใจได้มากที่สุดด้วยการโหวต 4 ครั้งจึงควรทำให้ชัดเจนว่าเขาไม่ถูกต้อง ตามที่เอกสาร jQuery เน้นใน$.ajaxบันทึก: "คำขอสคริปต์และ JSONP ไม่อยู่ภายใต้ข้อ จำกัด นโยบายต้นทางเดียวกัน" แหล่ง ในคำอื่น ๆ$.getScriptสามารถดึงไฟล์ .js จากโดเมนอื่น ๆ ไม่เพียง แต่ของคุณเอง
EleventyOne

64

ลองทำดังต่อไปนี้:

<script type="text/javascript">
// Use any event to append the code
$(document).ready(function() 
{
    var s = document.createElement("script");
    s.type = "text/javascript";
    s.src = "http://scriptlocation/das.js";
    // Use any selector
    $("head").append(s);
});

http://api.jquery.com/append


4
+1 เพื่อใช้ในappendการเพิ่มสคริปต์ เพิ่มสาเหตุแม้กระทั่งสคริปต์แบบอินไลน์เพื่อประเมินทันที (ตามที่ฉันต้องการ) ขอบคุณ
Gone Coding

1
ฉันพบปัญหามากมายใน IE8 / 9 ด้วยวิธีนี้ ได้แก่ ข้อผิดพลาด Stack Overflow ฉันใช้วิธี $ .getScript () ด้านล่างเพื่อให้ทำงานนี้ได้ทั่วทั้งกระดาน
zmonteca

1
ใช่ @jcoffland นี้เขียนในตุลาคม 2010 :)
Bassem

หากเพจที่มีโค้ดนี้โหลดโดยใช้ AJAX เบราว์เซอร์จะส่งคำเตือน "Synchronous XMLHttpRequest บนเธรดหลักเลิกใช้งานเนื่องจากผลกระทบที่เป็นอันตรายต่อประสบการณ์ของผู้ใช้ปลายทาง"
Rajshekar Reddy

@Reddy ความคิดเห็นที่ยอดเยี่ยม สิ่งนี้ถูกโพสต์ในเดือนตุลาคม 2010 ฉันแน่ใจว่าตอนนี้วิธีนี้ไม่ใช่แนวทางที่ถูกต้อง / แนะนำอีกต่อไปผู้ใช้ต้องดำเนินการตามดุลยพินิจของตนเอง
Bassem

34

นี่คือวิธีที่ถูกต้องในการทำกับ JQuery สมัยใหม่ (2014):

$(function () {
  $('<script>')
    .attr('type', 'text/javascript')
    .text('some script here')
    .appendTo('head');
})

หรือถ้าคุณต้องการแทนที่ div จริงๆคุณสามารถทำได้:

$(function () {
  $('<script>')
    .attr('type', 'text/javascript')
    .text('some script here')
    .replaceAll('#someelement');
});

3
หรือแทน. text ('some script here') คุณสามารถเขียน .attr ('src', 'path_to_your_js_file')
Serhii Maksymchuk

12

วิธีที่ง่ายกว่าคือ:

$('head').append('<script type="text/javascript" src="your.js"></script>');

คุณยังสามารถใช้แบบฟอร์มนี้เพื่อโหลด css


6
คุณอาจต้องการหลีกเลี่ยงการใส่สตริง</script>ในแหล่งที่มาของคุณเนื่องจากอาจทำให้เกิดปัญหาในการแยกวิเคราะห์: stackoverflow.com/questions/236073/…
jacobq

2
การหลบหนีครั้งสุดท้าย/เป็นเคล็ดลับสำหรับฉัน:$('head').append('<script src="your.js"><\/script>');
jerik

5

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

if (!$('head > script[src="js/jquery.searchable.min.js"]').length) {
    $('head').append($('<script />').attr('src','js/jquery.searchable.min.js'));
}

btw. ฉันทำเช่นเดียวกันกับ stylesheets: if (! $ ('head> link [href = "widgets / css / widgets.css"]'). length) {$ ('head') ผนวก ($ ('<link / > '). attr (' rel ',' stylesheet '). attr (' href ',' widgets / css / widgets.css '));}
ddlab

2

มีวิธีแก้ปัญหาหนึ่งที่ฟังดูเหมือนแฮ็กมากกว่าและฉันยอมรับว่ามันไม่ใช่วิธีที่ดีที่สุดในการทำ แต่ได้ผล 100%:

สมมติว่าการตอบสนอง AJAX ของคุณเป็นอย่างไร

<b>some html</b>
<script>alert("and some javscript")

โปรดทราบว่าฉันข้ามแท็กปิดโดยตั้งใจ จากนั้นในสคริปต์ที่โหลดด้านบนให้ทำดังต่อไปนี้:

$.ajax({
    url: "path/to/return/the-above-js+html.php",
    success: function(newhtml){
        newhtml += "<";
        newhtml += "/script>";
        $("head").append(newhtml);
    }
});

อย่าถามฉันว่าทำไม :-) นี่เป็นหนึ่งในสิ่งเหล่านั้นที่ฉันได้รับจากการทดลองแบบสุ่มและล้มเหลว

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

ในช่วงเวลาเช่นนี้ฉันรู้สึกว่าฉันหารด้วยศูนย์ได้สำเร็จ


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

1
<\/script>จะใช้ได้แม้ว่า
SP

ฉันคิดว่าประเด็นของ @ TrueBlueAussie คือการตอบสนองต่อความคิดเห็นของคุณ "อย่าถามฉันว่าทำไม ... แต่น่าสนใจพอมันจะใช้ไม่ได้ถ้าคุณต่อท้ายแท็กปิดในบรรทัดเดียว" เขาอธิบายว่าเหตุใดผู้อ่านที่ต้องการคำตอบที่ดีกว่า "ฉันไม่รู้" สามารถค้นหาได้ง่ายขึ้น ดูเพิ่มเติมที่: javascript.crockford.com/script.html
jacobq

1
@Sathvik ถูกต้องตามลิงค์นั้น ความคิดเห็นของ Ash ดูเหมือนจะเป็นการตอบกลับไปยังข้อความที่ถูกลบออกไป
Arlen Beiler

2

ตัวอย่าง:

var a = '<script type="text/javascript">some script here</script>';
$('#someelement').replaceWith(a);

มันควรจะทำงาน ฉันลองแล้ว; ผลลัพธ์เดียวกัน แต่เมื่อฉันใช้สิ่งนี้:

var length = 1;
var html = "";
for (var i = 0; i < length; i++) {
    html += '<div id="codeSnippet"></div>';
    html += '<script type="text/javascript">';
    html += 'your script here';
    html += '</script>';
}
$('#someElement').replaceWith(a);

สิ่งนี้ได้ผลสำหรับฉัน

แก้ไข: ฉันลืม#someelement(btw ฉันอาจต้องการใช้#someElementเนื่องจากการประชุม)

สิ่งที่สำคัญที่สุดคือ + = ดังนั้น html จึงถูกเพิ่มและไม่ถูกแทนที่

แสดงความคิดเห็นหากไม่ได้ผล ฉันอยากจะช่วยคุณ!


2

นี่เป็นวิธีที่ชัดเจนกว่ามาก - ไม่จำเป็นต้องใช้ jQuery - ซึ่งเพิ่มสคริปต์เป็นลูกสุดท้ายของ<body>:

document.body.innerHTML +='<script src="mycdn.js"><\/script>'

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


-4

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

หากสคริปต์เป็นแบบคงที่คำgetScriptแนะนำของ Rocket คือหนทางที่จะไป

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