Làm cách nào để chèn động thẻ <script> qua jQuery sau khi tải trang?


101

Tôi đang gặp sự cố khi làm việc này. Đầu tiên tôi đã thử đặt các thẻ tập lệnh của mình dưới dạng chuỗi và sau đó sử dụng jquery ReplaceWith () để thêm chúng vào tài liệu sau khi tải trang:

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

Nhưng tôi gặp lỗi chuỗi ký tự trên var đó. Sau đó, tôi đã thử mã hóa chuỗi như:

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

nhưng gửi nó đến replaceWith()kết quả đầu ra chỉ chuỗi đó cho trình duyệt.

Ai đó có thể vui lòng cho tôi biết bạn sẽ thực hiện như thế nào khi thêm động một <script>thẻ vào trình duyệt sau khi tải trang, lý tưởng nhất là thông qua jQuery?


Bạn có thể giải thích điều bạn đang cố gắng đạt được bằng cách thêm <script>thẻ vào tài liệu không?
Pointy

Câu trả lời của @ Rocket là tốt nhất, nhưng nếu bạn chắc chắn muốn thêm tập lệnh nội tuyến từ một chuỗi, thì bạn chỉ cần chuyển nó vào eval()hàm. Nhưng việc sử dụng eval()hầu như luôn luôn gợi ý rằng có một cách tốt hơn để thực hiện những gì bạn đang cố gắng làm.
Nick

chúng tôi đang cố gắng hoãn việc tải quảng cáo của bên thứ 3 cho đến khi kết thúc trang. những quảng cáo đó được gọi thông qua 2 thẻ script, vì vậy tôi muốn chạy một hàm sau khi tải trang để đưa chúng vào động.
Doug

2
Không phải tất cả các tập lệnh của bên thứ ba đều được thiết kế để có thể hoãn lại. Nếu tập lệnh sử dụng document.writevà bạn gọi nó sau khi tải trang, nó sẽ phá hủy trang.
bobince

1
Tại sao không nhập các thẻ đó trong <iframe>các phần tử? Bạn có thể trì hoãn việc đặt <iframe>URL cho đến khi sẵn sàng.
Pointy

Câu trả lời:


103

Bạn có thể đặt tập lệnh vào một tệp riêng biệt, sau đó sử dụng $.getScriptđể tải và chạy nó.

Thí dụ:

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

2
cảm ơn, nhưng điều đó sẽ gắn nó vào DOM? Tôi nhận ra rằng tôi đã bỏ qua thông tin quan trọng đó, rằng tôi cần thẻ script được chèn vào DOM, được đánh giá, tại thời điểm đó, nó trả về mã quảng cáo của bên thứ 3 để hiển thị trên trang web của chúng tôi trong một <div> cụ thể.
Doug

1
$.getScriptsẽ chỉ tải một tệp .js qua AJAX và thực thi nó. Tập lệnh không cần phải ở trong DOM để có thể truy cập một div trên trang của bạn.
Rocket Hazmat

6
Nhưng với $.getScript()script sẽ cần trên cùng một miền hoặc cả miền từ xa và trình duyệt sẽ cần hỗ trợ CORS.
hippietrail

14
@hippietrail Điều đó thực sự không đúng. Nó chỉ chèn một thẻ script ol 'thuần túy, không yêu cầu CORS hoặc cùng một miền. Tôi sử dụng điều này để rút ngắn mã để tải Google Analytics chẳng hạn và nó tải rất tốt. Trên thực tế, đoạn mã jquery thực tế đang chạy khá giống với đoạn mã GA.
Chris Moschini

39
Vì câu trả lời từ @hippietrail sẽ thu hút nhiều sự chú ý nhất với 4 lượt ủng hộ, nên cần phải khẳng định rõ ràng rằng anh ta không chính xác. Như tài liệu jQuery nêu bật trong $.ajaxghi chú của họ : "Yêu cầu tập lệnh và JSONP không phải tuân theo các hạn chế về chính sách gốc giống nhau." nguồn . Nói cách khác, $.getScriptcó thể kéo các tệp .js từ các miền khác, không chỉ của riêng bạn .
11

64

Hãy thử những cách sau:

<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 để sử dụng appendđể thêm tập lệnh. Nối các nguyên nhân ngay cả tập lệnh nội tuyến để đánh giá ngay lập tức (chỉ những gì tôi cần). Cảm ơn
Gone Coding

1
Tôi đã gặp rất nhiều vấn đề trong IE8 / 9 với cách tiếp cận này. Cụ thể là lỗi Tràn ngăn xếp. Tôi đã sử dụng phương thức $ .getScript () bên dưới để thực hiện công việc này.
zmonteca

1
Có @jcoffland cái này được viết vào tháng 10 năm 2010 :)
Bassem

Nếu trang có chứa mã này được tải bằng AJAX, trình duyệt sẽ đưa ra cảnh báo "Synchronous XMLHttpRequest trên luồng chính không được dùng nữa vì những tác động có hại đến trải nghiệm của người dùng cuối".
Rajshekar Reddy

