あ・つ・い・・・

5/30(金)辺りから、日本全国がうだるような暑さである。
関東、特に東京・千葉・横浜はまだ暑さの中に、寒気の一部が
残っており、天候が不安定だったのだが、今日になりそれも
何処へやら。

今日の、東京の最高気温が34℃とのこと。
暑さに身体が追い付いていないので、外を歩くのが危ないよう
な気温である。

今年は、エルニーニョの影響で冷夏との予報だが、果たして
如何に。

「hook(フック)」とは?

The <span> tag provides a way to add a hook to a part of a text or a part of a document.
これは、span要素の説明の一部を抜粋したものです。
翻訳すれば、
「<span>タグは、テキストまたは文書の一部にフックを追加する方法を提供する。」
とでもなるのだろうか。
そこで、このフックだが
辞書で調べてみても
 鉤、留め金、ホック(ボタン)、フック(ゴルフ)・・・等々
解決につながる訳が見つからない。

遂に奥の手、wikipediaを恐る恐る調べれば
フック(プログラミング)
が見つかった。

Wikipediaの説明は長くなるので、e-Wordsから引用する。

プログラミングの分野で、プログラム中の特定の場所に、
あとから別のプログラムが処理を追加できるような仕組み
を用意しておくことや、そのような仕組みを利用して追加
された処理のことをフックという。そのような機構を用い
て独自のコードを元のプログラムに割り込ませることを
「フックする」という。

つまり、「テキストの一部を<span>タグで囲み、
CSSなりJavaScriptから操作できるようにする」という
のが、翻訳で示した「フック」の意なのでしょう。

プログラムの世界では、一般的な用語なのかもしれないが
老SEにとっては、全く初めて聞いた単語。
英文の翻訳と言っても、こういう知識がないと翻訳する
のは難しいですね。

「オリジン」とは?

HTMLに関して、英文の文書を読んでいたところ
crossorigin
という<img>の属性に遭遇。
HTML5で新規に追加された属性とのことだが
全く、どういうものか理解できないので、調べてみた。

まずは、「オリジン」について。

オリジンとは、「RFC 6454 – The Web Origin Concept」(IPAによる日本語訳)
で定められた概念で、端的にいうとリソース自身のURLの「スキーム」「ホスト
ポート」の3つの組み合わせを「オリジン」と呼びます。
重要! まずは「オリジン」を理解しよう による)

これだけでは、分かり難いので
http://www.example.jp/index.html
を例にとれば、

スキーム http
ホスト www.example.jp
ポート 80(省略時のデフォルト値)

この3つを「オリジン」と云うのだそうだ。

クロスオリジンとは、
リソースのオリジンによって動作が制限される
ことで、次のようなものがあるとのこと。

XMLHttpRequest

XMLHttpRequestによるリソースへのリクエストでは、取得しようとしているリソースのオリジンが現在表示しているドキュメントのオリジンと同一の場合には、無条件にレスポンスの内容をJavaScriptからresponseTextなどを通じて取得できます。

 オリジンが一致しない場合には、リソースの提供側が明示的に許可している場合にしか、JavaScriptからレスポンスの内容にアクセスすることはできません。


Canvas

HTML5のCanvas要素を使用して表示された画像は、そのHTMLのオリジンと同一のオリジンに属するものであれば、表示されている内容にJavaScriptからgetImageDataメソッドなどを通じてアクセス可能です。

 オリジンが一致しない場合には、画像提供側で明示的に許可している場合にしかアクセスできません。


知りたかったのは、2番目のCanvas部分。
何となく理解した気分です。
詳細は、上記URLを参照してください。

Ajaxによるコンテンツの切替え–対策方法

コンテンツ(contentX.htmlと仮定)に直接アクセス
された場合、様々な対策法があるとは思うが、私は
次のようにすることにした。

  1. 直接アクセスされたかどうかを検知する。
  2. 直接アクセスされた場合、sessionStorageにcontentX.htmlを出力
  3. index.html(Ajaxを設定したページ)へリダイレクト
  4. sessionStorageを参照して、contentX.htmlをロード

