How to Programmatically Scroll Android WebView

48,262

Solution 1

I've found a better answer to this issue. It turns out that WebView does have scrollTo(), getScrollX() and getScrollY() methods as you'd expect. They're a bit hidden in the documentation because they're inherited from View (via AbsoluteLayout -> ViewGroup -> View). This is obviously a better way to manipulate the WebView's scroll position than the somewhat cumbersome JavaScript interface.

Solution 2

It turns out that the window.scrollTo() DOES work, you just can't add your own method named scrollTo(). For some reason my own scrollTo() method was being invoked when I called window.scrollTo().

So, in summary, to scroll a WebView to a particular DOM element, write a JavaScript function to do the scrolling:

function scrollToElement(id) {
    var elem = document.getElementById(id);
    var x = 0;
    var y = 0;

    while (elem != null) {
        x += elem.offsetLeft;
        y += elem.offsetTop;
        elem = elem.offsetParent;
    }
    window.scrollTo(x, y);
}

and then from your Android app (Java code), tell your WebView to load a URL:

webView.loadUrl("javascript:scrollToElement('" + elemId + "')");

There are some issues with this approach, such as the scroll will not be nicely animated, but the general mechanism works.

The DOM window object does report the current scroll position of the WebView correctly (see window.pageXOffset, window.pageYOffset or window.scrollX, window.scrollY). If you just want to know the current scroll position of the WebView, write some JavaScript to call your Java code and pass along the X/Y offsets.

Share:
48,262
Steve Liddle
Author by

Steve Liddle

I love a good coding frenzy.

Updated on June 22, 2021

Comments

  • Steve Liddle
    Steve Liddle almost 3 years

    I'm trying to programmatically scroll a WebView to the location of a particular element in the DOM tree. But so far I haven't been able to get the WebView to respond to scroll requests. I've tried calling JavaScript that uses window.scrollTo(...), but the WebView doesn't respond. On the Java side, I've tried calling the WebView.flingScroll(...) method. WebView will respond to flingScroll, but what I need is a scrollTo(...) capability. Any ideas?

  • Roman Nurik
    Roman Nurik over 14 years
    That happens because when declaring a function in the global scope, it's actually being declared as a property on the global window object.
  • HXCaine
    HXCaine over 13 years
    It's nice of you to come back and add this :)
  • Datta Kunde
    Datta Kunde almost 12 years
    it is good solution. but i want to do some extra. I have one html file which contain the school lesson(with some tag), and one audio file which contain the recording of explanation of that lesson. I want to scroll my web view(which contain the html file) according to the audio file which is play in background. if i forward the audio file then my scroll also move on that position where the audio is currently play. will u have any suggestion on same.
  • Datta Kunde
    Datta Kunde almost 12 years
    @Steve: it work fine for me, but i want to scroll web view at top(i.e. where web view is start). i am using mScrollView.scrollTo(0.mScrollView.getScrollY()) but it wont work.
  • Datta Kunde
    Datta Kunde almost 12 years
    @SteveLiddle: It work fine for scroll view but not for webView. I want to apply it for webView. And one more think i want ur suggestion, i want to auto scroll web view to particular position at some interval of time. I am using findAll("tag") and findNext(true) for that. It work fine but it scroll till "tag" at the bottom of screen, i want to scroll it till "tag" at top of screen. Thanks.
  • Maarten
    Maarten over 10 years
    @SteveLiddle How do you get the position of the DOM element you wish to scroll to then? A Javascript interface?
  • Steve Liddle
    Steve Liddle over 10 years
    @Maarten, an element can report its position and you can get that by writing some JavaScript. I think anything you want to do with the DOM tree will need to happen in JavaScript, not Objective-C.