@Reddy Nhận xét tuyệt vời. Điều này đã được đăng vào tháng 10 năm 2010, tôi chắc chắn rằng phương pháp này bây giờ không còn là một cách tiếp cận hợp lệ / được khuyến nghị, người dùng phải tiến hành theo quyết định của riêng mình.
Bassem

34

Đây là cách chính xác để làm điều đó với JQuery hiện đại (2014):

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

hoặc nếu bạn thực sự muốn thay thế một div, bạn có thể làm:

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

3
Hoặc thay vì .text ( 'một số kịch bản ở đây'), bạn có thể viết .attr ( 'src', 'path_to_your_js_file')
Serhii Maksymchuk

11

Một cách đơn giản hơn là:

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

Bạn cũng có thể sử dụng biểu mẫu này để tải css.


6
Bạn có thể muốn tránh đặt các chuỗi </script>trong mã nguồn của bạn mặc dù vì nó có thể gây ra vấn đề phân tích cú pháp: stackoverflow.com/questions/236073/...
iX3

2
trốn thoát cuối cùng /đã làm thủ thuật cho tôi:$('head').append('<script src="your.js"><\/script>');
jerik

5

Câu trả lời này về mặt kỹ thuật tương tự hoặc bằng với những gì jcoffland đã trả lời. Tôi vừa thêm một truy vấn để phát hiện xem một tập lệnh đã có hay chưa. Tôi cần điều này vì tôi làm việc trong một trang web mạng nội bộ với một vài mô-đun, trong đó một số đang chia sẻ tập lệnh hoặc mang tập lệnh của riêng chúng, nhưng những tập lệnh này không cần phải tải lại mọi lúc. Tôi đang sử dụng đoạn mã này từ hơn một năm nay trong môi trường sản xuất, nó hoạt động giống như một charme. Tự nhận xét: Vâng, tôi biết, sẽ đúng hơn nếu hỏi nếu một hàm tồn tại ... :-)

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

btw. Tôi cũng làm như vậy với các bảng định kiểu: if (! $ ('Head> link [href = "widgets / css / widgets.css"]'). Length) {$ ('head'). Append ($ ('<link / > '). attr (' rel ',' stylesheet '). attr (' href ',' widgets / css / widgets.css ')));}
ddlab

2

Có một cách giải quyết nghe giống hack hơn và tôi đồng ý rằng đó không phải là cách thanh lịch nhất để làm điều đó, nhưng hoạt động 100%:

Giả sử phản hồi AJAX của bạn giống như

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

Lưu ý rằng tôi đã cố tình bỏ qua thẻ đóng. Sau đó, trong tập lệnh tải ở trên, hãy thực hiện như sau:

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

Chỉ cần đừng hỏi tôi tại sao :-) Đây là một trong những điều tôi đã đến do kết quả của các thử nghiệm gần như ngẫu nhiên tuyệt vọng và thất bại.

Tôi không có gợi ý đầy đủ về cách hoạt động của nó, nhưng thú vị là nó sẽ KHÔNG hoạt động nếu bạn nối thẻ đóng vào một dòng.

Những lúc như thế này, tôi cảm thấy mình đã chia thành công cho số 0.


3
Nó sẽ không hoạt động nếu thẻ tập lệnh đóng nằm trong một mảnh vì trình duyệt coi nó là thẻ đóng cho tập lệnh của bạn thay vì một chuỗi ký tự.
Gone Coding

1
<\/script>sẽ có giá trị mặc dù
SP

Tôi nghĩ quan điểm của @ TrueBlueAussie là đáp lại nhận xét của bạn "Đừng hỏi tôi tại sao ... nhưng thú vị là, nó sẽ KHÔNG hoạt động nếu bạn thêm thẻ đóng vào một dòng." Ông giải thích lý do tại sao để bất kỳ độc giả nào muốn có câu trả lời tốt hơn là "Tôi không biết" có thể dễ dàng tìm thấy nó hơn. Xem thêm: javascript.crockford.com/script.html
iX3

1
@Sathvik là chính xác, theo liên kết đó. Nhận xét của Ash dường như là phản hồi cho một bình luận đã bị xóa.
Arlen Beiler

2

Thí dụ:

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

Nó sẽ hoạt động. Tôi đã thử nó; cùng một kết quả. Nhưng khi tôi sử dụng cái này:

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

Điều này đã làm việc cho tôi.

Chỉnh sửa: Tôi quên #someelement(btw tôi có thể muốn sử dụng #someElementvì quy ước)

Điều quan trọng nhất ở đây là dấu + = để html được thêm vào và không bị thay thế.

Để lại bình luận nếu nó không hoạt động. Tôi muốn giúp bạn!


2

Đây là một cách rõ ràng hơn nhiều - không cần jQuery - thêm một tập lệnh làm con cuối cùng của <body>:

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

Nhưng nếu bạn muốn thêmtải các tập lệnh, hãy sử dụng phương pháp của Rocket Hazmat .


-4

Nếu bạn đang cố gắng chạy một số JavaScript được tạo động, bạn sẽ tốt hơn một chút bằng cách sử dụng eval. Tuy nhiên, JavaScript là một ngôn ngữ động đến nỗi bạn thực sự không cần phải sử dụng nó.

Nếu tập lệnh là tĩnh, thì getScript-suggestion của Rocket là cách để thực hiện.

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.