FLASHでブラウザのスクロールバーを最上部に戻す方法で、最初出来たと思いきや不完全だったのでメモ。
基本設定は以下の通り。
ステージサイズを500×1000くらいにしておく
インスタンス名:_mcのムービークリップをステージの下の方に配置。
まず最初のイマイチアプローチから
以下フレームアクション
//AS:フレームアクション
_mc.addEventListener(MouseEvent.CLICK , xClick);
function xClick (e):void {
var tf = new TextField();
addChild(tf);
tf.text = "リロードしてないよ";
navigateToURL(new URLRequest("#","_self"));
}
これだけで出来ました。
ジャンプ先を#にするとブラウザリロードせずにページの先頭にジャンプできました。
先頭にはリロードしてないよの文字が表示されます。
で、これでいいや、と思いきや・・・
winのSafari3ではブラウザリロードしてしまいテキストが表示されません。
WINのIE6,7、FF3はリロードされなかったんですがね。。。
(HTMLの解釈的にはSafariの方が正しいっぽいような気がしますが)
というわけで別のアプローチ。
jsでスクロールバーを制御する方法。
js自体のソースはこちらのブログを参考にしました。
※イージングでゆっくりページのトップに戻るような処理のjsです。
//JS:HTMLに埋め込むか、jsファイルとしてhtmlで読み込むか
function backToTop() {
var x1 = x2 = x3 = 0;
var y1 = y2 = y3 = 0;
if (document.documentElement) {
x1 = document.documentElement.scrollLeft || 0;
y1 = document.documentElement.scrollTop || 0;
}
if (document.body) {
x2 = document.body.scrollLeft || 0;
y2 = document.body.scrollTop || 0;
}
x3 = window.scrollX || 0;
y3 = window.scrollY || 0;
var x = Math.max(x1, Math.max(x2, x3));
var y = Math.max(y1, Math.max(y2, y3));
window.scrollTo(Math.floor(x / 2), Math.floor(y / 2));
if (x > 0 || y > 0) {
window.setTimeout("backToTop()", 25);
}
}
上記関数をhtmlに仕込んでおいて、Flash側には以下のように設定
//AS:フレームアクション
_mc.addEventListener(MouseEvent.CLICK , xClick);
// 呼びたいJSの関数名
var callJasFunction:String = "backToTop";
// JavaScriptの実行
function xClick (e):void {
var tf = new TextField();
addChild(tf);
tf.text = "リロードしてないよ";
ExternalInterface.call(callJasFunction)
}
これでOKなのですが、Htmlにjs仕込むのが面倒くさい。
できることならFLASHだけで完結できないか、と。
と思ったら、こんな書き方でもFLASH上でJSを実行できるらしい。
//AS:フレームアクション
_mc.addEventListener(MouseEvent.CLICK , xClick);
// 呼びたいJSの関数
var callJasFunction:String = "function backToTop() {var x1 = x2 = x3 = 0;var y1 = y2 = y3 = 0;if (document.documentElement) {x1 = document.documentElement.scrollLeft || 0;y1 = document.documentElement.scrollTop || 0;}if (document.body) {x2 = document.body.scrollLeft || 0;y2 = document.body.scrollTop || 0;}x3 = window.scrollX || 0;y3 = window.scrollY || 0;var x = Math.max(x1, Math.max(x2, x3));var y = Math.max(y1, Math.max(y2, y3));window.scrollTo(Math.floor(x / 2), Math.floor(y / 2));if (x > 0 || y > 0) {window.setTimeout('backToTop()', 25);}}";
// JavaScriptの実行
function xClick (e):void {
var tf = new TextField();
addChild(tf);
tf.text = "リロードしてないよ";
ExternalInterface.call(callJasFunction)
}
ようは、関数名のところに関数全部書いちゃってもOKみたい。
これなら、Html変更しなくていいから楽チンだ!
と思いきや、これだと不具合ありました・・・
jsの再帰処理的な部分が実行されず、最初の一回しか実行されてないっぽい。
↓ここの部分
//上述したJSの一部を抜粋
if (x > 0 || y > 0) {
window.setTimeout("backToTop()", 25);
}
でも最初の一回は実行されるので、一回でトップに戻るようなjsなら問題なくページの頭だしは可能。
jsをこれだけにすれば、とりあえずイージングなしの頭だしは可能でした。
//AS:フレームアクション
_mc.addEventListener(MouseEvent.CLICK , xClick);
// 呼びたいJSの関数
var callJasFunction:String = "function backToTop() {window.scrollTo(0, 0);}";
// JavaScriptの実行
function xClick (e):void {
var tf = new TextField();
addChild(tf);
tf.text = "リロードしてないよ";
ExternalInterface.call(callJasFunction)
}
※2009/5/12追記
以下の書き方で再帰処理も可能でした。
document.insertScriptなんてものを使えばよいのだね。
JSよくわかんね。
_mc.addEventListener(MouseEvent.CLICK , xClick);
// 呼びたいJSの関数名
var callJasFunction:String = "document.insertScript = function(){ backToTop = function() {var x1 = x2 = x3 = 0;var y1 = y2 = y3 = 0;if (document.documentElement) {x1 = document.documentElement.scrollLeft || 0;y1 = document.documentElement.scrollTop || 0;}if (document.body) {x2 = document.body.scrollLeft || 0;y2 = document.body.scrollTop || 0;}x3 = window.scrollX || 0;y3 = window.scrollY || 0;var x = Math.max(x1, Math.max(x2, x3));var y = Math.max(y1, Math.max(y2, y3));window.scrollTo(Math.floor(x / 2), Math.floor(y / 2));if (x > 0 || y > 0) {window.setTimeout('backToTop()', 25);}}}";
var method = " backToTop";
//上記関数を読み込み(この段階では、関数backToTopは実行されないみたい)
ExternalInterface.call(callJasFunction)
// JavaScriptの実行
function xClick (e):void {
//ここで初めて実行されるみたい。
ExternalInterface.call("backToTop")
}