あしたから本気出す
いろいろ工作して情報発信してみる。自作キーボードとか。
開発ブログ
自作キーボード「TypingTrigger-SDZERO」
自作スマートフォン緊急充電器
プログラマブルな自動化キーボード実装編
プログラマブルな自動化キーボード(プロトタイプ編)を作ってみる-後編
開発ブログをもっと見る
ブログなど
ブログはこちら
ダウンロード
JW_WIN外部変形Kiefer
JW_WIN外部変形FastMeasure
お知らせ
2010/10/1 ブログを新しくした
2009/9/4 twitter始めた
2009/7/14 サイトのタイトル変更した

管理者プロフィール (-)
suda 81年神奈川県生まれ
職業:GRAFZ.NETという屋号でプログラム制作してます。
一言:実用性を形にする。工作の日々。
コンタクトは以下までお願いします。感想、応援、苦情とか
RSS
ブログをRSS配信してます。


© GRAFZ.NET 2008-2010
9月16日
検索に引っかかるフルフラッシュサイトの作り方


フルフラッシュとHTMLテキストを融合させる技術を紹介します。フルフラッシュなのに検索にザクザクとインデックス化される、そんなページのデザイン手法です。SEOを犠牲にすることなく、ページ全体を自由に使ったインパクトのある表現を目指します。

デモページはこちら

やることは単純です。フラッシュを配置したレイヤーを全画面ぴったりの大きさにフィットさせればよいのです。ただ、各ブラウザに対応するための振り分けが必要で、ブラウザ独特のクセのようなものがあります。レイヤーの大きさを変更するところは特に重点的に見ていきましょう。 大部分はjavascriptでの記述になりますが、まずはHTMLのソースから見ていきましょう。


<script src="./htmlFlash.js" type="text/javascript"></script>
javascriptを外部ファイルとしてHTMLに読み込みます(スクリプトの中身は後述)。

1:
2:
3:
4:
5:
<script type='text/javascript'>
<!--
window.onresize = myOnResize;
-->
</script>
ウィンドウの大きさがユーザーによって変更された場合に関数myOnResizeを実行させ、flashを配置するレイヤーを画面ぴったりの大きさに変形させるなどします。この部分は外部ファイルのjavascriptに記述しても構わないのですが、HTMLに含めた方がプログラムの大きな流れがひと目で分かります。このコードをHTMLのヘッダに追加します。

1:
2:
3:
4:
<body onload='myOnLoad()'>
<div id='idFlashLayer' style="position:absolute; top:0;left:0;">
<SCRIPT type="text/javascript">putFlash();</SCRIPT>
</div>
1行目:ページが読み込まれるタイミングで関数myOnLoadを実行。ブラウザの判定などをします。
2行目:フラッシュを貼り付けるためのレイヤーを作成。レイヤーが全画面になるように、positionをabsoluteに、位置を画面左上にします。IDの命名は任意で、ここではidFlashLayerとします。
3行目:flashを貼り付けます。関数putFlashはflashを配置するための処理をまとめてあり、これも外部ファイルにまとめてあります。

以下が外部ファイルとして読み込んでいるjavascriptの全ソースコードです。

1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:

78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
var nParamInterval = 10;
var strIdFlashLayer = 'idFlashLayer';

var nIdInterval0 = 0;
var nIdInterval1 = 0;
var strBrowser = '';

function myOnLoad(){
  strBrowser = checkBrowser();
  myOnResize();
}

function myOnResize() {
  var objLayer = document.getElementById(strIdFlashLayer);
  objLayer.style.width = document.documentElement.clientWidth + 'px';
  objLayer.style.height = document.documentElement.clientHeight + 'px';
  if(!nIdInterval0)nInterval0 = setInterval('myIntervalFunc0()',nParamInterval);
}

function checkBrowser(){
  var strAgent = navigator.userAgent;
  if(strAgent.indexOf("Opera") != -1)return 'opera';
  if(strAgent.indexOf("Chrome") != -1)return 'chrome';
  if(strAgent.indexOf("MSIE") != -1)return 'ie';
  if(strAgent.indexOf("Firefox") != -1)return 'firefox';
  if(strAgent.indexOf("Netscape") != -1)return 'netscape';
  if(strAgent.indexOf("Safari") != -1)return 'safari';
}

function myIntervalFunc0(){
  clearInterval(nIdInterval0);
  nIdInterval0 = false;
  var nScrollWidth = parseInt(document.documentElement.scrollWidth);
  var nScrollHeight = parseInt(document.documentElement.scrollHeight);
  if(strBrowser == 'firefox'){
    resizeFlash(nScrollWidth,nScrollHeight);
  }else if(strBrowser == 'safari' || strBrowser == 'chrome'){
    nScrollWidth = document.body.scrollWidth;
    nScrollHeight = document.body.scrollHeight;
    var nWidthNew,nHeightNew;
    var nClientWidth = document.documentElement.clientWidth;
    var nClientHeight = document.documentElement.clientHeight;
    if(nClientWidth < nScrollWidth)nWidthNew = nScrollWidth;
    else nWidthNew = nClientWidth;
    if(nClientHeight < nScrollHeight)nHeightNew = nScrollHeight;
    else nHeightNew = nClientHeight;
    resizeFlash(nWidthNew,nHeightNew);
  }else{//ie and else
    resizeFlash(nScrollWidth - 5,nScrollHeight - 5);
    if(!nIdInterval1)nInterval1 = setInterval('myIntervalFunc1()',nParamInterval);
  }
}

function myIntervalFunc1(){
  clearInterval(nIdInterval1);
  nIdInterval1 = false;
  var nScrollWidth = document.documentElement.scrollWidth;
  var nScrollHeight = document.documentElement.scrollHeight;
  resizeFlash(nScrollWidth,nScrollHeight);
}

