2011-11-20 39 views
8

Tôi đang cố gắng tải Skyscanner API động nhưng có vẻ như nó không hoạt động. Tôi đã thử mọi cách có thể tôi có thể nghĩ đến và tất cả điều đó xảy ra khi nội dung biến mất.Đang cố tải một API và một tệp JS động

Tôi đã thử console.log không cung cấp kết quả; Tôi đã thử các phần tử từ các công cụ phát triển của chrome và trong khi tất cả css của nội dung vẫn giữ nguyên, nội dung vẫn biến mất (tôi nghĩ nó có thể thêm hiển thị: không có gì trên loại html/body). Tôi đã thử tất cả các thủ thuật asynch của Google, nhưng lại là một trang trống. Tôi đã thử tất cả các plugin js cho tải async với kết quả tương tự.

Tài liệu API của AdWords kém và trong khi chúng cung cấp gọi lại, nó không hoạt động theo cách gọi lại của API của Google.

Ví dụ: http://jsfiddle.net/7TWYC/

Ví dụ với tải API trong phần head: http://jsfiddle.net/s2HkR/

Vậy làm thế nào tôi có thể tải các api vào nút bấm hoặc async? Không có tệp nằm trong phần HEAD. Nếu có một cách để ngăn chặn document.write làm cho trang trống hoặc bất kỳ cách nào khác. Tôi sẽ không nhớ bằng cách sử dụng js đồng bằng, jQuery hay PHP.

EDIT:

tôi đã thiết lập một tiền thưởng đến 250 ontop 50 tôi đã từng.

Orlando Leite đã trả lời một ý tưởng thực sự gần gũi về cách thực hiện tải asynch api này mặc dù một số tính năng không hoạt động như chọn ngày và tôi không thể đặt kiểu.

Tôi đang tìm câu trả lời trong đó tôi sẽ có thể sử dụng tất cả các tính năng để nó hoạt động vì nó hoạt động nếu nó đang tải khi tải.

Đây là fiddle cập nhật bởi Orlando: http://jsfiddle.net/cxysA/12/

-

EDIT 2 ON Gijs ĐÁP:

Gijs đề cập hai liên kết vào ghi đè document.write. Đó là một ý tưởng tuyệt vời nhưng tôi nghĩ rằng không thể hoàn thành những gì tôi đang cố gắng.

tôi đã sử dụng Resig cách của John để ngăn chặn document.write đều có thể được tìm thấy ở đây: http://ejohn.org/blog/xhtml-documentwrite-and-adsense/

Khi tôi sử dụng phương pháp này, tôi nạp API successfuly nhưng file snippets.js không tải ở tất cả.

Fiddle: http://jsfiddle.net/9HX7N/

+0

Dường như kịch bản tải kịch bản khác, dựa trên các API key. Thật kỳ lạ, khi tôi nhấp vào nút, nó làm sạch thẻ cơ thể o.O –

+0

đó là câu hỏi của tôi – jQuerybeast

+0

Tôi thích rằng xử lý của bạn là jQuerybeast và đại diện của bạn là 666. Công việc của bạn ở đây được thực hiện. – ThinkingStiff

Trả lời

3

