How do you disable the animation that occurs when you use the arrow keys to navigate within a WebView in Mac OS X Lion?
The behavior I’m trying to change appears to be the default for WebViews on Mac OS X Lion. If you load a document into a WebView, set the insertion point, and then use the Up Arrow and Down Arrow keys to navigate, scrolling is not instantaneous — there’s an animation (the view visibly scrolls up or down).
Here’s an Xcode project you can use to see this behavior (just run the application, set the insertion point within the document, and then use the Up Arrow and Down Arrow keys to navigate such that the view scrolls):
http://dl.dropbox.com/u/78928597/WebViewTest.zip
The behavior I’m trying to achieve is what happens in Safari. If you open an html document whose contenteditable attribute is set to true in Safari, you can set the insertion point within the document, and then navigate by using the Up Arrow and Down Arrow keys. When you navigate in this way, scrolling is not animated. The view scrolls instantaneously.
Here is an html document you can use to see this behavior:
http://dl.dropbox.com/u/78928597/WebViewTest.html
Since Safari uses a WebView, and it scrolls instantaneously, it seems like there should be a way to change the scrolling behavior of any WebView, but I’ve had no luck in finding it.
Note that you need to set the insertion point before you navigate with the arrow keys, otherwise you’ll see different behavior.
I think there is a way to do this, but it requires using the Objective-C runtime to modify a private method of a private class.
To use the Objective-C runtime, add
to the
#importdirectives at the top of AppDelegate.m in your Xcode project.Scroll animation appears to occur in the private method
of
NSClipView.We cannot modify the
NSClipViewobject (actually an instance of a private classWebClipView) managed by aWebViewthrough subclassing. Instead, we can use a technique called method swizzling.In the
@implementationof yourAppDelegateclass, addYou can read more about what’s happening here in Mike Ash’s article, “Method Replacement for Fun and Profit”; I’m using “Direct Override” method swizzling.
As a result of this code,
scrollTo_override()will be called instead of theWebClipViewmethod-[_scrollTo:animateScroll:flashScrollerKnobs:]. AllscrollTo_override()does is call the original-[_scrollTo:animateScroll:flashScrollerKnobs:]with 2 as theanimationSpecifier. This seems to prevent scroll animation from occurring.