Вопрос

I have a very long article page that I want to help mobile users scroll on. For very long lists in mobile apps there's usually a alphabetical index that can help users jump to various places in the list. How do I implement something like that for a webapp?

If it helps my stack is angularjs / jquery / phonegap.

Это было полезно?

Решение 2

iOS7 Style List Navigator

If you want something nice on the phone, I just wrote this iOS7 style list navigator. I think the way Apple solved the problem is very straightforward. So we steal it.

It's written considering that you won't probably scroll the body, because in the many designs I've seen for smartphones, scrolling a container allows you to have fixed headers and footers for Android < 4 without getting mad.

A word of warning: this code is really fresh and untested.

SEE DEMO AND CODE

CSS (extract)

#scrolling {
    padding-top: 44px;
    overflow: scroll;
    -webkit-overflow-scroll: touch;
    height: 100%;
}
.menu {
    position: fixed;
    right: 0;
    font-size: 12px;
    text-align: center;
    display: inline-block;
    z-index: 2;
    top: 58px;
}

.list .divider {
    position: -webkit-sticky; /* will stop the label when it reaches the header */
    top: 44px;
}

HTML (extract)

<div id="scrolling">
<ul class="menu">
    <li><a href="#a">A</a></li>
    <li><a href="#b">B</a></li>
    <li><a href="#c">C</a></li>
    <!-- etc -->
</ul>
<ul class="list">
   <li class="divider" id="a">A</li>
   <li><a href="#">Amelia Webster</a></li>
   <li><a href="#">Andrew WifKinson</a></li>
   <!-- etc -->

Javascript (zepto/jquery)

$(function() { 
  $(window).on("touchstart touchmove mouseover click", ".menu a", function(e) {
    e.preventDefault();
    clearInterval(t);
    var steps = 25;
    var padding =  68;
    var target = $( $(this).attr("href") ).next("li");
    if ( target.length > 0 ) {
        var scroller = $("#scrolling")[0];
        var step = parseInt((target[0].offsetTop - padding - scroller.scrollTop)/steps);
        var stepno = 0;
            setInterval( function() {
                if ( stepno++ <= steps  ) {
                    scroller.scrollTop += step;
                } else {
                    clearInterval(t)
                }
            }, 20);
    };
  });
});

It performs a basic check of link validity before attempting the scroll. You can change padding to your needs.

Also, you will notice that we are targeting the first element after the required target. This is because Safari seems to go nuts because of the sticky positioning.

This code uses jQuery/Zepto selectors for the sake of brevity and readability. But these libraries are not really needed to achieve the result. With just a little extra digitation you could easily go dependency-free.

http://codepen.io/frapporti/pen/GtaLD

Другие советы

Just use angular's built-in $anchorScroll service.

See the live example in angular's official docs. Here are the important pieces of code:

In your view template:

<div id="scrollArea" ng-controller="ScrollCtrl">
  <a ng-click="gotoBottom()">Go to bottom</a>
  <a id="bottom"></a> You're at the bottom!
</div>

In your controller:

function ScrollCtrl($scope, $location, $anchorScroll) {
  $scope.gotoBottom = function (){
    // set the location.hash to the id of
    // the element you wish to scroll to.
    $location.hash('bottom');

    // call $anchorScroll()
    $anchorScroll();
  };
}

You can use a toggleable sidebar like this one. Resize your browser to the width of the screen of a mobile phone to understand what I mean.

Then create a directive in angularjs to wrap jQuery's animate function to scroll to a specific part in the article. Like this:

angular.module('yourModule', [])
       .directive('scrollTo', function() {
          return {
           restrict : 'EA',
           link: function(scope , element, attr){
                   $('html, body').animate({
                      scrollTop: $( attr['href'] ).offset().top
                    }, 300);
                 }
          };
       });

where href will be an id of a specific section in the article. Then all you need to do is apply the directive to the links in the sidebar.

... 
<li><a href="#section-1" scroll-to>Jump to section 1</a></li>
...

Hope this helps.

This might be what you're looking for http://www.designkode.com/alphascroll-jquery-mobile/

Haven't used it myself, but seems pretty simple to get going with.

I think something like this could work for you: http://codepen.io/aecend/pen/AsnIE. This is just a basic prototype I put together to answer but I could expand on the concept if needed. Basically, it creates a translucent bar on the right side of the screen, finds each of the headings for articles (which would need to be adapted to suit your needs) and places clickable/tappable anchors to jump to individual articles. When you click one, the page scrolls to that article. I have a few ideas to make this actually usable, but here's the proof of concept.

CSS

#scrollhelper {
  position: fixed;
  top: 0;
  right: 0;
  height: 100%;
  width: 5%;
  background-color: rgba(0,0,0,0.2);
  overflow: hidden;
}

#scrollhelper .point {
  position: absolute;
  display: block;
  width: 100%;
  height: 10px;
  margin: 0 auto;
  background-color: rgba(0,0,255,0.5);
}

JavaScript

var articles;

function buildScrollHelp() {
    var bodyHeight = $("body").height();
    var viewHeight = window.innerHeight;

    $("#scrollhelper").html("");

    articles.each(function() {
        var top = $(this).offset().top;
        var element = document.createElement("a");
        element.className = "point";
        element.href = "#" + $(this).attr("id");
        element.style.top = ((top / bodyHeight) * viewHeight) + "px";
        $(element).on("click", function(e){
            e.preventDefault();
            $('html, body').animate({
                scrollTop: $($(this).attr("href")).offset().top
             }, 500);
        });

        $("#scrollhelper")[0].appendChild(element);
    });
}

$(document).ready(function() {

    articles = $("body").children("[id]");
    $("body").append("<div id=\"scrollhelper\"></div>");

    $(window).resize(function(){
        buildScrollHelp();
    });

    buildScrollHelp();

});
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top