Đối với các trường hợp có vấn đề như thế này, bạn chỉ có thể ghi đè document.write. Hacky là địa ngục, nhưng nó hoạt động và bạn có thể quyết định nơi mà tất cả các nội dung đi. Xem ví dụ. this blogpost by John Resig. Điều này bỏ qua IE, nhưng với một chút công việc, thủ thuật cũng hoạt động trong IE, xem ví dụ. this blogpost. Vì vậy, tôi muốn đề nghị ghi đè lên document.write với chức năng của riêng bạn, thực hiện hàng loạt khi cần thiết và đặt nó vào nơi bạn muốn (ví dụ: trong div ở dưới cùng của <body> '). Điều đó sẽ ngăn chặn các kịch bản từ nuking nội dung trang của bạn.

Chỉnh sửa: OK, vì vậy, tôi đã dành một chút thời gian để xem tập lệnh này. Để tham khảo trong tương lai, hãy sử dụng một cái gì đó như http://jsbeautifier.org/ để điều tra các tập lệnh của bên thứ ba. Dễ dàng hơn nhiều để đọc theo cách đó. May thay, hầu như không có bất kỳ sự can thiệp/giảm thiểu nào, và vì vậy bạn có một bổ sung cho tài liệu API của họ (mà tôi không thể tìm thấy, nhân tiện - tôi chỉ tìm thấy 'thuật sĩ mã' mà tôi không quan tâm) .

Dưới đây là một ví dụ gần như làm việc: http://jsfiddle.net/a8q2s/1/

Dưới đây là các bước tôi đã:

  1. override document.write. Điều này cần xảy ra trước bạn tải tập lệnh ban đầu. Hàm thay thế của bạn nên nối thêm chuỗi mã của chúng vào DOM. Đừng gọi số document.write cũ, điều đó sẽ chỉ khiến bạn gặp lỗi và không làm những gì bạn muốn. Trong trường hợp này bạn may mắn vì tất cả nội dung nằm trong một cuộc gọi document.write đơn lẻ (hãy kiểm tra nguồn của tập lệnh ban đầu). Nếu đây không phải là trường hợp, bạn sẽ phải bó tất cả mọi thứ cho đến khi HTML họ đã cho bạn là hợp lệ và/hoặc bạn chắc chắn không có gì khác đến.
  2. tải tập lệnh ban đầu lên nút bấm bằng jQuery $.getScript hoặc tương đương. Vượt qua một hàm gọi lại (tôi đã sử dụng một tham chiếu hàm được đặt tên cho rõ ràng, nhưng bạn có thể inline nó nếu bạn thích).
  3. Yêu cầu Skyscanner tải mô-đun.

Chỉnh sửa # 2: Hah, họ có API (skyscanner.loadAndWait) để nhận được cuộc gọi khi tập lệnh của họ đã được tải. Sử dụng hoạt động:

http://jsfiddle.net/a8q2s/3/

(lưu ý: đây vẫn dường như sử dụng một vòng lặp thời gian chờ trong nội bộ)

+0

Tôi đang cố gắng sắp xếp điều này. Nghiêm túc nếu tôi có thể đoán ra tôi sẽ là người đàn ông hạnh phúc nhất. – jQuerybeast

+0

Tôi tin rằng điều này là không thể. Bạn phải tải api, sau đó tải đoạn mã và sau đó thiết lập một cuộc gọi lại. Nếu bạn dừng document.write trước đoạn trích, đoạn mã sẽ không tải. Và ngược lại, nếu bạn tải đoạn mã trước, trang sẽ trống. Kiểm tra fiddle của tôi: http://jsfiddle.net/bLmer/ – jQuerybeast

+0

Về cơ bản tôi đang tìm kiếm một cách mà nó sẽ cho phép document.write mới nhưng ngăn chặn để xóa trang. – jQuerybeast

3

Trong skyrunner.js tập tin họ đang sử dụng document.write để làm cho trang trống theo yêu cầu tải lại ... Vì vậy, đây là một số hậu quả trong trường hợp của bạn ..

  1. này làm cho trang trống khi bạn nhấp vào nút.
  2. Vì vậy, nó loại bỏ mọi thứ khỏi trang ngay cả 'jQuery.js', đó là lý do tại sao cuộc gọi lại không hoạt động .. tức là chức năng chính không thể được gọi vì điều này được viết bằng jQuery.
  3. Và bạn đã bỏ lỡ thẻ mục tiêu 'div' có id = map (theo mã).Trên thực tế, đây là mục tiêu tải bản đồ.
  4. Một điều tôi đã quan sát được là bản đồ không thực sự là một div trong bối cảnh hiện tại, đó là bản đồ api để tải.

Ở đây bạn phải đi với phương pháp tiếp cận trường học cũ, Đó là .. Bạn nên bao gồm tệp skyrunner.js của bạn ở đầu nội dung đầu.

Vì vậy hãy thử tải xuống tệp đó và đưa vào thẻ đầu.

Cảm ơn

+0

@ brandon-tilley Cảm ơn bạn đã chỉnh sửa :-) – Exception

+0

Tôi đã nhận thấy. Câu hỏi của tôi là KHÔNG sử dụng skyscanner.js trong đầu bởi vì đôi khi nó bị lag, khiến toàn bộ webapp của tôi bị tụt hậu. – jQuerybeast

+0

Có cách nào trên trái đất (PHP, AJAX) để tải trên nút bấm không? Bất cứ điều gì có thể nói, hủy bỏ tất cả các trang document.write trống? – jQuerybeast

5

I belive những gì bạn muốn là nó:

function loadSkyscanner() 
{ 
    function loaded() 
    { 
     t.skyscanner.load('snippets', '1', {'nocss' : true}); 

     var snippet = new t.skyscanner.snippets.SearchPanelControl(); 
     snippet.setCurrency('GBP'); 
     snippet.setDeparture('uk'); 
     snippet.draw(document.getElementById('snippet_searchpanel')); 
    } 

    var t = document.getElementById('sky_loader').contentWindow; 
    var head = t.document.getElementsByTagName('head')[0]; 
    var script = document.createElement('script'); 
    script.type = 'text/javascript'; 
    script.onreadystatechange= function() { 
     if(this.readyState == 'complete') loaded(); 
    } 
    script.onload= loaded; 
    script.src= 'http://api.skyscanner.net/api.ashx?key=PUT_HERE_YOUR_SKYSCANNER_API_KEY'; 
    head.appendChild(script); 
} 

