3

我成功地使用了不可见的 UIWebView 作为 Javascript 片段的执行引擎。与某些页面的建议相反,它不需要可见。如果简单地宣布死亡

UIWebView* myJSExecutor = [UIWebView new];

它不仅执行任何stringByEvaluatingJavaScriptFromString:扔给它的东西,它甚至会冒泡alert()到桌面!(并不是你经常想这样做)免责声明:仅在 iOS 5+ 上测试

现在,我有另一个通常可见UIWebView的正常网页内容,我希望它暂停JavaScript 执行:即停止对计时器和 DOM 事件进行操作。我认为removeFromSuperviewwithstopLoading和 settingdelegate = nil可以解决问题。但是不,只要我将 UIWebView 添加回某个可见视图,我就可以看到计时器一直在运行。

我理解我的要求的精神分裂症。一方面我很欣赏它在后台工作(与一些观察相反),但另一方面我想暂停它。但我仍然想问是否有任何,甚至可能是私人的方式来暂停它。iOS 版 Safari 能够在后台暂停浏览器选项卡。适用于 iOS 的 Chrome 不能,这可能是一个可悲的负面证据 :(

4

3 回答 3

3

如果你正在寻找疯狂,我有一个想法。

我知道暂停 JavaScript 的唯一方法是显示警报、确认、提示或发送带有async=false.

隐藏 UIWebView 时是否隐藏警报?如果是这样,您可以在希望它冻结时发送警报。当您再次显示视图时,用户将不得不关闭它:

[web stringByEvaluatingJavaScriptFromString:@"alert('Press OK to continue...')"];

或者,也许您可​​以通过编程方式将其关闭。我相信你会同意这整个建议一定会带来麻烦,但这是一个想法。

于 2013-07-31T20:17:00.557 回答
1

这听起来很明显,但如果你可以编辑你在 UIWebView 中运行的 JS,你不能只在 JS 中存储一个名为“paused”的全局变量,并检查你的计时器何时触发吗?

var paused = false;
var thread = setInterval(function() {
    if(!paused) {
         // normal timer checking etc
    }
}, 300);

然后在删除 webview 时触发 [webView stringByEvaluatingJavaScriptFromString:@"paused = true;"] ,并在将其添加回视图时设置 paused = false 。

于 2013-08-05T13:54:25.960 回答
1

你需要一个完整的 UIWebView 吗?如果没有,您可以直接调用 JavaScriptCore。

- (NSString *)runJS:(NSString *)aJSString 
{
    JSContextRef ctx = JSGlobalContextCreate(NULL); 
    JSStringRef scriptJS = JSStringCreateWithUTF8CString([aJSString UTF8String]);
    JSValueRef exception = NULL;
    JSValueRef result = JSEvaluateScript([self JSContext], scriptJS, NULL, NULL, 0, &exception); 
    JSGlobalContextRelease(ctx);
    ...

这将使您对整个 JS 运行时有更多的控制,但不幸的是,除了释放整个上下文之外,我还没有找到一个 API 来暂停计时器的执行。

有关如何使用 JavaScriptCore 的更完整示例,请参阅https://github.com/jfahrenkrug/AddressBookSpy/blob/master/AddressBookSpy/AddressBookSpy/ABSEngine.m

于 2013-07-31T16:50:52.363 回答