3

我正在构建一个小型 Mac 应用程序,该应用程序通过 Web 套接字持续提供数据。处理完每个数据段后,数据以WebView. 新数据永远不会替换任何数据,WebView而是始终使用 DOM 操作将新数据附加WebView内容中。下面的代码示例应该让您了解我在做什么。

DOMDocument *doc = self.webview.mainFrame.DOMDocument;
DOMHTMLElement *container = (DOMHTMLElement *)[doc createElement:@"div"];
NSString *html = [NSString stringWithFormat:@"... omitted for the sake of brevity ... "];
[container setInnerHTML:html];
[doc.body appendChild:container];

的渲染WebView显然是异步发生的。有没有办法判断 DOM 操作何时完成并且内容已被绘制?我想使用类似[webview scrollToEndOfDocument:self]实现自动滚动的东西。侦听 DOM 事件并没有帮助,因为它们似乎是在 DOM 被修改但在这些更改被呈现之前触发的。到目前为止我使用的代码类似于以下内容

[self.webview.mainFrame.DOMDocument addEventListener:@"DOMSubtreeModified" listener:self useCapture:NO];

和这个结合

- (void)handleEvent:(DOMEvent *)event
{
    [self.webview scrollToEndOfDocument:self];
}

这段代码的问题是滚动发生得太早了。我基本上总是落后一个数据段。我可以注册在绘制内容时触发的任何类型的回调/通知吗?

4

1 回答 1

0

使用定时器

可以使用NSTimer. 该解决方案面临的挑战是确定何时禁用计时器以允许手动滚动。我无法做到后者。无论如何,这是使用计时器启用自动滚动的代码:

self.WebViewAutoScrollTimer = 
  [NSTimer scheduledTimerWithTimeInterval:1.0/30.0 
                                   target:self
                                 selector:@selector(scrollWebView:)
                                 userInfo:nil
                                  repeats:YES];

scrollWebView:只是一种scrollToEndOfDocument:在 Web 视图上调用的方法。

使用通知

由 web 视图发出的列表NSViewFrameDidChangeNotification只允许在帧大小更改的情况下滚动。这些变化发生在添加新内容时以及封装视图的大小发生变化时,例如调整窗口大小。我的实现没有区分这两种情况。

NSClipView *contentView = self.webView.enclosingScrollView.contentView;
[contentView setPostsFrameChangedNotifications:YES];
[[NSNotificationCenter defaultCenter] addObserverForName:NSViewFrameDidChangeNotification
                                                  object:contentView
                                                   queue:nil
                                              usingBlock:^(NSNotification *notification) {
                                                  [self.webView scrollToEndOfDocument:self];
                                              }];

注意:指示 web 视图的滚动视图的内容视图很重要——考虑几次,它就会开始变得有意义——当它的帧大小发生变化时发布通知,因为NSView默认情况下实例不这样做。这是使用上面示例中的前两行代码完成的。

于 2013-01-03T15:48:57.607 回答