$("button").click(function(e) 
{ 
    loadSkyscanner(); 
}); 

Đó là Skyscanner tải trong iframe # sky_loader, sau khi cuộc gọi nạp chức năng để tạo ra các SearchPanelControl. Nhưng cuối cùng, đoạn trích rút ra trong tài liệu chính. Nó thực sự là một cách giải quyết kỳ lạ, nhưng nó hoạt động.

Hạn chế duy nhất là bạn cần khung nội tuyến. Nhưng bạn có thể ẩn nó bằng cách sử dụng display:none.

A working example

EDIT

Xin lỗi anh chàng, tôi không nhìn thấy nó. Bây giờ chúng ta có thể thấy API skyscanner khủng khiếp đến mức nào. Nó đặt hai div để thực hiện tự động hoàn thành, nhưng không liên quan đến phần tử mà bạn gọi để vẽ, mà là tài liệu. Khi tập lệnh được tải trong khung nội tuyến, tài liệu là tài liệu iframe.

Có một giải pháp, nhưng tôi không khuyên bạn, thực sự là một cách giải quyết:

function loadSkyscanner() 
{ 
    var t; 
    this.skyscanner; 
    var iframe = $("<iframe id=\"sky_loader\" src=\"http://fiddle.jshell.net/orlleite/2TqDu/6/show/\"></iframe>"); 

    function realWorkaround() 
    { 
     var tbody = t.document.getElementsByTagName("body")[0]; 
     var body = document.getElementsByTagName("body")[0]; 

     while(tbody.children.length != 0) 
     { 
      var temp = tbody.children[0]; 
      tbody.removeChild(temp); 
      body.appendChild(temp); 
     } 
    } 

    function snippetLoaded() 
    { 
     skyscanner = t.skyscanner; 

     var snippet = new skyscanner.snippets.SearchPanelControl(); 
     snippet.setCurrency('GBP'); 
     snippet.setDeparture('uk'); 
     snippet.draw(document.getElementById('snippet_searchpanel')); 

     setTimeout(realWorkaround, 2000); 
    } 

    var loaded = function() 
    { 
     console.log("loaded"); 
     t = document.getElementById('sky_loader').contentWindow; 

     t.onLoadSnippets(snippetLoaded); 
    } 

    $("body").append(iframe); 
    iframe.load(loaded); 
} 

$("button").click(function(e) 
{ 
    loadSkyscanner(); 
}); 

tải một iframe với một html người tải và gọi lại khi đoạn được tải. Sau khi nạp, tạo đoạn mã bạn muốn và sau khi đặt thời gian chờ vì chúng tôi không thể biết khi nào SearchPanelControl được tải. Điều này realWorkaround di chuyển các div tự động hoàn thành vào tài liệu chính.

You can see a work example here

The iframe loaded is this

EDIT

Sửa lỗi bạn phát hiện và cập nhật các liên kết.

vòng lặp for đã biến mất và thêm một lúc, hoạt động tốt hơn ngay bây giờ.

while(tbody.children.length != 0) 
    { 
     var temp = tbody.children[0]; 
     tbody.removeChild(temp); 
     body.appendChild(temp); 
    } 
+0

Nó dường như là những gì tôi đang tìm kiếm mặc dù xin lưu ý rằng tính năng tự động hoàn thành không hoạt động? Vui lòng kiểm tra tại đây: http://jsfiddle.net/s2HkR/ Đây là cách tải mặc định của API. Lưu ý tự động hoàn thành biểu mẫu tìm kiếm khi bạn nhập một thành phố. Trong ví dụ làm việc của bạn, điều đó đang bị ngừng hoạt động. Ý tưởng của bạn làm nó mặc dù là thiên tài và tôi không nhớ có một iframe ẩn. Cảm ơn – jQuerybeast

+0

Tuyệt vời. Vâng, bạn không khuyên bạn nên nhưng tôi nghĩ rằng tôi đã không có một giải pháp khác không? Nó dành cho webapp của bảng điều khiển và khi máy chủ của họ bị lag, tất cả các trang tổng quan đều bị lag. – jQuerybeast

+0

Được rồi, một giờ tôi đang cố gắng tìm ra điều này. Tôi nghĩ rằng đó là một vấn đề trên trang của tôi, nhưng tôi chỉ tìm ra rằng nó không hoạt động trên ví dụ của bạn hoặc. Kiểm tra này ra: http://jsfiddle.net/orlleite/cxysA/7/show/ Nếu bạn xem fiddle của riêng bạn, nó không hiển thị bất cứ điều gì. (Điều này làm việc mặc dù: http://fiddle.jshell.net/orlleite/cxysA/7/show/) Cảm ơn một lần nữa – jQuerybeast

Các vấn đề liên quan