function resizeFlash(nWidth,nHeight){
  var objLayer = document.getElementById(strIdFlashLayer);
  objLayer.style.width = nWidth + 'px';
  objLayer.style.height = nHeight + 'px';
}

function putFlash(){
  var widthSwf = "100%";
  var heightSwf = "100%";
  var filenameSwf = './testFlash.swf';
  var nameEmbed = 'testFlash';
  var strIdFlash = 'flash';
  var nBgColor = '#ffffff';
  var strObject = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" ';
  strObject += 'codebase="http://fpdownload.macromedia.com/pub/shockwave/
      cabs/flash/swflash.cab#version=7,0,0,0" ';
  strObject += 'width="' + widthSwf + '" ';
  strObject += 'height="' + heightSwf + '" ';
  strObject += 'id="' + strIdFlash + '" ';
  strObject += 'name="' + nameEmbed + '" ';
  strObject += 'align="middle">';
  strObject += '<param name="allowScriptAccess" value="sameDomain" />';
  strObject += '<param name="movie" value="' + filenameSwf + '" />';
  strObject += '<param name="quality" value="high" />';
  strObject += '<param name="wmode" value="transparent" />';
  strObject += '<param name="scale" value="noscale" />';
  strObject += '<param name="bgcolor" value="' + nBgColor + '" />';
  strObject += '<embed src="' + filenameSwf + '" ';
  strObject += 'quality="high" bgcolor="' + nBgColor + '" ';
  strObject += 'width="' + widthSwf + '" ';
  strObject += 'height="' + heightSwf + '" ';
  strObject += 'name="' + nameEmbed + '" ';
  strObject += 'wmode="transparent" ';
  strObject += 'scale="noscale" ';
  strObject += 'id="' + strIdFlash + '" ';
  strObject += 'align="middle" ';
  strObject += 'allowScriptAccess="sameDomain" ';
  strObject += 'type="application/x-shockwave-flash" ';
  strObject += 'pluginspage="http://www.macromedia.com/go/getflashplayer" ';
  strObject += '/></object>';
  document.write(strObject);
}
1行目:ウィンドウの大きさが変更されても、常に全画面にflashが表示されるようにするには、flashが配置されているレイヤーを全画面に変形させる必要があります。ある程度の時間差(setInterval使用)をつけて多段階で変形させる必要があります。理由は「そうすると出来るから」としか言えないんです。理屈では理解できない奇妙な仕様、つまりブラウザの癖があります。 nParamInterval はsetIntervalを呼ぶときのパラメータ(単位はミリ秒)で、17行目・50行目で使用します。
2行目:HTMLで指定しておいたレイヤーのID。
4・5行目:時間差の処理(インターバル)の設定・解除に必要な変数。
6行目:ブラウザの種類を格納するための変数。以上5つの変数は、ファイルのどこからでもアクセスできるグローバル変数にしてあります。
8-11行目:HTMLが読み込まれたときに実行されます。ブラウザを判定し、レイヤーを変形させます。各関数の記述は後述。
13行目:レイヤーを変形させる関数。myOnLoadから呼んでいる他に、ウィンドウサイズが変更される際にも直接呼ばれます。
14行目:IDを指定してflashを配置したレイヤーの参照をobjLayerに格納して、
15-16行目:幅と高さをウィンドウのクライアント領域の大きさに変更します。
17行目:実はこれで完了ではなくて、画面に収まっていないスクロール領域がある場合の処理が必要なのです。15-16行目の処理が完了するのを待つ必要があるため、setIntervalで時間差をつけます。nParamInterval(ミリ秒)経過したあとにmyIntervalFunc0(後述)を呼びます。
20-28行目:userAgentを解析してブラウザの種類を判定します。ここでは各ブラウザのバージョン等は考慮していません。厳密に場合分けする必要がある場合はこの部分を変更してください。
30行目:レイヤーがクライアント領域の大きさに変形する処理が完了したタイミングで実行されます。17行目で指定したsetIntervalによって呼び出されます。
31・32行目:clearIntervalしないと繰り返し呼び出されてしまいます。解除します。
33・34行目:クライアント領域に納まりきらないスクロール領域がある場合、その大きさを格納します。
35行目:Firefoxの場合、
36行目:どんな場合もスクロール領域に変形すればOK。
37行目:Safari、Chromeの場合は、
38・39行目:スクロール領域の取得にbodyを使用して、
40行目:
41・42行目:クライアント領域と
43-46行目:比較し、大きいほうを採用して
47行目:レイヤーを変形させます。
48行目:IE、Operaの場合はちょっとややこしく、
49行目:ひとまず適当な大きさに変形した後で
50行目:さらに時間差で処理してやらねばなりません(なぜと聞かないで下さい。僕にも分かりません)。その処理は、
54行目:ここから60行目まで。
55・56行目:まずはclearInterval(31行目と同様)。
57・58行目:スクロール領域を取得して
59行目:レイヤーを変形します。
62行目:そしてこれがレイヤー変形の関数。
63行目:
64・65行目:数値に単位をつけるのをお忘れなく。
68-103行目:ここからはflashを配置するための関数。大きさは縦横共に100%、ファイル名は71行目で指定しています。必要に応じて他のパラメータは変更させてください。

いかがでしたか。setIntervalを使用して多段階でサイズを変更せねばならないのは、ちょっと独特ですね。

皆さまに読んでいただけるからこそ今日も記事が書けます。
ご参考になれば幸いです。m(_ _)m



ダウンロード
サンプルファイル一式はこちら