1. の検知方法は、title 要素の存在有無で
判定している。ちょっと怪しい処理だが、自分には
問題がないので、これで良しとする。

この検知処理は全コンテンツに追加する必要がある。
外部ファイルとするので
<script src=”/my/directory/xxx.js></script>
のような1行をHTMLの末尾に追加するだけだが、量が多いので
中々大変な作業量になってしまう。
と言うことで、以前書いた
「ディレクトリにある全ソースの末尾に1行追加」
につながる訳で、これで一件落着。目出度し目出度し。

各コンテンツに追加したスクリプトは以下の通り。

// 直接このコンテンツをアクセスしたかのチェック
var x = document.getElementsByTagName("title");
if(x.length == 0){  // 直接アクセスした?
  // 直接アクセスした場合の処理
  var url = document.URL;      // このドキュメントのURL
  var arry = url.split("/");  // スラッシュで分割
  // リダイレクトするURLの生成
  var html = "/"+arry[arry.length - 3]+"/"+arry[arry.length - 2]+"/"+"index.html";
  if(sessionStorage){
    sessionStorage.setItem("AccessURL",arry[arry.length - 1]);
  }else{
    alert("セッションストレージが使用できません");
  }
  // index.htmlへリダイレクト
  location.href=html;
}

index.htmlのスクリプト。

$(document).ready(function(){

    init();
    
    // 左サイドメニューをクリック
    $("#leftcolumn a").click(function(){
      srcSet(this);
    });
    // a タグの"href"を読んで、取得した内容を #main に設定する
    $("#leftcolumn a").pjax("#main");

});

function init(){
  if(sessionStorage){
    // sessionStorageが設定されていれば、それを入力
    var html = sessionStorage["AccessURL"];
    if(!html){
      // 設定されていなければdefault.htmlを入力
      html = "default.html";
    }
  }else{
    alert("セッションストレージが使用できません");
  }
  $("#main").load(html);
  // アンカータグのデフォルト動作を抑止
  $("#leftcolumn a").click(function(event){
    event.preventDefault();
  });
  // 本文中のリンクをクリック(tryitbtnを除く)
  $("#main").on('click','a:not(.tryitbtn)',function(event){
    event.preventDefault();  // リンクの動作を抑止
    srcSet(this);
    var vhref = $(this).attr("href");
      // tile に設定する値を、左サイドメニューから取得
      var title = $("#leftcolumn a[href='"+vhref+"']").text();
      if(title != ""){
        $("title").text(title);
      }
    //}
  });
}
function srcSet(obj){
  document.title = $(obj).text();      // title を設定
  $("a[style]").removeAttr("style");  // Bold 設定を一旦削除
  var geturl = $(obj).attr("href");    // クリックされたメニューの href 属性値
  // クリックされたメニューを Bold に
  $("#leftcolumn a[href='"+geturl+"']").css("font-weight","bold");
  // HTML 本文のロード
  $.pjax({
    "url": geturl,
    "container": "#main"
  });
  $("html").scrollTop(0);  // 画面を先頭に戻す

}

Ajaxによるコンテンツの切替え

この方式は、副作用が多々あるようである。

先ずは、Pjaxのところで書いたように
URLの変更がないため履歴が変更されず
ブラウザの「戻る」や「進む」ボタンが
使えない。
そのため、Pjaxを使用するなどの対策が
必要になるのであった。

ところが、このPjaxを使用したことによる
問題もあることが判明。

ブラウザの「更新」(再読み込み)
ボタンを押すと、コンテンツのみが
ロードされてしまうのだ。

一般的には、それ程使用するボタンでは
ないと思われるが、ページの開発過程
では頻繁に使用するボタンである。
このボタン押すたびに、フォームが崩れ
毎回、Ajaxを設定しているHTML
(index.html)から、読み直すのは結構
なストレスがかかる。

