2010-04-23 28 views
30

Tôi có một trang HTML như sau:jQuery - thẻ script trong HTML được phân tách ra bởi jQuery và không thực hiện

<html> 
<body> 
<div id='something'> 
    ... 
    <script> 
    var x = 'hello world'; 
    </script> 
    ... 
</div> 
</body> 
</html> 

Trên trang khác, tôi đang làm điều này:

$.ajax({ 
    url: 'example.html', 
    type: 'GET', 
    success: function(data) { 
     $('#mydiv').html($(data).find('#something').html()); 
     alert(x); 
    } 
}); 

jQuery, tuy nhiên, không thực thi javascript trong tệp đầu tiên, mặc dù tài liệu cho biết. Làm thế nào tôi có thể làm cho nó làm điều đó?

EDIT: Thật không may trong ứng dụng thế giới thực tôi đang làm việc trên tôi không có quyền kiểm soát những gì trang "được bao gồm" có. Chúng tôi đang ở trên cùng một tên miền, nhưng tôi không thể sửa đổi mã mà nó xuất ra vì nó là một sản phẩm đóng gói, bộ phận CNTT của chúng tôi sẽ không cho phép chúng tôi sửa đổi.

+0

Bạn đã kiểm tra để xem những gì sẽ xảy ra nếu bạn làm một 'alert() 'trong kịch bản gốc (có nghĩa là, bên trong trang "bao gồm")? – Pointy

+0

Vâng, nếu bạn không thể thay đổi nó, bạn có thể kiểm tra lý thuyết của tôi bằng cách thêm một số mã gỡ lỗi để xem những gì '$ (dữ liệu) .html()' trông giống như. Nếu điều đó không chứa các thẻ script, thì đó là vấn đề. Bạn có thể muốn tìm trong nguồn jQuery và xem nó làm gì để loại bỏ các script; nó sử dụng một regex khá xấu xí nhưng có lẽ bạn có thể tự mình cắt các đoạn mã và sau đó thực thi chúng. – Pointy

Trả lời

40

Như chóp chỉ ra (cớ sự chơi chữ), jQuery messes với các thẻ SCRIPT khi bạn vượt qua HTML để $(). Nó không loại bỏ chúng mặc dù - nó chỉ đơn giản là thêm chúng vào bộ sưu tập DOM được tạo ra từ HTML của bạn. Bạn có thể thực hiện các script như sau:

$.ajax({ 
    url: 'example.html', 
    type: 'GET', 
    success: function(data) { 

     var dom = $(data); 
     $('#mydiv').html(dom.find('#something').html()); 
     dom.filter('script').each(function(){ 
      $.globalEval(this.text || this.textContent || this.innerHTML || ''); 
     }); 
    } 
}); 
+1

Thiên tài. Cảm ơn bạn. –

+5

Nó sẽ là tốt đẹp nếu jQuery tiếp xúc với nó 'evalScript' thực hiện. Sau đó bạn có thể thực hiện 'dom.filter ('script'). Mỗi ($. EvalScript)', sẽ xử lý các kịch bản với các thuộc tính 'src', giống như các phương thức thao tác dom khác làm. –

+0

Đối với tôi, nó chỉ hoạt động, nếu tôi làm 'dom.filter' SAU thay thế nội dung. Có vẻ hợp lý với tôi, nhưng khác với những gì có vẻ là một câu trả lời đủ điều kiện (xem ở trên). Ai đó có thể sửa lỗi này? –

0

Tôi hy vọng trang đầu tiên được thực thi JavaScript, tuy nhiên điều này là không thể truy cập từ trang thứ hai, vì vậy alert(x) sẽ không làm việc

Nếu bạn muốn x trở lại, bạn sẽ phải đầu ra nó vào AJAX phản ứng.

+0

Ah - Tôi sắp nói tại sao đây không phải là vấn đề, nhưng tôi nghĩ tôi đã tìm ra thỏa thuận là gì. – Pointy

3

Tôi không hoàn toàn chắc chắn về điều này, nhưng có thể những gì đang xảy ra là khi jQuery xây dựng đoạn từ $(data), thẻ tập lệnh sẽ bị mất tại thời điểm đó.

Nếu bạn có thể sắp xếp cho trang bao gồm để thực sự chỉ là một đoạn:

<div id='something'> 
    <!-- ... --> 
    <script>var x = 'hello world';</script> 
</div> 

mà không cần bất cứ thứ xung quanh khác, sau đó gọi lại thành công của bạn có thể làm điều này:

success: function(data) { 
    $('#mydiv').html(data); 
} 

Bây giờ những kịch bản các thẻ sẽ được chú ý bởi hàm jQuery html(), tìm kiếm chúng một cách rõ ràng và loại bỏ chúng. Tuy nhiên, nó giữ lại các khối script đó, và nó thực hiện chúng sau khi nó hoàn thành việc cập nhật các nội dung đích.

25

Như thay thế cho @ James trả lời, chuỗi HTML có thể được phân tích với $.parseHTML(), bằng cách chú ý thêm cờ boolean bao gồm các kịch bản để true:

$.ajax({ 
    url: 'example.html', 
    type: 'GET', 
    success: function(data) { 

     var content = $($.parseHTML(data, document, true)).find('#something'); 
     $('#mydiv').html(content); 

    } 
}); 

theo cách này, mọi tập lệnh được nhúng trong văn bản đã tải xuống đều có thể được thực thi.

+1

Cảm ơn lời khuyên guari - điều này nên được bình chọn vì nó là một lựa chọn hiệu quả hơn. – eugene

+1

Ngọt, chỉ là những gì tôi muốn – shramee

1

Giải pháp 1: máy chủ trở lại nội dung chính xác

$.ajax({ 
    url: 'example.html', 
    type: 'GET', 
    success: function(data) { 

     $('#mydiv').html(data); 

    } 
}); 

Giải pháp 2: Sử dụng innerHTML

$.ajax({ 
    url: 'example.html', 
    type: 'GET', 
    success: function(data) { 

     var dom = $(data); 
     $('#mydiv').html(dom.find('#something')[0].innerHTML); 

    } 
}); 
Các vấn đề liên quan