やっぱり書いてしまったのか!>おれ

誰かが、きっと、どっかのライブラリーをもちだして、
コンパクトに書いてくると思ったので、自力で書いてみた。
作業時間90分。さっぱりだめだなぁ〜
右から左なら簡単そうなんだけど・・・と思ったりもしたけど
まぁ〜似たようなものか。
Hogeの中から、Timerをcallしていないのだが、あれは大丈夫なのか?
動かしたり、止めたりのイベントの取り付け!
あれはないだろう!とつっこまれるなぁ〜

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="ja">

<head>
  <meta http-equiv="Content-Script-Type" content="application/javascript">
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <title>TEST</title>

  <style type="text/css">
  #MLIST {
    width : 600px;
    height: 230px;
    border: 1px #800 solid;
    list-style : none;
    margin : 0;
    padding : 0;
    overflow : auto;
  }
  .part {
    width : 200px;
    height: 240px;
    margin : 0;
    padding : 0;
    float: left;
  }
  .part ol {
    list-style : none;
  }
  .photo {
    width  : 200px;
    height : 200px;
  }
  .photo img {
    width  : 200px;
    height : 200px;
  }
  .comment {
    width  : 200px;
    height : 40px;
    text-align: center;
    font-size: 12px;
    padding-top:10px;
  }
  </style>

</head>

<body>
  <ul id="MLIST" onMouseover="MLIST.stop()" onMouseout="MLIST.start(MLIST.move)">
    <li class="part">
      <ol>
        <li class="photo"><img src="./img/0.gif" alt="photo0" ></li>
        <li class="comment">せつめい1</li>
      </ol>
    </li>
  </ul>

<script type="text/javascript"><!--

function Locator (x) {
  this.left = x + 'px';
}

function Starter (callbackfn) {
  this.timerID = (function (o) {
    return setInterval(function () { return callbackfn.call(o); }, o.interval);
  })(this);
}

function Stopper () {
  clearInterval(this.timerID);
}

function Timer ( n ) {
  this.timerID = null;
  this.interval = n;
}

Timer.prototype.start = function (listener) {
  return Starter.call(this, listener);
};

Timer.prototype.stop = function () {
  return Stopper.call(this);
};

var Hoge = function ( ) {
  this.init.apply( this, arguments );
};

Hoge.prototype = new Timer;
Hoge.prototype.constructor = Hoge;

Hoge.prototype.init = function ( tid, step, interval ) {
  var e = document.getElementById( tid );
  if(! e) return;
  e.style.overflow = 'hidden';
  e.style.position = 'relative';
  this.e = e;
  this.s = step;
  this.interval = interval;
  this.reset();
};

Hoge.prototype.addPart = (function ( tag ) {
  return function ( ary ) {
    var cnt = 0, o, p, i;
    while( o = ary[ cnt++ ] ) {
      i = tag( 'img' ), i.src = o[0], i.alt = o[1];
      this.e.appendChild(
        tag( 'li', 'part',
          tag( 'ol', '',
            tag( 'li', 'photo', i),
            tag( 'li', 'comment', o[2] )
          )
        )
      );
    }
    this.reset();
  };
})(
    function ( tag, cs, c1, c2 ) {
      var d = document;
      var e = d.createElement( tag );
      cs && (e.className = cs);
      c1 && e.appendChild( 'string' == typeof c1 ? d.createTextNode( c1 ): c1 );
      c2 && e.appendChild( 'string' == typeof c2 ? d.createTextNode( c2 ): c2 );
      return e;
    }
  );

Hoge.prototype.reset = (function ( get ) {
  return function ( ) {
    this.min = this.max = this.e.offsetWidth;
    var cnt = 0, o;
    this.ch = get( this.e );
    
    while( o = this.ch[ cnt++ ] ) {
      o.style.position = 'absolute';
      Locator.call( o.style, this.min -= o.offsetWidth);
    }
  };
})(
    function ( e ) {
      var cnt = 0, ch = [ ], o;
      while( o = e.childNodes[ cnt++ ] ) o.nodeType == 1 && ch.push( o );
      return ch;
    }
  );

Hoge.prototype.move = function ( ) {
  var cnt = 0, o, x;
  while( o = this.ch[ cnt++ ] ) {
    if( (x = o.offsetLeft + this.s) >= this.max ) x = this.min;
    Locator.call( o.style, x);
  }
}

var ary = [
  [ './img/1.gif', '*', 'せつめい1' ],
  [ './img/2.gif', '*', 'せつめい2' ],
  [ './img/3.gif', '*', 'せつめい3' ],
  [ './img/4.gif', '*', 'せつめい4' ],
  [ './img/5.gif', '*', 'せつめい5' ],
  [ './img/6.gif', '*', 'せつめい6' ]
];  
var MLIST = new Hoge( 'MLIST', 4, 50 );
MLIST.addPart( ary );
MLIST.start( MLIST.move );

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