もう一つの問題は、Google検索である。
申請して、漸く使えるようになったの
だが、もしコンテンツ部分がクロール
され、それが結果に表示された場合
あられもない、スッピンのHTMLが表示
されてしまうのだ。

ページを公開するには、何らかの対策
が必要なのだが、長くなったので、こ
の対策は後日書く。

ディレクトリにある全ソースの末尾に1行追加

いろいろHTMLを見直していたら
多数のソースの末尾に1行追加
する必要が生じた。

Javascriptは、ファイルのロードは出来ても
出力ができ無ない。
そこで、こんなものを作ってみた。

● HTML

<!DOCTYPE html>
<html>
<head>
<title>ソースの末尾にコードを追加するツール</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="Description" content="ソースの末尾にコードを追加するツール" />
<script type="text/javascript" src="/files/jquery.js"></script>
<script type="text/javascript">
//******************************************************
//  ソースの末尾にコードを追加するツール
//******************************************************
$(document).ready(function(){
  $("button").click(function(){
    indir = $("#indir").val();
    otdir = $("#otdir").val();
    // テンプレートデータ入力
    $.ajax({
      type: "GET",
      url: "lineAdd.php",			// データ入力
      data: {
             "indir" : indir,
             "otdir" : otdir
            },
      dataType: "text",
      success: dataProc,
      error: function(req,msg,err){
      alert("input error " + msg);
    }
  });
});

  function dataProc(data){
    $("#output").html(data);
  }
})
</script>

</head>
<body>
<h1>ソースの末尾にコードを追加するツール</h1>
<div>
入力ソースのディレクトリ名: <br />
<input type="text" size="20" id="indir" name="indir" value="/w3c/sql/in/" />
</div>
<br/>
<div>
出力ソースのディレクトリ名: <br />
<input type="text" size="20" id="otdir" name="otdir" value="/w3c/sql/out/" />
</div>
<br/>
<button>処理実行</button><br /><br />
<div id="output"></div>
</body>
</html>

● php

<?php
	
	/***********************************************************************
	   指定ディレクトリ(/web/xxx/in/)配下のファイル名を配列で返します
	***********************************************************************/
	function getProg($dirname){
		// ディレクトリのオープン
		$dir = dir($dirname);
		//var_dump($dir);
		// g:/w3c 配下のディレクトリを入力
		$cnt = 0;
		while [1]$file = $dir->read( !== false){
			if(is_file($dirname . $file)){					// ファイル以外は無視
			  if($file != ".." && $file != "."){		// 「.」、「..」は無視
			  	//echo $file . "<br/>";
					$info = pathinfo($file);						// path情報取得
					if($info['extension'] == "html"){		// 拡張子の判定取得
						$pArry[$cnt] = $file;							// ファイル名を設定
						$cnt++;
					}
			 	}
			}
		}
		//echo (count($pArry) . "<br/>");
		return $pArry;
	}

	/***********************************************************************
	   Main
	***********************************************************************/
	// 入力ソースのディレクトリ名(/web/dom/in/)
	if(isset($_GET['indir'])) {
		$indir = $_GET['indir'];
	} else {
		die ("引数に indir の指定がありません !");
	}
	//echo "dir名=" . $indir . "<br/>";	// <-- Debug
	
	// 出力ソースのディレクトリ名(/web/dom/out/)
	if(isset($_GET['otdir'])) {
		$otdir = $_GET['otdir'];
	} else {
		die ("引数に otdir の指定がありません !");
	}
	//echo "otdir名=" . $otdir . "<br/>";	// <-- Debug
	
	//**********************************************************************
	// w3schoolのソースを抽出
	$pArry = getProg($indir);
	$num = count($pArry);
	$wtbl = '<table id="res">';
	for($i = 0; $i < $num; $i++){
		$file = file_get_contents($indir.$pArry[$i]);
		$src  = mb_convert_encoding($file,"utf-8", "auto");
		// ソースの末尾に1行追加する
		$src .= '<script src="/w3c/common/procSeqCheck.js"></script>';
		// ファイル出力
	 	$otfile = $otdir . $pArry[$i];
	 	$flen  = file_put_contents($otfile,$src);
		$wtbl .= '<tr><td class="sou">' . $pArry[$i] . '</td><td class="byt">' . $flen . ' bytes</td></tr>';
	}
	echo $wtbl .= "</table>";
