Firefoxのmarquee実装
Shibuya.esの後のバカ話をふと思い出したので見てみたら、こんな感じでメソッドが付いてた。
$('foo').init(); $('foo').start(); $('foo').stop(); $('foo')._doMove(aSkipSettingNewPosition);
メソッド叩いたら、普通に止まったり動いたりしたので、Firebugでcopy($('foo').init.toSource())とかしてみた。
こんな感じ。
function _doMove(aSkipSettingNewPosition) { this.stop(); if (this.startNewDirection) { this.startNewDirection = false; if (this.directionField == "up" || this.directionField == "down") { var height = this.getAttribute("height") != "0" && this.getAttribute("height") || document.defaultView.getComputedStyle(this, "").height != "0px" && document.defaultView.getComputedStyle(this, "").height || "200px"; if (/%/.test(height)) { height = parseInt("0" + height, 10); height = height / 100 * this.outerDiv.offsetHeight; } this.outerDiv.style.height = height; this.innerDiv.style.padding = height + " 0"; this.innerDiv.style.whiteSpace = ""; } else { this.outerDiv.style.height = ""; this.innerDiv.style.padding = "0px"; this.innerDiv.style.whiteSpace = "nowrap"; } switch (this.directionField) { case "up": this.dirsign = 1; this.startAt = this.behaviorField == "alternate" ? this.originalHeight : 0; this.stopAt = this.innerDiv.offsetHeight - parseInt(this.outerDiv.style.height) - (this.behaviorField == "alternate" ? this.originalHeight : 0); break; case "down": this.dirsign = -1; this.startAt = this.innerDiv.offsetHeight - parseInt(this.outerDiv.style.height) - (this.behaviorField == "alternate" ? this.originalHeight : 0); this.stopAt = this.behaviorField == "alternate" ? this.originalHeight : 0; break; case "right": this.dirsign = -1; this.stopAt = this.behaviorField != "alternate" ? this.innerDiv.offsetLeft - this.outerDiv.offsetWidth : this.innerDiv.offsetWidth; this.startAt = this.outerDiv.offsetWidth + (this.behaviorField != "alternate" ? this.innerDiv.offsetWidth + this.stopAt : 0); break; case "left": default: this.dirsign = 1; this.startAt = this.behaviorField != "alternate" ? this.innerDiv.offsetLeft - this.outerDiv.offsetWidth : this.innerDiv.offsetWidth; this.stopAt = this.outerDiv.offsetWidth + (this.behaviorField != "alternate" ? this.innerDiv.offsetWidth + this.startAt : 0); } if (!aSkipSettingNewPosition) { this.newPosition = this.startAt; } } this.newPosition = parseInt(this.newPosition) + this.dirsign * this.scrollAmount; if ( this.dirsign == 1 &&this.newPosition > this.stopAt || this.dirsign == -1 && this.newPosition < this.stopAt ) { if (this.behaviorField == "alternate") { this.startNewDirection = true; const swap = {left:"right", down:"up", up:"down", right:"left"}; this.directionField = swap[this.directionField]; } else { this.newPosition = this.startAt; } } if (!this.startNewDirection) { if (this.directionField == "up" || this.directionField == "down") { this.outerDiv.scrollTop = this.newPosition; } else { this.outerDiv.scrollLeft = this.newPosition; } } var myThis = this; var lambda = function myTimeOutFunction() { myThis.start(); }; this.runId = window.setTimeout(lambda, this.scrollDelay); } function init() { var height; if (this.hasAttribute("height")) { height = this.getAttribute("height"); this.outerDiv.style.height = height + "px"; } this.outerDiv.style.width = this.width; if (this.hasAttribute("id")) { window[this.getAttribute("id")] = this; } if (this.hasAttribute("bgcolor")) { this.outerDiv.style.backgroundColor = this.getAttribute("bgcolor"); } this.originalHeight = this.innerDiv.offsetHeight; this._doMove(false); } function start() { this._doMove(false); } function stop() { if (this.runId != 0) { clearTimeout(this.runId); } this.runId = 0; }
普通にJavaScriptで実装されてる。なんかキモいことやりたくなってきたけど、時間が無いのでとりあえずここまで。