我的应用程序正在加载一个外部javascript文件jQuery.getScript()。当我使用bookmarklet或扩展来启动应用程序时,一切都很好。当应用程序通过KBX安装,虽然在Chrome与KBX扩展名 javascript文件中包含的函数在回调中不再可访问,我得到:Uncaught ReferenceError: myfunc未定义。
是否有任何技巧来访问包含的函数?
Bookmarklet: javascript:(function(){var d=document;var s=d.createElement('script');s.text="KOBJ_config={'rids':['a1135x30']};";d.body.appendChild(s);var l=d.createElement('script');l.src='http://init.kobj.net/js/shared/kobj-static.js';d.body.appendChild(l);})()
Chrome扩展:crx
通过KBX安装的url: app on KBX
下面是规则集:
ruleset a1135x30 {
meta {
name "test_external_js_loading"
description <<
debugging external loading in kbx
>>
author "loic devaux"
logging on
}
dispatch {
domain ".*"
}
global {
}
rule first_rule {
select when pageview ".*" setting ()
// pre { }
// notify("Hello World", "This is a sample rule.");
{
emit <|
$K.getScript('http://lolo.asia/kynetx_debug/js/myfunc.js',function() {
myfunc();
/*
* myfunc.js content:
myfunc = function(){
console.log('running myfunc');
};
*/
}
);
|>
}
}
}
我不完全确定您的问题是否与KBX运行代码的沙盒环境有关,但我认为可能是这样。这是我写的一篇关于处理KBX沙箱环境的文章http://geek.michaelgrace.org/2011/03/kynetxs-new-sandboxed-browser-extensions/
选自博客文章
我最近在Kynetx应用程序商店发布了我的"Old School Retweet"Kynetx应用程序,用于新发布的浏览器扩展。我非常喜欢新的扩展,以及它们为用户和开发人员所做的一切。当我在应用商店中发布应用时,我忘记了一些事情,即新的扩展是沙盒的。因为这些扩展是沙箱化的,所以这些扩展中的所有脚本的运行方式与以前的Kynetx扩展略有不同。在不涉及太多技术细节的情况下,之前的扩展只是将JavaScript注入到页面中,而新的扩展在沙箱中运行JavaScript,沙箱可以访问DOM,但不能访问页面上的任何其他内容。由于这个变化,我的转发应用程序崩溃了,因为我使用了由Twitter.com加载的jQuery来调出新的tweet框(我这样做是因为Twitter.com使用该库绑定点击事件并触发该事件,它必须来自绑定它的相同库)。幸运的是,在一个朋友的帮助下,我找到了Firefox和Chrome的沙盒环境的解决方案。我是怎么做到的……如果应用程序不是在沙箱中运行我可以访问Twitter.com加载的jQuery来打开一个新的tweet框
$("#new-tweet").trigger("click");
在Firefox沙箱中我可以访问沙箱外的页面
window['$']("#new-tweet").trigger("click");
如果我在Chrome沙箱,我可以创建一个脚本元素,有我想要执行的JavaScript。很粗糙,但很有效。:)
var trigger_click_script = document.createElement("script");
var fallback = "window['$']('#new-tweet').trigger('click');";
trigger_click_script.innerHTML = fallback;
document.getElementsByTagName("head")[0].appendChild(trigger_click_script);
这是我最终编写的JavaScript代码,当用户点击转发按钮时执行。
// get stuff to retweet
var tweet = $K(this).parents(".tweet-content").find(".tweet-text").text();
var name = $K(this).parents(".tweet-content").find(".tweet-screen-name").text();
// build tweet
var retweet = "RT @"+name+" "+tweet;
// open new tweet box
$("#new-tweet").trigger("click");
// hack for FF sandbox
if ($("#tweet-dialog:visible").length === 0) {
window['$']("#new-tweet").trigger("click");
}
// put tweet in new tweet box
$K(".draggable textarea.twitter-anywhere-tweet-box-editor").val(retweet).focus();
$K("#tweet_dialog a.tweet-button.button.disabled").removeClass("disabled");
// hack for chrome sandbox
if ($("#tweet-dialog:visible").length === 0) {
var fallback = "window['$']('#new-tweet').trigger('click'); ";
fallback += "window['$']('.draggable textarea.twitter-anywhere-tweet-box-editor').val('"+retweet+"').focus(); ";
fallback += "window['$']('#tweet_dialog a.tweet-button.button.disabled').removeClass('disabled'); ";
var trigger_click_script = document.createElement("script");
trigger_click_script.innerHTML = fallback;
document.getElementsByTagName("head")[0].appendChild(trigger_click_script);
}
另一种可以使您的内容在沙箱之外可访问的方法是在窗口级别声明您的内容(违背了沙箱的目的,不推荐使用)。例如:如果你想执行console.log,而在沙箱中,console.log不会记录到窗口控制台。但是,如果你说window。console。log,它会。因此,您可以(但不应该)以以下方式声明var:
window.myvar = "MyValue";
这将使变量成为窗口级变量。尽管我反对这样做,但我已经做了一两次测试。
所以…我只是做了一些同时适用于FF和Chrome的东西。它不漂亮,但这一切都不漂亮。很高兴有一个解决方案,而不是不得不为FF工作不同于Chrome。我需要从全局对象中获取值…但沙盒阻挡了这一点。通过这个hack,我可以用一种方式在两个浏览器上都做到这一点。
首先,从沙箱中…在文档底部添加一个不可见的div。身体
$K('body').append('<div id="randomdiv" style="display:none;"></div>');
然后在文档中创建一个脚本。将randomdiv的文本设置为我需要的值。
var temp = '$("#randomdiv").text(twttr.currentUserScreenName);';
var somescript = document.createElement("script");
somescript.innerHTML = temp;
document.getElementsByTagName("head")[0].appendChild(somescript);
然后……此时,在沙箱中,您可以从DOM中选择值,而不是从某个全局js对象中选择值。这就是你要做的。
var myvar = $K('#randomdiv').text();
让我知道你的想法。这对我来说是最简单的。