Kindle paperwhite ブラウザ(体験版)の HTML を画面右をクリックすることでスクロールさせる (javascript で scroll)

右端のクリックは良いのだけれど、左端では微妙に戻れない。研究の余地あり。
というか、スクロールの指定ぐらい実装しろよ! > amazon !!
ページ内のリンクもOK!!
TreeWalker オブジェクトも使えるので、そちらに切り替えようか?
それにしてもこの中途半端な Javascript 頭にくる!
イライラ。

<!DOCTYPE html>
<html lang="ja">
<meta charset="UTF-8">
<title>Kindle</title>

<style>
body {
  margin: 0 1em;
  font-size: 230%;
  width: 700px;
  line-height:300%;
}
div {
  border:4px black doubel;
}

</style>

<body>

<div id="A">
  <h1>A</h1>
  <ol>
    <li>1abc
    <li>2abc
    <li>3abc
    <li>4<a href="#B">B</a>
    <li>5abc
    <li>6abc
    <li>7abc
    <li>8abc
    <li>9abc
    <li>10abc
    <li>11abc
    <li>12abc
    <li>13abc
    <li>14abc
  </ol>
</div>


<div id="B">
  <h1>B</h1>
  <ol>
    <li>BBBBBBBBBB0<span id="Z">ZZZZZZZZZ</span>
    <li><a href="#C">C</a>
    <li>BBBBBBBBBB1
    <li>BBBBBBBBBB2
    <li>BBBBBBBBBB3
    <li>BBBBBBBBBB4
    <li>BBBBBBBBBB5
    <li>BBBBBBBBBB6
    <li>BBBBBBBBBB7
    <li>BBBBBBBBBB8
  </ol>
</div>


<div id="C">
  <h1>C</h1>
  <table border="1" class="fix">
    <tr>
      <td><a href="#A">A</a>
      <td><a href="#B">B</a>
      <td><a href="#C">C</a>
      <td><a href="#D">D</a>
    <tr>
      <td colspan="8">f
  </table>
</div>


<div id="D">
  <h1>D</h1>
  <a href="#A">A</a>
</div>
<script>

