htmlブロックのヘッダとその応用例

注意

この技法は失敗するとページの復旧が難しくなります。下記のページに紹介されている不具合の復旧ができない場合はおすすめしません。

不具合が起きてしまった!そんな時

基本

htmlブロックを固定ヘッダにする事ができます。まず下記のCSSを適用してください。

[[module css]]
.overlay iframe{
position:fixed;
left:0px;
top:0px;
z-index:20;
}

[[/module]]

Code:1

次にhtmlブロックを下記のように設置してください。

[[div class="overlay"]]
[[html]]
hogehoge
[[/html]]
[[/div]]

Code:2

これでhtmlブロックを固定ヘッダにする事ができます。htmlブロック内ではjavascriptを使った多彩なギミックを入れる事ができます。

例えばhtmlブロックに下記のコードを入れると、固定ヘッダ内に「Connect to <現在のpagename>」という風に現在のpagenameとリアルタイムで通信しているかの様な演出をつける事ができます。

iframe通信による応用

iframe通信を使う事によって更なるギミックを作る事ができます。まず下記のボタンを押してみてください。

なんか動作が止まったら、黒い背景をクリックしてください。にょろーんと出てきたのが引っ込みます。

仕組みを説明します。このギミックには3つのiframeが使われています。まずは固定ヘッダです。固定ヘッダの中身は下記の様になります。

ここで少しjavascriptをやった事がある人なら、上のソースコードを読むと違和感を感じるかも知れません。それは、runnning()及びsearch()という関数はソースコード中に呼び出しの記述があるにも関わらずclash()を呼び出すコードがどこにもない事です。

この関数clash()は、正に先ほど押した貰ったボタンにおいて起動させられます。しかし、このボタンが置かれているiframe(htmlブロック)と固定ヘッダは別のiframeです。つまり、ボタンが置かれているiframeから固定ヘッダにアクセスが行われている訳です。

ボタンが置かれているhtmlブロック内のソースは下記になります。

[[html]]
<script type="text/javascript">
<script type="text/javascript">
var end = false;
function findyou(){
if(end)return;
//↓このhtmlブロックが埋め込まれているページに存在する全iframeを取得
var pare = window.parent.window.frames;
//↓iframe検索、クロスドメイン違反によるプログラム停止を避ける為、必ず
//try{}catch(e){}に入れる事
for(var i = 0;i < pare.length;i++){
try{
//そのiframeclashという関数があった場合
if(typeof(pare[i].clash) == "function"){
//そのifarmeにあるclash関数を起動
pare[i].clash();
}
 
}catch(e){
 
}
}
end = true;
}
</script>
<button onclick="findyou();">Authenticate Security Clearance</button>
[[/html]]

Code:5


ここは非常に重要な事です。つまり、自分のページ、そのiframe内のページではなく、別のページにある関数を起動するという技法が使われているからです1

細かい事は省きますが、以下の条件をどちらか満たす場合、異なるiframeに格納されたページにある関数を起動させる事ができます。

  • 同じサイト内に作られたhtmlブロックである事
  • 同じサイト内に作られたローカルコード(codeブロックにより生成されたURLのページ)である事

また条件付きで下記のページを収めたiframe同士もお互いの関数を起動させる事ができます。

  • 同じページ内にアップロードされたhtmlファイル同士である事

正確な原理としてはクロスドメインポリシーでググってください。

ここでは固定ヘッダに用いられているiframeもボタンを格納しているiframeも同じ椎茸天然製造に作られている為、クロスドメインポリシーに反せず、お互いの関数にアクセスする事ができるのです。

また、先頬のボタンを押したギミックでは、ユーザがWikidotアカウントにサインインしている場合はWikidotアカウント名が表示されます。これはサインインユーザと非サインユーザに対する文章表示切替で紹介した方法の応用ですが、今回はもっとシンプルに作ってあります。

まず下記のソースコードをtype="html"のcodeブロックに格納します。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Script-Type" content="text/javascript"/>
<meta http-equiv="Content-Style-Type" content="text/css"/>
<meta http-equiv="content-language" content="ja,jp-ja"/>
<meta charset="UTF-8"/>
<title>userNameを送る</title>
<script type="text/javascript" src="http://ja.scp-wiki.net/scpmetatitlesearch/code/4"></script>
<script type="text/javascript">
//ユーザネームを取得
var userName = decodeURI(window.location.href.split("#")[1]);
function getUserName(){
return decodeURIExtension(userName);
}
</script>
</head>
<body>
</body>
</html>

Code:6


そして上記のコードブロックで生成されたローカルコードを下記のコードで呼び出します。

[[module ListUsers users="."]]
[[embed]]
<iframe src="コードブロックが埋め込まれたページのURL/code/1#%%title%%" name="userName" style="display:none;"></iframe>
[[/embed]]
[[/module]]

Code:7


このアカウント名を出力するgetUserName()を起動するコードは下記です。

var useN = "";
//下のtry{}catch(e){}の部分はかなり重要
try{
//ユーザがサインイン状態の時
var check = window.parent.window.userName;
useN = check.getUserName();
}catch(e){

}

Code:8

Code:5で見せた固定ヘッダにアクセスするコードでは一回、自分自身を埋め込んだページに存在する全iframeを取得し、その全件に対して目的のiframeであるかの検査をおこなっていました。しかし、Code8では直接getUserNameが存在するiframeにアクセスして関数を起動しています。

これは下記のように

[[embed]]
<iframe src="コードブロックが埋め込まれたページのURL/code/1#%%title%%" name="userName" style="display:none;"></iframe>
[[/embed]]

Code:9

[[embel]]タグの中にiframeを設置する場合は、そのiframeにname属性を付ける事ができる為、ここでつけた名前を使って直接ユーザネームを呼び出すiframeを獲得しているのです。

ただし、Code7のように[[module ListUsers users="."]]に挟まれたiframeはWikidotにサインインしていないユーザがページを閲覧した時は消えてしまいます。存在しないiframeにアクセスしようとするとエラーになってしまいプログラムが停止してしまいます。その為、Wikidotにサインインしていないユーザに配慮する為、Code8ではアカウントネームを取得する処理をtry{}catch(e){}に入れ、存在しないiframeにアクセスしようとした時でもプログラムの動作が止まらない様にしているのです。

更に応用

こんなものも作れます。

繰り返しますが今回紹介する技法はミスってしまった場合復旧が難しくなる可能性があります。試す際は充分に気を付けるか、一番良いのは下のページを穴が空く程見る事です。

不具合が起きてしまった!そんな時

それでは良き活動を。

特に指定がない限り、このサイトのコンテンツには次のライセンスが適用されます: Creative Commons Attribution-ShareAlike 3.0 License