<!DOCTYPE html>
<html lang="ja">
<head>
<title></title>
<meta charset="utf-8">
<meta name="viewport" content="width=320">
<style>
ol {
list-style:none;
}
ol > li {
width : 50px;
height: 50px;
border:6px red solid;
padding:2px;
text-align:center;
}
p {
margin: 20em 0;
}
</style>
</head>
<body>
<h1>Test</h1>
<p>a<p>b<p>c<p>d<p>e<p>f<p>g<p>h<p>i<p>j<p>k<p>l
<ol>
<li>左上
<li>中央上
<li>右上
<li>右中央
<li>右下
<li>中央下
<li>左下
<li>左中央
<li>ど真ん中
<ol>
<script>
(function () {
var DOC = document;
var VIEW = DOC.defaultView;
function Singleton () {
var target_stock = [];
var option_stock = [];
return new function () {
this.contains =
(function () {
return Array.prototype.some.call (arguments, function (target) {
return (-1 < this.indexOf (target)); }, target_stock); });
this.add =
(function add (target, option) {
if (! this.contains (target)) {
target_stock.push (target);
option_stock.push (option);
}});
this.getOption =
(function (target) {
var index = target_stock.indexof (target);
return (-1 < index) ? option_stock[index]: null; });
this.getAllOptions =
(function () { return option_stock.slice (0); });
};
}
function Controller (obj) {
if (1 > arguments.length)
return null;
return new function () {
this.getAttribute =
(function (attr) { return (obj.hasOwnProperty (attr)) ? obj[attr]: undefined; });
this.setAttribute =
(function (attr, val) {
if (obj.hasOwnProperty (attr))
obj[attr] = val; });
this.method =
(function (name) {
if ('function' === typeof obj[name])
return obj[name].apply (obj, Array.prototype.slice.call (arguments, 1)); });
};
}
function Locator (x, y) {
this.top = y + 'px';
this.left = x + 'px';
}
function Elevator (target, parm, cbFunc, cbObject) {
this.target = target;
this.accell = parm.accell;
this.interval = parm.interval;
this.cuddleHeight = parm.cuddleHeight;
this.cuddleWidth = parm.cuddleWidth;
this.offsetX = parm.offsetY;
this.offsetY = parm.offsetX;
this.timerId = null;
this.cbFunc = cbFunc;
this.cbObject = cbObject;
}
function Elevator_start () {
if (! this.timerId)
this.timerId = setInterval (function (that) { Elevator_onTimer.call (that) }, this.interval, this);
};
function Elevator_stop () {
if (this.timerId) {
clearInterval (this.timerId);
this.timerId = null;
}
};
function Elevator_onTimer () {
var e = this.target;
var s = e.style;
var a = this.accell;
var py = window.pageYOffset - this.offsetY;
var px = window.pageXOffset - this.offsetX;
switch (this.cuddleHeight) {
case 1 : py += Math.floor (window.innerHeight / 2 - e.offsetHeight / 2); break;
case 2 : py += Math.floor (window.innerHeight - e.offsetHeight); break;
}
switch (this.cuddleWidth) {
case 1 : px += Math.floor (window.innerWidth / 2 - e.offsetWidth / 2); break;
case 2 : px += Math.floor (window.innerWidth - e.offsetWidth); break;
}
var diffX = px - e.offsetLeft;
var diffY = py - e.offsetTop;
if (0 === diffX)
if (0 === diffY)
Elevator_stop.call (this);
var x = e.offsetLeft + Math.floor (diffX / a + (0 < diffX));
var y = e.offsetTop + Math.floor (diffY / a + (0 < diffY));
Locator.call (s, x, y);
};
function Elevator_cuddleHeight (position) {
var ary_cuddle_height = ['top', 'middle', 'bottom'];
var type_no;
if (! position)
position = 'top';
type_no = ary_cuddle_height.indexOf (position.toLowerCase ());
if (0 > type_no)
throw new Error ('指定できない値');
return type_no;
}
function Elevator_cuddleWidth (position) {
var ary_cuddle_width = ['left', 'center', 'right'];
var type_no;
if (! position)
position = 'left';
type_no = ary_cuddle_width.indexOf (position.toLowerCase ());
if (0 > type_no)
throw new Error ('指定できない値');
return type_no;
}
Elevator.prototype.start = Elevator_start;
Elevator.prototype.stop = Elevator_stop;
var Manager = new function () {
var stocker = new Singleton;
var ary_cuddle_height = ['top', 'middle', 'bottom'];
var ary_cuddle_width = ['left', 'center', 'right'];
this.handleEvent =
(function (event) {
switch (event.type) {
case 'scroll' :
stocker.getAllOptions().forEach (function (obj) { obj.method ('start'); });
break;
case 'unload' :
document.removeEventListener ('scroll', this, false);
window.removeEventListener ('unload', this, false);
break;
}
});
this.create =
(function (target, parm, cbFunc, cbObject) {
if (1 > arguments.length)
return null;
if (stocker.contains (target))
return stocker.getOption (target);
var elevator = new Elevator (target, {
'accell' : parm.accell || 2,
'interval' : parm.interval || 50,
'cuddleHeight': Elevator_cuddleHeight (parm.cuddleHeight),
'cuddleWidth' : Elevator_cuddleWidth (parm.cuddleWidth),
'offsetY' : parm.offsetY || 0,
'offsetX' : parm.offsetX || 0
}, cbFunc, cbObject);
target.style.position = 'absolute';
elevator.start ();
var controller = Controller (elevator);
stocker.add (target, controller);
return controller;
});
document.addEventListener ('scroll', this, false);
window.addEventListener ('unload', this, false);
};
this.Elevator = Manager;
})();
var li = document.querySelectorAll ('li');
Elevator.create (li[0], {accell:4, interval: 10 });
Elevator.create (li[1], {accell:8, interval: 10, cuddleWidth: 'center' });
Elevator.create (li[2], {accell:12, interval: 10, cuddleWidth: 'right' });
Elevator.create (li[3], {accell:16, interval: 10, cuddleHeight: 'middle', cuddleWidth: 'right' });
Elevator.create (li[4], {accell:20, interval: 10, cuddleHeight: 'bottom', cuddleWidth: 'right' });
Elevator.create (li[5], {accell:24, interval: 10, cuddleHeight: 'bottom', cuddleWidth: 'center' });
Elevator.create (li[6], {accell:28, interval: 10, cuddleHeight: 'bottom'});
Elevator.create (li[7], {accell:32, interval: 10, cuddleHeight: 'middle'});
Elevator.create (li[8], {accell:36, interval: 10, cuddleHeight: 'middle', cuddleWidth: 'center' });
</script>