(function () {

  var SCROLL_AREA_WIDTH = 80;
  var MARGIN_BOTTOM     = 20;
  var DOCUMENT_ROOT     = document.body;

  //_______


  function basicFormat (e) {
    switch (e.nodeName) {
    case 'LI' :     return 'list-item';
    case 'TABLE':   return 'table';
    case 'CAPTION': return 'table-caption';
    case 'THEAD':   return 'table-header-group';
    case 'TFOOT':   return 'table-footer-group';
    case 'TBODY':   return 'table-row-group';
    case 'TR':      return 'table-row';
    case 'TD': case 'TH' : return 'table-cell';

    case 'RUBY':    return 'ruby';
    case 'RB':      return 'ruby-base';
    case 'RT':      return 'ruby-text';
    case 'RBC':     return 'ruby-base-container';
    case 'RTC':     return 'ruby-text-container';
    
    case 'SCRIPT' : return 'none';
    
    case 'A' : case 'ABBR' : case 'ACRONYM' : case 'B' : case 'BDO' :
    case 'BIG' : case 'BR' : case 'BUTTON' : case 'CITE' : case 'CODE' :
    case 'DFN' : case 'EM' : case 'I' : case 'IMG' : case 'INPUT' :
    case 'KBD' : case 'LABEL' : case 'MAP' : case 'OBJECT' : case 'Q' :
    case 'SAMP' : case 'SELECT' : case 'SMALL' : case 'SPAN' : case 'STRONG' :
    case 'SUB' : case 'SUP' : case 'TEXTAREA' : case 'TIME' : case 'TT' :
    case 'VAR' : return 'inline';
     
    default :
      return 'block';
    }
  }


  //前方の要素を非表示にする(兄要素の子孫は無視&直系の祖先も無視)
  function hide_previous (e) {
    var n;
    while (e) {
      if (n = e.previousElementSibling) {
        n.style.display = 'none';
        e = n;
      } else {
        e = e.parentNode;
        if (DOCUMENT_ROOT === e)
          break;
      }
    }
  }
  
  
  //後方の要素を非表示にする(弟要素の子孫は無視&直系の祖先も無視)
  function hide_next (e) {
    var n;
    while (e) {
      if (n = e.nextElementSibling) {
        n.style.display = 'none';
        e = n;
      } else {
        e = e.parentNode;
        if (DOCUMENT_ROOT === e)
          break
      }
    }
  }


  //直系の祖先を表示する
  function display_directAncestor (e) {
    while (e) {
      e.style.display = basicFormat (e);
      e = e.parentNode;
      if (DOCUMENT_ROOT === e) break; //body まで遡って見えていなとは?
    }
  }



  //子要素も探る
  function getNextElement (e) {
    var n;
    if (n = e.firstElementChild ) return n;
    do {
      if (DOCUMENT_ROOT === e) break;
      if (n = e.nextElementSibling) return n;
    } while (e = e.parentNode);
    return null;
  }


   //子要素も探る
   function getPrevElement (e) {
    var n, m, p;
    if (n = e.previousElementSibling) {
      while (m = n.lastElementChild) {
        n = m;
      }
      return n;
    }
    p = e.parentNode;
    return DOCUMENT_ROOT === p ? null: p;
  }

 



  

  function getHeight (e) {
    e.style.visibility = 'hidden';
    e.style.display = 'block';
    var rect = e.getBoundingClientRect ();
    var h = rect.top;
    e.style.display = 'none';
    e.style.visibility = 'visible';
    return h;
  }


  
  
  //__________________________________________________
  
  function Scroller () {
    this.root   = document;
    this.height = document.documentElement.clientHeight - MARGIN_BOTTOM;
    this.width  = document.documentElement.clientWidth - SCROLL_AREA_WIDTH
    this.first  = document.body.firstElementChild;//表示されている最初の要素
    this.last   = null;//表示されている最後の要素
    
    document.addEventListener ('click', this, false);
    window.addEventListener ('hashchange', this, false);//location.hashを監視

    this.disp (this.first);
  }
  
  
  function scrollUp () {
    this.disp (this.first, true);
  }
  
  
  function scrollDown () {
    this.disp (this.last);
  }
  
  
  
  
  //要素を基準に下へ向かって高さがエリア内なら表示し、エリア外は非表示
  function disp (e, direction) {
    if ('undefined' === typeof e)
      return;
    if ('undefined' === typeof direction)
      direction = false;
    
    var height = this.height, h, b, r;


    //下から表示
    if (direction) {
      e = getPrevElement (e);
      hide_next (e);
      display_directAncestor (e);
      this.last = b = e;

      while (e) {
        e.style.visibility = 'hidden';
        e.style.display = basicFormat (e);
        r = b.getBoundingClientRect ();
        h = r.top;
        if (height < h) {
          e.style.display = 'none';
          e.style.visibility = 'visible';
          
          hide_previous (e);
          this.first = e;
          return;
        }
        e.style.display = basicFormat (e);
        e.style.visibility = 'visible';
        
        e = getPrevElement (e);

      }
      this.first = document.body.firstElementChild;
    }

    //上の要素から表示
    else {

      hide_previous (e);
      display_directAncestor (e);
      this.first = e;

      while (e) {
        if (getHeight (e) < height) {
          e.style.display = basicFormat (e);
        }
        else {
          this.last = e;
          hide_next (e);
          break;
        }
        e = getNextElement (e)
      }//子要素も含めて探す

    }
  }

    
  //イベント処理
  function handleEvent (event) {
    var x = event.pageX;
    var wd = this.width;
    
    switch (event.type) {

    case 'click' : //クリック処理
      if (x < SCROLL_AREA_WIDTH)
        this.scrollUp ();
      else
        if (x > wd) this.scrollDown ();
      break;

    
    case 'hashchange' ://ページ内リンクなら
      var
        hash = location.hash,
        target;
      
      if (0 === hash.indexOf ('#'))
        if (target = document.querySelector (hash))
          this.disp (target);

      break;
    }
  }

  //__

  Scroller.prototype.disp        = disp;
  Scroller.prototype.scrollUp    = scrollUp;
  Scroller.prototype.scrollDown  = scrollDown;
  Scroller.prototype.handleEvent = handleEvent;
  
  //__
  
  this.Scroller = Scroller;

}) ();

//s. disp ();
/*
var treeWalker = document.createTreeWalker(
  document.body,
  NodeFilter.SHOW_ELEMENT,
  { acceptNode: function(node) { return NodeFilter.FILTER_ACCEPT; } },
  false
);
*/

//var isKindle = /^Mozilla.+Linux.+AppleWebKit.+KHTML.+Safari.+/;
//if (isKindle.test(window.navigator.userAgent));
  new Scroller ();

</script>
</body>
</html>