我的应用正在使用 jQuery.getScript()加载外部javascript文件。当我使用书签或扩展程序启动应用程序一切正常。当应用程序通过KBX安装,但在 Chrome 内部使用 KBX扩展程序时,javascript文件中包含的功能在回调中无法访问,我得到:未捕获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进行安装的网址: 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');
};
*/
}
);
|>
}
}
}
答案 0 :(得分:3)
我不完全确定您的问题与KBX运行代码的沙盒环境有关,但我认为可能。这是我写的关于处理KBX http://geek.michaelgrace.org/2011/03/kynetxs-new-sandboxed-browser-extensions/
的沙盒环境的帖子我最近在Kynetx应用商店中发布了我的“Old School Retweet” Kynetx app,用于新发布的浏览器扩展程序。我非常喜欢新的扩展以及他们为用户和开发人员所做的一切。我在应用程序商店中发布应用程序时忘记的一点是新扩展程序是沙箱。 由于扩展是沙盒化的,因此扩展中的所有脚本的运行方式与以前的Kynetx扩展中的运行方式略有不同。在没有深入了解技术细节的情况下,之前的扩展只是将JavaScript注入到页面中,新扩展在沙箱中运行JavaScript,沙盒可以访问DOM,但无法访问页面上的任何其他内容。由于这个改变,我的转发应用程序破了,因为我使用Twitter.com加载的jQuery来调出新的推文框(我这样做是因为Twitter.com使用该库来绑定点击事件并触发它必须的事件来自绑定它的同一个库)。值得庆幸的是,在朋友的帮助下,我能够解决Firefox和Chrome的沙盒环境问题。 我是怎么做到的...... 如果应用程序不在沙盒中运行,我可以访问Twitter.com加载的jQuery以打开一个新的推文框
$("#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);
}
答案 1 :(得分:1)
你可以做的另一件事是让你的东西在沙箱之外可以访问的是在窗口级别声明你的东西(违背沙箱的目的,不推荐)。例如:如果要在沙箱中执行console.log,则console.log将不会登录到窗口控制台。但是,如果你说window.console.log,它会。所以,您可以(但不应该)通过以下方式声明var:
window.myvar = "MyValue";
这会使var成为窗口级变量。即使我正在反对这一点,我已经做了一两次测试。
答案 2 :(得分:1)
所以...我刚刚做了一些适用于FF和Chrome的东西。它不漂亮,但实际上并非如此。很高兴为两者提供一种解决方法,而不是必须以不同的方式为FF工作而不是Chrome。我需要从全局对象中获取值...但是沙箱阻止了这一点。有了这个黑客,我就能够为这两种浏览器做到这一点。
首先,从沙箱中...在document.body
的底部添加一个不可见的div$K('body').append('<div id="randomdiv" style="display:none;"></div>');
然后在document.head中创建一个脚本,将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();
让我知道你的想法。这对我来说是最容易的。