?>

これが、どうしても必要な訳は後日に。

References

References
1 $file = $dir->read(

Pjaxの使用方法

Ajaxを使用して、メニューに応じてコンテンツのみを入れ替えるページを作成してみた。
全ページに共通した部分とコンテンツ部分に分離できるので、共通部のメニュー等に変更が
発生した場合にも、1ページの変更で済むので、メンテナンス性が飛躍的に向上する。

また、コード量が縮小できるので、ロード時間の短縮やディスク・スペースの節減等々文句
のつけようの無い方式のようにも思えるのだが、何点か問題が指摘されているようだ。

中でも困るのは、表示履歴が更新されないので「戻る」ボタンが使えないことだ。

この問題は、別段新しい話題ではなく、随分前から語り尽くされた感のある話題のようである。
検索で得られた沢山の情報の中で、とりわけPjaxというjQueryプラグインが目を引いた。

Pjax に関しては、事例を基に解説してくる親切なサイトが多いのだが、私の目指す方向に合う
説明が見つからず、方向性が正しいのかどうかで、昨日一日スッタモンダの大苦闘。

これ以上、他サイトの情報は期待できないので、Pjaxのソースを見て方向性を判断することに
したのだが、簡単に言えば、pjax は引数に指定した url(HTMLソース)を container の位置に
挿入し、表示履歴を push してくれるものらしい。

これは、使い方の観点からは $.ajax または load()メソッドに同じである。
とすれば、昨日混乱した原因の一つのサーバサイド・スクリプトもいらない・・・
(コンテンツ部分だけを返すような場合は、サーバ側での対応は不要のようだ。)

以上から、ajaxで load() を使用していた部分を、pjax()に変更し、括弧内のパラメータを設定
すれば、私の目的は達成でるとの結論に至る。
長々と書いたが、結論は全くあっけないもの。
でも、問題が解決できて嬉しい!

最後に、ajaxとpjaxの比較に今回作成したものを掲載したので、同じ悩みをお持ちの方の参考になれば幸いです。

アンカー・タグのリンクを無効にする(続き)

前回の内容は、それはそれで一つの方法ではあるが、
リファレンスを調べたところ、もと正統な方法が
あったので、その方法を追記すると共に、知識の無さ
に恥じ入る次第。
反省!

$(document).ready(function(){
  $("a").click(function(event){
    event.preventDefault();
  });
});

アンカー・タグのリンクを無効にする

アンカータグのリンクを無効にして、リンク情報のみを入手したい場合がある。

例えば、ヘッダ、フッタ、(左)サイドメニューを固定し、コンテンツのみを
ロードするようなケースである。

コンテンツ部分のみをロードすれば、量が少なくなり回線の負荷が軽減できる。
当然、コーディング量も減るし、ヘッダ等の変更があっても1本だけの変更で
済み、効率アップには大変に有効である。

これを行うためには、アンカータグのリンクを無効にすることが必要である。

その方法は次の通り。

$(document).ready(function(){
  $('a').click(function(){
    alert($(this).attr("href")); // hrefの属性値をアラートで表示
    return false;                // リンクを無効に
  });
});

世界を敵に回した日本

安倍と言うこの人間、前々からアホな奴と思っていた。
何もしなきゃ、毒にもならないが
世界中から批判を浴びる行動をとるにおよんで
国民全体が、このバカと同類項に巻き込まれた。

でも、わたしゃやだよ。
こんなアホと一緒にしないでくれ。

アメリカ、ロシア、中国、ユーロなど全世界を敵に回して
何をしたいんだろうね。
もう靖国を抱いて地獄に行ってくれ。

上昇機運の経済も危ないぞ!