尝试动态加载 API 和 JS 文件 [英] Trying to load an API and a JS file dynamically
问题描述
我正在尝试动态加载 Skyscanner API,但它似乎不起作用.我尝试了我能想到的所有可能的方法,但所有内容都消失了.
I am trying to load Skyscanner API dynamically but it doesn't seem to work. I tried every possible way I could think of and all it happens the content disappears.
我试过 console.log 没有结果;我尝试了 chrome 开发人员工具中的元素,虽然所有内容的 css 保持不变,但内容仍然消失(我认为它可能是在 html/body 类型上添加 display:none ).我尝试了所有谷歌的异步技巧,但又是空白页.我尝试了所有用于异步加载的 js 插件,结果仍然相同.
I tried console.log which gives no results; I tried elements from chrome's developers tools and while all the content's css remains the same, still the content disappears (I thought it could be adding display:none on the html/body sort of). I tried all Google's asynch tricks, yet again blank page. I tried all js plugins for async loading with still the same results.
Skyscanner 的 API 文档很差,虽然他们提供了回调,但与谷歌 API 的回调不同.
Skyscanner's API documentation is poor and while they offer a callback it doesn't work the way google's API's callback do.
头部加载 API 示例:http://jsfiddle.net/s2HkR/
Example with loading API in head section: http://jsfiddle.net/s2HkR/
那么如何在按钮单击或异步加载 api?没有文件在 HEAD 部分.如果有办法阻止 document.write 使页面空白或任何其他方式.我不介意使用普通的 js、jQuery 或 PHP.
So how can I load the api on button click or async? Without the file being in the HEAD section. If there is a way to prevent the document.write to make the page blank or any other way. I wouldn't mind using plain js, jQuery or PHP.
在我之前的 50 个赏金基础上,我将赏金设置为 250 个.
I've set a bounty to 250 ontop of the 50 I had previously.
Orlando Leite 回答了一个关于如何使这个异步 api 加载的非常接近的想法,尽管某些功能不起作用,例如选择日期并且我无法设置样式.
Orlando Leite answered a really close idea on how to make this asynch api load although some features doesn't work such as selecting dates and I am not able to set styling.
我正在寻找一个我将能够使用所有功能的答案,以便它可以像在加载时加载一样工作.
I am looking for an answer of which I will be able to use all the features so that it works as it would work if it was loading on load.
这是奥兰多更新的小提琴:http://jsfiddle.net/cxysA/12/
Here is the updated fiddle by Orlando: http://jsfiddle.net/cxysA/12/
-
在 Gijs 答案上编辑 2:
Gijs 提到了两个覆盖 document.write 的链接.这听起来很棒,但我认为不可能完成我正在尝试的事情.
Gijs mentioned two links onto overwriting document.write. That sounds an awesome idea but I think it is not possible to accomplish what I am trying.
我使用 John 的 Resig 方式来防止 document.write 可以在这里找到:http://ejohn.org/blog/xhtml-documentwrite-and-adsense/
I used John's Resig way to prevent document.write of which can be found here: http://ejohn.org/blog/xhtml-documentwrite-and-adsense/
当我使用此方法时,我成功加载了 API,但 Snippets.js 文件根本没有加载.
When I used this method, I load the API successfuly but the snippets.js file is not loading at all.
小提琴:http://jsfiddle.net/9HX7N/
推荐答案
对于这种有问题的情况,你可以覆盖document.write
.像地狱一样糟糕,但它有效,您可以决定所有内容的去向.见例如.John Resig 的这篇博文.这忽略了 IE,但通过一些工作,这个技巧也适用于 IE,参见例如.这篇博文.
For problematic cases like this, you can just overwrite document.write
. Hacky as hell, but it works and you get to decide where all the content goes. See eg. this blogpost by John Resig. This ignores IE, but with a bit of work the trick works in IE as well, see eg. this blogpost.
所以,我建议用你自己的函数覆盖 document.write
,在必要的地方批量输出,然后把它放在你喜欢的地方(例如,在你的 document.write
底部的一个 div代码>
So, I'd suggest overwriting document.write
with your own function, batch up the output where necessary, and put it where you like (eg. in a div at the bottom of your <body>
'). That should prevent the script from nuking your page's content.
好的,所以我有/花了一些时间来研究这个脚本.为了将来参考,请使用诸如 http://jsbeautifier.org/ 之类的内容来调查第三方脚本.这样读起来容易多了.幸运的是,几乎没有任何混淆/缩小,所以你有他们的 API 文档的补充(顺便说一下,我找不到 - 我只找到了我不感兴趣的代码向导").
OK, so I had/took some time to look into this script. For future reference, use something like http://jsbeautifier.org/ to investigate third-party scripts. Much easier to read that way. Fortunately, there is barely any obfuscation/minification at all, and so you have a supplement for their API documentation (which I was unable to find, by the way -- I only found 'code wizards', which I had no interest in).
这是一个几乎可行的示例:http://jsfiddle.net/a8q2s/1/
Here's an almost-working example: http://jsfiddle.net/a8q2s/1/
这是我采取的步骤:
- 覆盖
document.write
.这需要在您加载初始脚本之前发生.您的替换函数应该将它们的代码字符串附加到 DOM 中.不要调用旧的document.write
,那只会给你带来错误,无论如何都不会做你想做的事.在这种情况下,您很幸运,因为所有内容都在一个document.write
调用中(检查初始脚本的来源).如果不是这种情况,您必须将所有内容进行批处理,直到他们提供给您的 HTML 有效和/或您确定没有其他内容. - 使用 jQuery 的
$.getScript
或等效代码在单击按钮时加载初始脚本.传递回调函数(为了清楚起见,我使用了命名函数引用,但如果您愿意,也可以将其内联). - 告诉 Skyscanner 加载模块.
- override
document.write
. This needs to happen before you load the initial script. Your replacement function should append their string of code into the DOM. Don't call the olddocument.write
, that'll just get you errors and won't do what you want anyway. In this case you're lucky because all the content is in a singledocument.write
call (check the source of the initial script). If this weren't the case, you'd have to batch everything up until the HTML they'd given you was valid and/or you were sure there was nothing else coming. - load the initial script on the button click with jQuery's
$.getScript
or equivalent. Pass a callback function (I used a named function reference for clarity, but you can inline it if you prefer). - Tell Skyscanner to load the module.
编辑 #2:哈,他们有一个 API (skyscanner.loadAndWait
),用于在脚本加载后获取回调.使用它:
Edit #2: Hah, they have an API (skyscanner.loadAndWait
) for getting a callback once their script has loaded. Using that works:
(注意:这似乎仍然在内部使用超时循环)
(note: this still seems to use a timeout loop internally)
这篇关于尝试动态加载 API 和 JS 文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!