Top > JavaScript [全て開く]
2012年1月20日

リターン(Enterキー)でフォームを送信しない方法

January 20,2012 1:55 AM
Tag:[, ]
Permalink

フォームのテキスト入力中にうっかりリターン(Enterキー)を押してしまい、中途半端なフォームが送信されてしまったという経験をした人は結構多いのではないかと思います。

ということで、リターン(Enterキー)でフォームを送信しないようにする方法を紹介します。この記事の投稿時点でのGoogle Chrome・Firefoxの最新版とIE9で同じ動作になることを確認しています。

1.リターンでフォームが送信される原因

次のように、type属性が「text」のinput要素、いわゆるテキストフィールドが含まれるフォームで、テキストフィールドがアクティブなときにリターンを押すとフォームが送信されてしまいます。

<form action="hoge.cgi">
  <input type="text" name="foo" />
  <input type="text" name="bar" />
  <input type="submit" value="送信" />
</form>

または

<form action="hoge.cgi">
  <input type="text" name="foo" />
  <input type="text" name="bar" />
  <button type="submit">送信</button>
</form>

type属性が「password」の場合も同様です。

2.送信ボタンを書き換える

送信ボタンを赤色のように、「type="button"」のinput要素またはbutton要素に書き換えることで、リターンによる送信を回避できます。

<form action="hoge.cgi">
  <input type="text" name="foo" />
  <input type="text" name="bar" />
  <input type="button" onclick="submit();" value="送信" />
</form>

または

<form action="hoge.cgi">
  <input type="text" name="foo" />
  <input type="text" name="bar" />
  <button type="button" onclick="submit();">送信</button>
</form>

つまり、type属性が「submit」のinput要素またはbutton要素を作らない、ということがポイントです。

onclick属性の部分をjQueryで書き直すと、次のようになります。

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script>
$(function(){
  $("input[type=button]").click(function(){
    $("form").submit();
  });
});
</script>
<form action="hoge.cgi">
  <input type="text" name="foo" />
  <input type="text" name="bar" />
  <input type="button" value="送信" />
</form>

なお、フォームにテキストフィールドが1つしかない場合は次の対処も併せて行う必要があります。

3.テキストフィールドがフォームに1つしかない場合

次のように、テキストフィールド(またはパスワードフィールド)がフォームに1つしかない場合、2項の対処を行っても送信されてしまいます(下)。textareaや他のtype属性のinput要素が複数存在しても挙動は同じです。

<form action="hoge.cgi">
  <input type="text" name="foo" />
  <input type="button" onclick="submit();" value="送信" />
</form>

このような場合はダミーのテキストフィールドのinput要素を用意して、テキストフィールドが2つある状態にします。

<form action="hoge.cgi">
  <input type="text" name="foo" />
  <input type="text" name="dummy" style="display:none;">
  <input type="button" onclick="submit();" value="送信" />
</form>

4.押されたキーを判定して抑止する

3項まではtype属性が「submit」の要素を排除することで実現しましたが、ここでは押されたキーによって判定する方法を紹介します。

押されたキー(リターンは「13」)で判定するには次のようにします。

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script>
$(function(){
  $("input[type=text]").keypress(function(ev) {
    if ((ev.which && ev.which === 13) ||
        (ev.keyCode && ev.keyCode === 13)) {
      return false;
    } else {
      return true;
    }
  });
});
</script>
<form action="hoge.cgi">
  <input type="text" name="foo" onkeypress="return entsub()" />
  <input type="submit" value="送信" />
</form>

この方法であればtype属性がsubmitのinput要素を使えるようです。

5.参考サイト

参考サイトは以下です。ありがとうございました。

Comments [0] | Trackbacks [0]
2012年1月18日

onsubmitイベントと「return false」を組み合わせてsubmitを中断する方法

January 18,2012 2:22 AM
Tag:[, ]
Permalink

onsubmitイベントと「return false」を組み合わせてsubmitを適切に中断する方法を紹介します。

1.onsubmitイベントとは

onsubmitイベントは、フォームの送信ボタン(type属性がsubmitのボタン)がクリックされた時に発生するイベントです。

<form method="post" action="foo.cgi" onsubmit="foo();">
  <input type="text" value="" />
  <input type="submit" value="送信" />
</form>

2.submitを中断する(=フォームを送信しない)方法

onsubmitイベントを使ってsubmitを中断するケースとして、送信時にJavaScriptでフォームのチェックをして、フォームデータに未入力の項目がある場合、「return false;」で送信を中止するというパターンがあると思いますが、中止したはずのに送信が実行されてしまうということがあります。

次のソースコードはその例で、未入力の項目がある場合に「return false」を行ってますが、送信は中断されません。

<script type="text/javascript">
function check() {
    for(i = 0; i < document.foo.length; i++) {
        if (document.foo.elements[i].type == "text") {
            if (document.foo.elements[i].value == '') {
                 alert("未入力の項目があります。");
                 return false;
            }
        }
    }
}
</script>
<form name="foo" action="foo.cgi" onsubmit="check();">
  <input type="text" id="a" value="" />
  <input type="text" id="b" value="" />
  <input type="submit" value="送信" />
</form>

原因は、赤色で示したform要素のonsubmit属性の記述が誤っているためです。

送信を中止するためには、onsubmit属性で起動した関数の返却値(false)をさらに返却する必要があります。つまり、

onsubmit="関数名"

ではなく、

onsubmit="return 関数名"

としなければなりません。

また、常に送信を中止したい場合は、

onsubmit="関数名; return false;"

と書けばよいでしょう。

先程のサンプルでは、次の青色部分のように修正すれば送信を中止します。

<script type="text/javascript">
function check() {
    for(i = 0; i < document.foo.length; i++) {
        if (document.foo.elements[i].type == "text") {
            if (document.foo.elements[i].value == '') {
                 alert("未入力の項目があります。");
                 return false;
            }
        }
    }
}
</script>
<form name="foo" action="foo.cgi" onsubmit="return check();">
  <input type="text" id="a" value="" />
  <input type="text" id="b" value="" />
  <input type="submit" value="送信" />
</form>

「true」はonsubmitイベントのデフォルト返却値なので、OKの場合に「return true;」を明示的に記述する必要はないと思います。

3.jQueryでの記述

jQueryで記述する場合は、次のようになるみたいです。

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script>
$(function(){
    $('#foo').submit(function(){
        var flag = 0;
 
        // フォームチェック
        $(this).find('input[type=text]').each(function(){
            if ($(this).val() == '') {
 
                // NGの場合
                flag = 1;
                return false; // break
            }
        });
        if (flag) {
            return false; // return
        }
    });
});
</script>
<form id="foo" action="foo.cgi">
  <input type="text" id="a" value="" />
  <input type="text" id="b" value="" />
  <input type="submit" value="送信" />
</form>

青色で示した、submit()ブロック内で「return false;」をすればフォームの送信を中止するようです。

each()ブロック内の赤色で示した「return false;」は、each()のループを脱出しているだけなので、間違えないように注意しましょう。

Comments [0] | Trackbacks [0]
2012年1月12日

JavaScriptで現在日時を取得する

January 12,2012 1:55 AM
Tag:[]
Permalink

JavaScriptで今日の日付と時刻を取得・表示する方法です。

毎回同じものを作っているような気がするのと、JavaScriptのビギナーの方むけの情報という意味で、このエントリーで動作サンプルを掲載しておきます。

1.現在日時を取得するサンプル

現在日時を取得するサンプルを以下に掲載します。このサンプルをウェブページに丸ごとコピー&ペーストすれば、サンプル下にある「出力結果例」の表示になると思います。

<script type="text/javascript">
var get_current_timestamp = function() {
    var weeks = new Array('日', '月', '火', '水', '木', '金', '土');
    var d = new Date();
 
    // 年月日・曜日・時分秒の取得
    var month  = d.getMonth() + 1;
    var day    = d.getDate();
    var week   = weeks[ d.getDay() ];
    var hour   = d.getHours();
    var minute = d.getMinutes();
    var second = d.getSeconds();
 
    // 1桁を2桁に変換する
    if (month < 10) {month = "0" + month;}
    if (day < 10) {day = "0" + day;}
    if (hour < 10) {hour = "0" + hour;}
    if (minute < 10) {minute = "0" + minute;}
    if (second < 10) {second = "0" + second;}
 
    // 整形して返却
    return d.getFullYear()  + "/" + month + "/" + day + "(" + week + ") " + hour + ":" + minute + ":" + second;
}
 
// 現在の日付・時刻を表示する
document.write(get_current_timestamp());
</script>

出力結果例

2012/01/12(木) 00:03:03

青色部分は現在日時の取得処理を関数にまとめたもので、その下の行にある「document.write( ... );」は、その関数を呼び出して動作を確認するためのものです。

2.別の関数から現在時刻を取得する

別の関数から現在時刻を取得したい場合、たとえばfoo()という関数から取得するには、赤色部分のように記述してください。青色は、1項のサンプルの青色部分が相当します。

<script type="text/javascript">
var get_current_timestamp = function() {
  // 中略
}
function foo() {
    var current = get_current_timestamp();
    // 変数currentを使った処理を記述
}
</script>

3.出力フォーマットを変更する

出力フォーマットを変更するには次の部分を書き換えてください。

return d.getFullYear() + "/" + month + "/" + day + "(" + week + ") " + hour + ":" + minute + ":" + second;

例えば「xxxx年xx月xx日 xx時xx分」にするには、次のように書き換えます。

return d.getFullYear() + "年" + month + "月" + day + "日 " + hour + "時" + minute + "分";

4.月日時分秒を1桁で出力する

月日時分秒の「1」~「9」を1桁で出力したい場合は、次の部分をまるっと削除してください。

// 1桁を2桁に変換する
if (month &lt; 10) {month = "0" + month;}
if (day &lt; 10) {day = "0" + day;}
if (hour &lt; 10) {hour = "0" + hour;}
if (minute &lt; 10) {minute = "0" + minute;}
if (second &lt; 10) {second = "0" + second;}

5.注意事項

get_current_timestamp()は関数リテラルによる定義(var xx = function(){ ... }という形式)のため、関数定義の前にdocument.write()などの処理を記述すると正常に動作しません。

<script type="text/javascript">
document.write(get_current_timestamp()); // これはエラー
var get_current_timestamp = function() {
  // 中略
}
</script>

要するに1項のサンプルや2項のように、get_current_timestamp()の定義の後方に、get_current_timestamp()を呼び出す処理を記述してください。

Comments [0] | Trackbacks [0]
2011年8月29日

CSSファイルやJavaScriptファイルを読み込むときの末尾にあるクエリー文字列は何のためにあるか

August 29,2011 1:55 AM
Tag:[, , , ]
Permalink

あちこちのウェブサイトのHTMLソースを見ると、CSSファイルやJSファイルを読み込むlink要素やscript要素のファイル名の末尾に「?xxx=123」のような、いわゆるクエリーがついているのを頻繁にみかけます。

例えばWordPressでjqueryを読み込んだときなど、

<script src="http://user-domian/wp-includes/js/jquery/jquery.js?ver=1.6.1"></script>

と、jQueryのバージョン番号を示すクエリー文字列がついています。CSSファイルやJavaScriptファイルはCGIではないので、このクエリーを解釈して使っている訳ではありません。

知っている人は「な~んだ」って感じだと思いますが、この「?ver=1.6.1」の役割について紹介します。

1.キャッシュを制御する

ページ読み込みと同時に読み込まれるCSSやJavaScriptの内容はブラウザキャッシュに読み込まれ、ページを強制リロードしない限りブラウザキャッシュの内容が適用されるようです(詳細は4項参照)。

ですが、CSSファイルやJavaScriptファイルを更新してもキャッシュの内容が適用され続けるのは困るので、クエリー文字列を使って制御します。

具体的には、クエリーのバージョン番号やタイムスタンプを更新すると、ブラウザはそのクエリーつきのURLを「まだ取得していないファイルだ」と認識して、キャッシュから読み込まずに、サーバのファイルを取得します。

この手法はCSSファイルやJavaScriptファイル以外でも使えます。

2.クエリーが変更されないとキャッシュを使う理由

そういうものかと思ってこの技をなんとなく使っている訳ですが、ふと、HTTPの仕様として「クエリーが変更されないとキャッシュを利用する」ということがどこかに規定されているのではないかと思いました。

調べてみたところ、RFC2616の「13 Caching in HTTP」の「13.9 Side Effects of GET and HEAD」にそれらしき記述があるなので日本語訳から引用し、該当すると思われる箇所を赤字で示します。

ハイパーテキスト転送プロトコル -- HTTP/1.1 - 13.9 GET や HEAD の副作用

オリジンサーバがそれらのレスポンスのキャッシングを明示的に禁止していない場合に、あらゆるリソースへ GET や HEAD メソッドを適用する事によってそれらのレスポンスがキャッシュから取り出されたならば、誤った動作を導くような副作用を抱えるべきではない。それらは副作用を抱えるかもしれないが、キャッシュはそのキャッシング決定においてそのような副作用を考慮必要は無い。キャッシュは常にキャッシングにおいてオリジンサーバの明示的な制限を観察する事が期待される。
この規則の一つの例外について記す。アプリケーションの中には伝統的に重要な副作用を抱えた操作を実行するためにクエリ URL (それらは rel_path 部分に "?" を含んでいる) を伴う GET や HEAD を使用しているものがあるので、キャッシュはサーバが明示的有効期限を与えていなければそのようなURI へのレスポンスを新鮮であるように扱ってはならない。これは、そのような URI に対する HTTP/1.0 サーバからのレスポンスはキャッシュから取り出されるべきではない という事を特に意味している。関連する情報については section 9.1.1 参照。

「この部分ではない」ということであれば記事を修正しますので、ご指摘ください。

3.jQueryでキャッシュをクリアする

話がまったく横道にそれますが、キャッシュつながりということで、jQueryのAjaxで読み込むファイルのキャッシュをクリアする方法も掲載しておきます。

キャッシュをクリアするには、cacheプロパティを利用します。

$.ajax({
    url: 'http://user-domain/',
    type: 'GET',
    cache: false,
    success: function (data) {
        //
    }
});

ajaxSetupでも設定可能です。

$.ajaxSetup({
    cache: false
});
$('#foo').load('http://user-domain/');

4.実験結果

本当にブラウザキャッシュが使われているのかどうか、FirefoxのLive HTTP Headersを使って、当ブログのトップページのHTTPヘッダを確認してみました。

初回に読み込まれるCSSやJavaScriptは「200 OK」で返却されます。

初回読み込み

2回目以降のアクセス(ロケーションバーにカーソルをあててリターン)ではリクエスト自体が送信されておらず、ブラウザキャッシュが利用されているものと考えます。

リロードボタンを押すとサーバにリクエストが送信されますが、サーバは「304 Not Modified」を返却(=ブラウザキャッシュを利用)します。

リロード

強制リロード(Shift+リロードボタンまたはCtrl+F5)では、サーバから「200 OK」が返却されます。

また、本題であるクエリーを変更した直後も「200 OK」が返却されました。

Comments [0] | Trackbacks [0]
2011年5月30日

FirefoxやChromeでブラウザのウインドウサイズを変更するブックマークレット

May 30,2011 12:55 AM
Tag:[, ]
Permalink

小ネタです。ブラウザのウインドウサイズを変えるブックマークレットを紹介します。ビギナー向けにブックマークレットについても簡単に解説しています。

1.ブックマークレットとは

「ブックマークレット」とは、JavaScriptで記述したちょっとしたプログラムのことを指し、ブラウザのブックマークやブックマークツールバーに登録して利用することからこの名称となったようです。 登録したブックマークをクリックすることでブックマークレットが機能します(一部Wikipediaより引用)。

Wikipedia - ブックマークレット

2.ウインドウサイズを変更するブックマークレット

以下のリンク(ブックマークレット)を左クリックしてブックマークツールバーにドラッグするか、右クリックして「お気に入り」や「ブックマーク」に追加します。

①:1000 x 750

Chromeの場合は以下のブックマークレットを使用してください。Firefoxは①②のどちらでも動作します。

②:1000 x 750

3.ブックマークレットの使い方

ブックマークツールバーにドラッグした「1000 x 750」をクリックすれば、ウィンドウサイズを変更することができます。②のブックマークレットは、表示中のページを、指定したサイズで新しいウィンドウを開きます。

ブックマークツールバー

「お気に入り」や「ブックマーク」に追加した場合は、追加した「1000 x 750」を選択してください。

3.サイズの変更方法

サンプルのブックマークレットは幅1000px、高さ750pxで設定しているので、サイズは適宜変更してください(タイトルも)。

Firefoxの場合、①のブックマークレットの値を変更するには、ブックマークレットを右クリックして、「プロパティ」をクリック。

ブックマークメニュー

URL欄に表示されているJavaScriptの「1000」「750」を変更して「保存」をクリックします。

プロパティ画面

Google Chromeの場合、②のブックマークレットの値を変更するには、ブックマークレットを右クリックして、「編集」をクリック。

ブックマークメニュー

「URL」欄に表示されているJavaScriptの「1000」「750」を編集して「OK」をクリックします。

編集画面

4.サイズの算出方法について

①のブックマークレットにあるresizeTo()で指定した値は、ブラウザ全体の幅・高さになります。表示領域を1000x750にしたい場合は多めの値を設定してください。スクロールバーありの場合、Firefoxであれば、幅は1033pxで丁度いいようです。高さはツールバーの表示状態によって異なります。

②のブックマークレットにあるwindow.open()で指定した値は、設定したサイズがそのまま表示領域となります。ただしスクロールバーは含まれるので、その分は多めに設定してください。Chromeであれば横幅は1017pxを設定すると丁度いいようです。

ブックマークレットはスクロールバーの有無で使い分けられるよう、2つ用意しておくといいでしょう。

5.Firefoxの「Web Developer」アドオンでリサイズする

ご存知の方も多いと思いますが、Firefoxであれば「Web Developer」アドオンにリサイズ機能がついています。

「Web Developer」アドオン

6.参考サイト

参考サイトは以下です。ありがとうございました。

Comments [0] | Trackbacks [0]
2011年4月11日

Facebookでよく使われるようになったインラインフレーム(iframe)の注意事項

April 11,2011 1:55 AM
Tag:[, , ]
Permalink

これまでウェブサイトの制作であまり使ったことがなかったインラインフレーム(iframe)ですが、Facebookが登場してからiframeタブやソーシャルプラグインなどで利用するシーンが増えてきました。

ということで、インラインフレームについての注意事項をまとめてみました。

1.親フレームでインラインフレームのCSSは定義できない

Facebookのコメントボックスを黒背景のブログで使えるようにする」でも書きましたが、親フレームで定義したCSSはインラインフレームに適用されません。

サンプル1
サンプル1

サンプルの枠上部にある「foo」という文字と枠内(インラインフレーム)の「bar」という文字に対し、親フレームで同じスタイルを与えていますが、インラインフレームには反映されていないことが分かります。

CSSを反映できるのはiframe要素までです。

2.リンクターゲットに気をつけよう

iframe内ページのリンクにtarget属性を付与しないと、リンク先のコンテンツがフレーム内に表示されてしまいます。

次の例は、当Facebookページの「いいね!ランキング」のiframeタブページをサンプルにした失敗例です。

インラインフレームにあるリンクをクリック

適切なtarget属性を指定しないとリンク先のコンテンツがフレーム内に表示

このようなことにならないよう、適切なリンクターゲット(target属性)を設定しましょう。フレームを解除して表示する場合はtarget属性に「_top」を指定します。

各target属性の振る舞いについてはサンプルで確認してください。他のフレームに表示する方法も掲載しています。

サンプル2
サンプル3

iframe3.htmlというのは、次項のサンプルで登場でする、アクセス方法を確認するスクリプトを組み込んだページです。

3.インラインフレームで表示されているかどうかを確認するには

該当のページがブラウザから直接アクセスして表示されているのか、インラインフレームとして表示されているかを判断するには、JavaScriptで次のような判定を行います。

<script>
if(self == top){ 
  alert("直接アクセスしています");
} else {
  alert("インラインフレームでアクセスしています");
}
</script>

上記のスクリプトの動作は次のサンプルで確認できます。IE6でも動作します。

サンプル3-1(直接アクセスした場合)
サンプル3-1

サンプル3-2(インラインフレームでアクセスした場合)
サンプル3-2

iframeタブは外部ページで作成するので、何かの役に立つかもしれません(そもそもFacebookの機能で判断できるかもしれませんが)。

Comments [0] | Trackbacks [0]
2010年12月20日

フォームから別ウィンドウを開く方法のまとめ

December 20,2010 12:55 AM
Tag:[, ]
Permalink

フォームから別ウィンドウを開くためのTipsをまとめました。

1.はじめに

フォームから別ウィンドウを開く場合、

  • 別ウィンドウで起動されるCGIにフォームデータを渡したい
  • フォームボタンを複数回クリックしたときに別ウィンドウを1枚しか開きたくない
  • フォームボタンを複数回クリックしたときに別ウィンドウを複数枚開けるようにしたい

と、色々なケースがあります。

業務で使うCGIを開発するときにこれらのことをネットで色々調べたのですが、FAQサイトなどに個別の情報が散在しているだけでしたので、このエントリーで一挙にまとめてみました。

ここではjQueryを使わないオーソドックスなコードで解説します。コード内に使われているCGI(new_window.cgi)は6項に掲載しています。サンプルを実行する場合、すべての資材を同じディレクトリに配置して実行してください。

2.基本動作

フォームから別ウィンドウを開くには、form要素にtarget属性を与え、値に「_blank」を設定する方法があります。

<form method="post" target="_blank" action="./new_window.cgi">
  <input name="id" type="submit" value="新しいウィンドウを開く" />
</form>

ただし、この方法ではタブブラウザでは新しいタブが開きます。

ウィンドウとして開くには、type属性値が「submit」のinput要素にonclickイベントハンドラを与え、イベントハンドラの中でwindow.openメソッドを起動します。

<script type="text/javascript">
function open1() {
    window.open("new_window.cgi", "hoge", 'width=200, height=200');
}
</script>
<form method="post" action="./new_window.cgi" onsubmit="return false;">
  <input type="submit" name="id" value="新しいウィンドウを開く" onclick="open1()"/>
</form>

form要素にはonsubmitイベントハンドラを与え、値に「return false」を設定しておきます。この設定を行わないと、元ウィンドウでもaction属性に設定されたCGIが実行されてしまいます。

open関数の引数は次の通りです。

  • 第1引数:起動URL
  • 第2引数:ウィンドウ名
  • 第3引数:ウィンドウのスタイル

ウィンドウ名に「_blank」を設定すれば、クリックするたびに新しい画面が開きます。サンプルでは「hoge」という固定文字列を与えているので1枚しか開きません。

3.新しいウィンドウにデータを渡す(開くウィンドウはひとつ)

新しいウィンドウにフォームデータを渡すには、イベントハンドラのパラメータでフォームデータを渡し、そのフォームデータでform.submitメソッドを起動します。このケースではwindow.openの第1引数は使わない(form要素のaction属性値が使われる)ので「about:blank」を設定しています。

<script type="text/javascript">
function open2(f) {
    f.target = "hoge";
    var w = window.open("about:blank", f.target, 'width=200, height=200');
    w.focus();
    f.submit();
}
</script>
<form method="post" action="./new_window.cgi" onsubmit="return false;">
  <input type="text" name="data" />
  <input type="submit" name="id" value="送信" onclick="open2(this.form)"/>
</form>

4.新しいウィンドウにデータを渡す(開くウィンドウは複数)

新しいウィンドウを複数開く方法です。3項では新しいウィンドウを開いた状態でフォームボタンをクリックしても、常に1枚しか開きませんが、本項では別のウィンドウを開くことができます。

<script type="text/javascript">
function open3(f) {
    window.name = (new Date()).getTime();
    var date = new Date();
    var time = date.getTime()
    f.target = window.name + time;
    var w = window.open("about:blank", f.target, 'width=200, height=200');
    w.focus();
    f.submit();
}
</script>
<form method="post" action="./new_window.cgi" onsubmit="return false;">
  <input type="text" name="data" />
  <input type="submit" name="id" value="送信" onclick="open3(this.form)"/>
</form>

window.openの第2引数に、常に値が異なるようタイムスタンプを設定します。2項のケースではウィンドウ名に「_blank」を設定すれば異なるウィンドウが開きますが、JavaScript内からsubmitを起動する場合は期待した動作になりません(新しい空のウィンドウが開き、もうひとつ別のウィンドウが開いてCGIが起動される)。

5.新しいウィンドウにボタンの値を渡す

最後に、新しいウィンドウにtype属性値が「button」のinput要素の値を渡す方法です。値を渡すにはvalue属性をイベントハンドラのパラメータに渡し、その値をtype属性が「hidden」のinput要素に設定します。

<script type="text/javascript">
function open4(f, value) {
    f.button.value = value;
    f.target = "new";
    var w = window.open("about:blank", f.target, 'width=200, height=200');
    w.focus();
    f.submit();
}
</script>
<form method="post" action="./new_window.cgi">
  <input type="text" name="data" />
  <input type="hidden" name="button" />
  <input type="button" value="送信1" onclick="open4(this.form, '送信1')" />
  <input type="button" value="送信2" onclick="open4(this.form, '送信2')" />
</form>

6.CGIサンプル

上記のサンプルから起動されるCGIです。動作確認用にご利用ください。

#!/usr/bin/perl
 
use strict;
use CGI;
 
my $q = new CGI;
 
print $q->header(-charset=>'utf-8',);
print $q->start_html();
 
print '<p>テスト</p>';
print 'text:',$q->param('data') if $q->param('data');
print '<br />button:',$q->param('button') if $q->param('button');
 
print $q->end_html();
Comments [2] | Trackbacks [2]
2010年8月 9日

jQuery ベースのドロップダウンメニュー「Superfish」(縦メニュー)

August 9,2010 11:55 PM
Tag:[, ]
Permalink

Superfish は jQuery ベースでドロップダウンメニューを実現するためのライブラリです。

Superfish によるグローバルナビゲーション

このエントリーは「jQuery ベースのドロップダウンメニュー「Superfish」」の縦型メニュー版の設定方法です。質問を頂きましたので本エントリーで紹介致します。

サンプルを用意しましたので動作をご確認してください。

Superfish によるグローバルナビゲーションのサンプル

ここでは、Superfish + Movable Type(配布テンプレート)による、冒頭の画像ような、サイドバーにカテゴリメニューを設定する方法を紹介します。

1.Superfish のダウンロード

Superfish のサイトにアクセス。

Superfish のサイト

タブの「Download & Support」をクリックし、「Superfish-1.4.8.zip(2009年9月時点のバージョン)」のリンクをクリックしてアーカイブをダウンロード。

Superfish のダウンロード

2.Superfish のアップロード

アーカイブを展開し、superfish-1.4.8 のフォルダ名を superfish にリネームして、フォルダごとブログディレクトリにアップロード。

3.head 要素の修正

head 要素のあるテンプレートに下記を追加します。MT5のクラシックブログやクラシックウェブサイトであれば、「HTMLヘッダー」テンプレートモジュール、当サイト配布のテンプレートであれば「ヘッダー」テンプレートモジュールが該当します。

<link rel="stylesheet" type="text/css" media="screen" href="<mt:BlogURL />superfish/css/superfish.css" />
<link rel="stylesheet" type="text/css" media="screen" href="<mt:BlogURL />superfish/css/superfish-vertical.css" />
<script type="text/javascript" src="<mt:BlogURL />superfish/js/jquery-1.2.6.min.js"></script>
<script type="text/javascript" src="<mt:BlogURL />superfish/js/hoverIntent.js"></script>
<script type="text/javascript" src="<mt:BlogURL />superfish/js/superfish.js"></script>
<script type="text/javascript" src="<mt:BlogURL />superfish/js/supersubs.js"></script>
<script type="text/javascript">
    $(document).ready(function(){
        $("ul.sf-menu").superfish({ 
            animation: {height:'show'},   // slide-down effect without fade-in 
            delay:     1200               // 1.2 second delay on mouseout 
        }); 
    });
</script>

script 要素内の「ul.sf-menu」が、3項の一番外側の ul 要素の class 属性値になります。また、

  • animation:アニメーション表示
  • delay:マウスアウト後の表示期間(ms指定)

となっています。

3.ドロップダウンメニューの追加

サブカテゴリリストを利用したドロップダウンメニュー(青色)を、サイドメニューに設定します。以下はサンプルで設定したものと同じものです。当サイト配布のテンプレートであれば「サイドバー」テンプレートモジュールまたは任意のウィジェットを作成して、そこに設定します。

それ以外のテンプレートであれば、サブテンプレートの最初と最後の方にあるdd要素の開始タグと終了タグを削除してください。

青色で示すclass属性値が、superfishで利用するクラス名になります。

<mt:ifArchiveTypeEnabled archive_type="Category">
<dd class="clearfix">
<mt:topLevelCategories>
  <mt:subCatIsFirst>
  <ul<mt:hasNoParentCategory> class="sf-menu sf-vertical"</mt:hasNoParentCategory>>
  </mt:subCatIsFirst>
    <mt:if tag="CategoryCount">
    <li><a href="<mt:categoryArchiveLink />" title="<mt:categoryDescription />"><mt:categoryLabel /></a>
    <mt:else>
    <li><a href="#"><mt:categoryLabel /></a>
  </mt:if>
    <mt:subCatsRecurse />
    </li>
    <mt:subCatIsLast>
  </ul>
    </mt:subCatIsLast>
  </mt:topLevelCategories>
</dd>
</mt:ifArchiveTypeEnabled>

4.メニュー幅の修正

メニュー幅はsuperfish-vertical.cssにある、widthプロパティとleftプロパティ(赤色部分)をそれぞれ修正します。ダウンロード時のデフォルト値は10emになっています。サンプルでは12.8emに変更しています。

.sf-vertical, .sf-vertical li {
        width: 10em;
}
/* this lacks ul at the start of the selector, so the styles from the main CSS file override it where needed */
.sf-vertical li:hover ul,
.sf-vertical li.sfHover ul {
        left: 10em; /* match ul width */
        top: 0;
}
Comments [0] | Trackbacks [0]
2009年9月30日

jQuery ベースのドロップダウンメニュー「Superfish」

September 30,2009 1:55 AM
Tag:[, ]
Permalink

Superfish は jQuery ベースでドロップダウンメニューを実現するためのライブラリです。

Superfish によるグローバルナビゲーション

サンプルを用意しましたので動作をご確認してください。

Superfish によるグローバルナビゲーションのサンプル

ここでは、Superfish + Movable Type(配布テンプレート)によるグローバルナビゲーションを設定方法を紹介します。

なお、配布サイトのサンプルを試しましたが、書かれている通りに実行しないものがいくつかありました。ここではサンプルの「with Supersubs」を選びました。理由は、サンプルの設定通りに動いてくれたことと、メニューの幅を変更でき、使いやすそうだったためです。

また、Superfish では、本エントリーで紹介するサンプル以外にも、以下のようなことができます。

IEでプルダウンに重なっても表示
Superfish によるグローバルナビゲーション:プルダウンに重なっても表示

縦型メニュー
Superfish によるグローバルナビゲーション:縦型メニュー

2段目のサブメニューを水平表示
Superfish によるグローバルナビゲーション:2段目のサブメニューを水平表示

1.Superfish のダウンロード

Superfish のサイトにアクセス。

Superfish のサイト

タブの「Download & Support」をクリックし、「Superfish-1.4.8.zip(2009年9月時点のバージョン)」のリンクをクリックしてアーカイブをダウンロード。

Superfish のダウンロード

2.Superfish のアップロード

アーカイブを展開し、superfish-1.4.8 のフォルダ名を superfish にリネームして、フォルダごとブログディレクトリにアップロード。

3.head 要素の修正

head 要素のあるテンプレートに下記を追加します。MT4の既定のブログであれば、「HTMLヘッダー」テンプレートモジュール、当サイト配布のテンプレートであれば「ヘッダー」テンプレートモジュールが該当します。

<link rel="stylesheet" type="text/css" media="screen" href="<mt:BlogURL />superfish/css/superfish.css" />
<script type="text/javascript" src="<mt:BlogURL />superfish/js/jquery-1.2.6.min.js"></script>
<script type="text/javascript" src="<mt:BlogURL />superfish/js/hoverIntent.js"></script>
<script type="text/javascript" src="<mt:BlogURL />superfish/js/superfish.js"></script>
<script type="text/javascript" src="<mt:BlogURL />superfish/js/supersubs.js"></script>
<script type="text/javascript">
    $(document).ready(function(){
        $("ul.sf-menu").supersubs({
            minWidth:    12,   // minimum width of sub-menus in em units
            maxWidth:    27,   // maximum width of sub-menus in em units
            extraWidth:  1     // extra width can ensure lines don't sometimes turn over
                         // due to slight rounding differences and font-family
        }).superfish();  // call supersubs first, then superfish, so that subs are
                         // not display:none when measuring. Call before initialising
                         // containing tabs for same reason.
    });
</script>

script 要素内の「ul.sf-menu」が、3項の一番外側の ul 要素の class 属性値になります。また、

  • minWidth:サブメニューの最小幅のem値
  • maxWidth:サブメニューの最大幅のem値
  • extraWidth:折りかえらないための設定(詳細は未確認)

となっています。

3.ドロップダウンメニューの追加

サブカテゴリリストを利用したドロップダウンメニュー(青色)を、ブログヘッダーの下に設定します。以下はサンプルで設定したものと同じものです。当サイト配布のテンプレートであれば「ヘッダー」テンプレートモジュールに設定します。

<div id="header">
<h1 id="blog-name"><a href="<mt:blogURL />" accesskey="1"><mt:blogName encode_html="1" /></a></h1>
<mt:if tag="BlogDescription"><p class="blog-description"><mt:blogDescription encode_html="1" /></p></mt:if>
</div>
 
<mt:ifArchiveTypeEnabled archive_type="Category">
<mt:topLevelCategories>
  <mt:subCatIsFirst>
  <ul<mt:hasNoParentCategory> id="navi" class="sf-menu" style="width:800px"</mt:hasNoParentCategory>>
  </mt:subCatIsFirst>
    <mt:if tag="CategoryCount">
    <li><a href="<mt:categoryArchiveLink />" title="<mt:categoryDescription />"><mt:categoryLabel /></a>
    <mt:else>
    <li><a href="#"><mt:categoryLabel /></a>
  </mt:if>
    <mt:subCatsRecurse />
    </li>
    <mt:subCatIsLast>
  </ul>
    </mt:subCatIsLast>
  </mt:topLevelCategories>
</mt:ifArchiveTypeEnabled>

グローバルナビゲーションを手動で設定する場合は、一番外側の ul 要素に以下の class 要素を付与してください。配下の要素には何も設定する必要はありません。

<ul class="sf-menu">
Comments [2] | Trackbacks [0]
2008年8月11日

Accordion で特定のメニューをデフォルト表示する

August 11,2008 1:55 AM
Tag:[, ]
Permalink

先日紹介した「Accordion によるサイドメニューの折りたたみ」で、特定のメニューを最初から表示させておくためのカスタマイズです。

1.loadAccordions の修正(1ヶ所だけ表示)

Accordion によるサイドメニューの折りたたみ」での loadAccordions の設定は次のようになっています。

function loadAccordions() {
    var leftAccordion = new accordion('links-left');
    var rightAccordion = new accordion('links-right');
}

例えば、左サイドバーの「最近のブログ記事」をデフォルトで表示したい場合、この関数に次の1行を追加します。

function loadAccordions() {
    var leftAccordion = new accordion('links-left');
    var rightAccordion = new accordion('links-right');
    leftAccordion.activate($$('#links-left .accordion_toggle')[0]);
}

leftAccordion は左サイドバー用の変数、#links-left .accordion_toggle は、左サイドバーの id 属性と Accordion に登録しているメニュータイトルの class 属性値、[0] は Accordion に登録しているメニューの順番です(0から開始)。「最近のコメント」を開きたい場合は [1] にします。

右サイドバーの「タグクラウド」を表示させるには次のようにします。

function loadAccordions() {
    var leftAccordion = new accordion('links-left');
    var rightAccordion = new accordion('links-right');
    rightAccordion.activate($$('#links-right .accordion_toggle')[1]);
}

2.loadAccordions の修正(2ヶ所表示)

左サイドバーと右サイドバーのメニューを同時に表示したい場合は次のように2行記述します。

function loadAccordions() {
    var leftAccordion = new accordion('links-left');
    var rightAccordion = new accordion('links-right');
    leftAccordion.activate($$('#links-left .accordion_toggle')[0]);
    rightAccordion.activate($$('#links-right .accordion_toggle')[1]);
}

なお、同じ変数(leftAccordion または rightAccordion)の中で2つ以上のメニューを同時にデフォルト表示することはできないようです。

3.表示メニューのスタイル

表示されているメニューのスタイルは、次のセレクタで制御できます。

.accordion_toggle_active {}

4.ページ別に表示するメニューを変更する

例として、Movable Type の場合であれば、ヘッダーに次のような制御を組み込めば、表示するメニューを変更することができます。

function loadAccordions() {
    var leftAccordion = new accordion('links-left');
    var rightAccordion = new accordion('links-right');
<mt:if name="category_archive">
    leftAccordion.activate($$('#links-left .accordion_toggle')[0]);
</mt:if>
<mt:if name="entry_archive">
    rightAccordion.activate($$('#links-right .accordion_toggle')[1]);
</mt:if>
}

name モディファイアの値は「予約変数一覧 for Movable Type 4.2」を参考にしてください。

この方法を用いれば、制御する変数によって色々な組み合わせが可能です。

Comments [0] | Trackbacks [0]
2008年8月 7日

「JavaScript で文字をトリミングする(改善版)」バージョンアップ

August 7,2008 12:03 AM
Tag:[, ]
Permalink

JavaScript で文字をトリミングするスクリプトをバージョンアップしました。

JavaScript で文字をトリミングする(改善版)

具体的には、feedburner のバズブーストのようなマークアップ(下)で、記事タイトル部分をトリミングできるようにしました。

下の例であれば、記事タイトルの親要素(span)の class 属性値 headline と、記事タイトルの要素(a)、そしてトリミング文字数を指定すれば、記事タイトルを指定した文字数でトリミングできます。

<ul>
  <li>
    <span class="headline">
      <a href="http://~">記事タイトル1</a>
    </span>
    <p class="date">2008/8/03</p>
    <div>記事タイトル1の概要</div>
  </li>
  <li>
    <span class="headline">
      <a href="http://~">記事タイトル2</a>
    </span>
    <p class="date">2008/8/02</p>
    <div>記事タイトル2の概要</div>
  </li>
  <li>
    <span class="headline">
      <a href="http://~">記事タイトル3</a>
    </span>
    <p class="date">2008/8/01</p>
    <div>記事タイトル3の概要</div>
  </li>
</ul>

設定の詳細については「JavaScript で文字をトリミングする(改善版)」をご覧ください。

Comments [0] | Trackbacks [0]
2007年12月28日

dtree のサブカテゴリーリストにブログ記事タイトルを表示する for Movable Type

以前ご紹介した、「dTree によるサブカテゴリーリスト for Movable Type」で、ブログ記事タイトルを表示するカスタマイズをご紹介します。

dTree とは、エクスプローラー風のツリー表示用スクリプトです。下記のサンプルで動作をご確認ください。

サンプル

本エントリーのカスタマイズを行うことで、下のスクリーンショットのように、各カテゴリー配下に属するブログ記事タイトルを表示させることができます。

dTreeにブログ記事タイトルを表示

以下、サブカテゴリーリストにブログ記事タイトルを表示するカスタマイズです。なお、この記事の5項の設定を行う前に、「dTree によるサブカテゴリーリスト for Movable Type」の4項までを設定しておいてください。

5.dTree サブカテゴリーリスト表示用タグ設定

テンプレートで、サブカテゴリーリストを表示したい位置に下記のタグを設定してください。

表示用タグは PHP 版と JavaScript 版、MTタグ版を用意しました。表示される結果はどれも同じです。

5.1 PHP版

このタグを設定する場合、PHP化を行っていることが前提です。

<script type="text/javascript">
d = new dTree('d');
d.config.useCookies=false;
d.add(0, -1,'SubCategories','javascript: void(0);');
<?php $cat_number = 0; $level = 0; $tree = array(); ?>
<MTTopLevelCategories>
<?php $tree[$level] = ++$cat_number; if(!$level) { ?>
    d.add(<?php echo $cat_number ?>, 0,'<$MTCategoryLabel encode_php="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
<?php } else { if(!$tree[$level - 1]) { ?>
    d.add(<?php echo $cat_number ?>, 1,'<$MTCategoryLabel encode_php="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
<?php } else { ?>
    d.add(<?php echo $cat_number ?>, <?php echo $tree[$level - 1] ?>,'<$MTCategoryLabel encode_php="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
<?php }} ?>
<MTEntries>
<MTEntriesHeader>
<?php $level++; ?>
</MTEntriesHeader>
<?php $cat_number++; ?>
  d.add(<?php echo $cat_number ?>, <?php echo $tree[$level - 1] ?>,'<$MTEntryTitle encode_php="1"$>','<$MTEntryPermalink$>');
<MTEntriesFooter>
<?php $level--; ?>
</MTEntriesFooter>
</MTEntries>
<?php $level++; ?>
<MTSubCatsRecurse>
<?php $level--; ?>
</MTTopLevelCategories>
document.write(d);
</script>
<p style="text-align:center"><a href="javascript: d.openAll();">open all</a> | <a href="javascript: d.closeAll();">close all</a></p>

5.2 JavaScript 版

<script type="text/javascript">
d = new dTree('d');
d.config.useCookies=false;
d.add(0, -1, 'SubCategories','javascript: void(0);');
var cat_number = 0;
var level = 0;
var link = new Array();
<MTTopLevelCategories>
link[level] = ++cat_number;
if(!level) {
    d.add(cat_number, 0,'<$MTCategoryLabel encode_js="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
} else {
    if(!link[level - 1]) {
        d.add(cat_number, 1,'<$MTCategoryLabel encode_js="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
    } else {
        d.add(cat_number, link[level - 1],'<$MTCategoryLabel encode_js="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
    }
}
<MTEntries>
<MTEntriesHeader>
level++;
</MTEntriesHeader>
cat_number++;
  d.add(cat_number, link[level - 1],'<$MTEntryTitle encode_js="1"$>','<$MTEntryPermalink$>');
<MTEntriesFooter>
level--;
</MTEntriesFooter>
</MTEntries>
level++;
<MTSubCatsRecurse>
level--;
</MTTopLevelCategories>
document.write(d);
</script>
<p style="text-align:center"><a href="javascript: d.openAll();">open all</a> | <a href="javascript: d.closeAll();">close all</a></p>

5.3 テンプレートタグ版(MT4.1 以上のみ対応)

<script type="text/javascript">
d = new dTree('d');
d.config.useCookies=false;
d.add(0, -1,'Categories','javascript: void(0);');
<$mt:setvar name="cat_number" value="1"$>
<$mt:setvar name="level" value="1"$>
<MTTopLevelCategories>
<$mt:setvar name="cat_number" op="++"$>
<$mt:setvar name="tree[$level]" value="$cat_number"$>
<mt:if name="level" eq="1">
  d.add(<$mt:getvar name="cat_number" op="--"$>, 0,'<$MTCategoryLabel escape="html"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
<mt:else>
  d.add(<$mt:getvar name="cat_number" op="--"$>, <$mt:setvar name="tmp" value="$level"$><$mt:setvar name="tmp" op="--"$><$mt:getvar name="tree[$tmp]" op="--"$>,'<$MTCategoryLabel escape="html"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
</mt:if>
<MTEntries>
<MTEntriesHeader>
<$mt:setvar name="level" op="++"$>
</MTEntriesHeader>
<$mt:setvar name="cat_number" op="++"$>
  d.add(<$mt:getvar name="cat_number" op="--"$>, <$mt:setvar name="tmp" value="$level"$><$mt:setvar name="tmp" op="--"$><$mt:getvar name="tree[$tmp]" op="--"$>,'<$MTEntryTitle escape="html"$>','<$MTEntryPermalink$>');
<MTEntriesFooter>
<$mt:setvar name="level" op="--"$>
</MTEntriesFooter>
</MTEntries>
<$mt:setvar name="level" op="++"$>
<$MTSubCatsRecurse$>
<$mt:setvar name="level" op="--"$>
</MTTopLevelCategories>
document.write(d);
</script>
<p style="text-align:center"><a href="javascript: d.openAll();">open all</a> | <a href="javascript: d.closeAll();">close all</a></p>

以上です。

2007.12.28
MT3.x でパーマリンクが正常に生成されない不具合を修正しました(MTEntryPermaLink を MTEntryPermalink に修正)。

Comments [5] | Trackbacks [0]
2007年11月15日

Parallax Backgrounds で背景画像のスクロール速度を変える

November 15,2007 12:33 AM
Tag:[]
Permalink

背景画像のスクロール速度を変えることで、コンテンツと背景画像で遠近感を演出することができるスクリプト「Parallax Backgrounds」を紹介します。

Parallax Backgrounds

公式サイトのサンプルでは、スピードが異なる2つの背景画像を組み合わせているので、やや奇抜な印象を受けますが、背景を遠方として捉えたイメージで作り直したサンプル(単に雲を除いただけ)をご覧頂ければ、シンプルな遠近感の動きを楽しめます。

サンプル

サンプル途中にある引用(blockquote)部分は、横スクロールで背景画像のスクロール速度が変わります。

以下、サンプルを例に、

  • ひとつの背景画像を縦スクロール
  • 複数の背景画像を縦スクロール
  • ひとつの背景画像を横スクロール(blockquote内)

の3通りについて設定方法を説明します。

1.ひとつの背景画像を縦スクロール

ひとつの背景画像をスクロールする場合は次のように設定します。

1.1 (X)HTML

背景を表示する要素に ground という id 属性値を付与。属性値の名称は何でも構いませんが、後で設定する CSS と JavaScript で同じ名称にする必要があります。

<body id="ground">
  :
</body>

1.2 CSS

1.1で設定した id 属性に下記のスタイルを与えます。

#ground {
    background-image: url(bg-green.gif);
    background-repeat: repeat;
    background-attachment: fixed;
}

1.3 JavaScript

下記のスクリプトを script 要素で括り、head 終了タグの直前に配置します(外部ファイルにしても構いません)。

function calcParallax(tileheight, speedratio, scrollposition) {
  //    by Brett Taylor http://inner.geek.nz/
  //    originally published at http://inner.geek.nz/javascript/parallax/
  //    usable under terms of CC-BY 3.0 licence
  //    http://creativecommons.org/licenses/by/3.0/
  return ((tileheight) - (Math.floor(scrollposition / speedratio) % (tileheight+1)));
}
window.onload = function() {
    window.onscroll = function() {
        var posY = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : window.pageYOffset;
  
        var ground = document.getElementById('ground');
        var groundparallax = calcParallax(53, 8, posY);
        ground.style.backgroundPosition = "0 " + groundparallax + "px"; 
    }
}

calcParallax(tileheight, speedratio, scrollposition) に設定するパラメータの内容は下の通りです。

tileheight:背景画像の高さ
speedratio:スクロール速度、1が通常スクロールで、1より大きいと遅くなり、小さくすると早くなる
scrollposition:スクロール方向

サンプルでは背景画像の高さ53px、スクロール速度8、スクロール方向はY(縦)です。
背景画像の高さは利用する画像に依存し、スクロール方向はスクリプト内で取得した変数をそのまま設定するだけですので、実際に値を変更できるのはスクロール速度のみです。

2.複数の背景画像を縦スクロール

2.1 (X)HTML

背景を表示する要素に ground という id 属性値に加え、clouds という id 属性値を付与します。

<body id="ground">
  <div id="clouds">
  :
  </div>
</body>

2.2 CSS

2.1で設定した id 属性にそれぞれ下記のスタイルを与えます。

#ground {
    background-image: url(bg-green.gif);
    background-repeat: repeat;
    background-attachment: fixed;
}
#clouds {
    background-image: url(clouds.png);
    background-repeat: repeat;
    background-attachment: fixed;
}
* html #clouds {
  /* because IE6 can't do transparent PNGs for backgrounds */
  background-image: url(clouds.gif);  
}

2.3 JavaScript

下記のスクリプトを script 要素で括り、head 終了タグの直前に配置します(外部ファイルにしても構いません)。

function calcParallax(tileheight, speedratio, scrollposition) {
  //    by Brett Taylor http://inner.geek.nz/
  //    originally published at http://inner.geek.nz/javascript/parallax/
  //    usable under terms of CC-BY 3.0 licence
  //    http://creativecommons.org/licenses/by/3.0/
  return ((tileheight) - (Math.floor(scrollposition / speedratio) % (tileheight+1)));
}
window.onload = function() {
  window.onscroll = function() {
    var posX = (document.documentElement.scrollLeft) ? document.documentElement.scrollLeft : window.pageXOffset;
    var posY = (document.documentElement.scrollTop) ? document.documentElement.scrollTop : window.pageYOffset;
 
    var ground = document.getElementById('ground');
    var groundparallax = calcParallax(53, 8, posY);
    ground.style.backgroundPosition = "0 " + groundparallax + "px"; 
 
    var clouds = document.getElementById('clouds');
    var cloudsparallax = calcParallax(400, .5, posY);
    clouds.style.backgroundPosition = "0 " + cloudsparallax + "px"; 
  }
}

お分かりのように、複数の背景を制御する場合は、1.3項の後半に現われるソースコードを、変数名を変更して必要分作成しています。

3.ひとつの背景画像を横スクロール(blockquote内)

3.1 (X)HTML

以下のように blockquote 属性に id 属性値を設定します。またスクロール設定のための class 属性も与えています。

<blockquote id="javascriptcode" class="scrollcode">~</blockquote>

3.2 CSS

.scrollcode {
    overflow:auto;
    white-space:nowrap;
}
#javascriptcode {
    background-image: url(bg-greenwhite.gif);
    background-repeat: repeat;
}

3.3 JavaScript

下記のスクリプトを script 要素で括り、head 終了タグの直前に配置します(外部ファイルにしても構いません)。

function calcParallax(tileheight, speedratio, scrollposition) {
  //    by Brett Taylor http://inner.geek.nz/
  //    originally published at http://inner.geek.nz/javascript/parallax/
  //    usable under terms of CC-BY 3.0 licence
  //    http://creativecommons.org/licenses/by/3.0/
  return ((tileheight) - (Math.floor(scrollposition / speedratio) % (tileheight+1)));
}
window.onload = function() {
  document.getElementById('javascriptcode').onscroll = function() {
    var posX = (this.scrollLeft) ? this.scrollLeft : this.pageXOffset;
    var j = calcParallax(53, 16, posX);
    console.log('scroll js: '+ j);
    document.getElementById('javascriptcode').style.backgroundPosition = j + "px 0";
  } 
}

1.3や2.3と異なるのは、window.onscroll プロパティではなく、取得 id 属性のonscroll プロパティで動作している点です。

Comments [0] | Trackbacks [0]
2007年9月13日

prototype.js と pngfix.js の競合を解消する

September 13,2007 2:18 AM
Tag:[]
Permalink

prototype.js の Ajax.Request と pngfix.js の処理が競合(あるいは干渉)して、pngfix.js 側の処理が正常に行われなくなるという問題の解消策です。

この問題の発端は、pngfix.js を利用した「Movable Type 4 の透過 PNG ロゴを IE6 以下のブラウザで透過する」と、prototype.js を利用した「BlogPeople 等のリンクリストによる表示の遅延を解消する(その2:Ajax編)」のカスタマイズを同時に行うと「PNGが透過されません」というご質問を頂いたことによるもので、本エントリーにて回答致します。

両スクリプトの読み込み順序を入れ替える実験を行ったところ、

<!--[if lt IE 7.]>
<script defer type="text/javascript" src="http://user-domain/pngfix.js"></script>
<![endif]-->

をページの一番最後(body 終了タグの直後等)に配置すれば、PNGが透過されるようになりました。

ただしタイミングによってはステータスバーに、

(残り1項目)ページ http://~ を開いています...

という表示が継続してしまうので、完全な解決には至っていないかもしれません。

Comments [2] | Trackbacks [1]
2007年9月 4日

JavaScript の for 文のパフォーマンスを改善する

September 4,2007 2:28 AM
Tag:[, ]
Permalink

すでにご存知の方も多いと思いますが、for 文のパフォーマンス改善テクニックです。

変更前

for (i = 0; i < elements.length; i++) {
       :
}

変更後

for (i = 0, len = elements.length; i < len; i++) {
       :
}

変更前は、ループ処理の i < elements.length つまり length プロパティの参照が毎回行われます。この、いわゆる「ドットつき比較計算」はコストが高い、ということです。

変更後は初期化式で elements.length を保持しているので、ループ回数にかかわらず参照は1回だけになります。

ただし、ネイティブな配列の場合は変更前後でそれほど差はないようで、NodeList オブジェクト(よくみかける document.getElementsByTagName() 等)では、length プロパティの参照回数のインパクトが大きいようです。ブラウザによっても差があるようです。

参考記事:

Comments [0] | Trackbacks [0]
2007年8月23日

Google マップの貼り付け用 HTML を valid にする

August 23,2007 1:23 AM
Tag:[, ]
Permalink

Google マップをブログ等に貼り付ける「埋め込み HTML」の提供が開始されましたが、その HTML を valid にするスクリプトを公開します。

1.埋め込み HTML の利用方法

埋め込み HTML 自体の利用方法ですが、まず Google マップで任意の地図を表示させ、「このページへのリンク」をクリックします(スクリーンショット右上)。

リンクをクリックすると、HTMLコードがすぐ下に表示されます(下)ので、

「HTML を貼り付けてサイトに地図を埋め込みます」の下に表示されている、

<iframe width="425" height="350" ~

のコードをマウスコピーして、それをブログの投稿画面に貼り付ければOKです。

2.問題点

埋め込み HTML で使われている iframe タグは HTML4.01 Strict・XHTML1.0 Strict では未定義、XHTML1.1 では廃止されていることと、以下に示す問題のため、この HTML をブログに埋め込むと not Valid になる可能性があります。

  • & が実体参照(&amp;)されていない
  • br 要素の"/"の前に空白がない

3.変換スクリプト

ということで、埋め込み用 HTML を valid にするスクリプトを作成してみました。

上のテキストエリアに Google マップ埋め込み用 HTML を貼り付けて、 object または iframe + object のボタンをクリックすると下のテキストエリアに valid な HTML が表示されますので、それをブログ等に貼り付けてください。

object 要素だけではどうもクロスブラウザにならないようです(IE で正常に表示されない等)ので、現状では iframe + object(条件付きコメント利用)を推奨します。


Windows XP + IE6/IE7/FireFox2/Opera9/Safari3で動作確認し、Markup Validation Service で valid になることを確認していますが、不具合等ございましたらご連絡ください。

参考までに、このスクリプトでは下記の変換を行っています。

  • iframe 要素を object 要素に変更
  • src 属性を data 属性に変更
  • object 要素で不要な属性(frameborder/scrolling/marginheight/marginwidth)を削除
  • object 要素に type="text/html" を追加
  • object 要素の「要素の内容」に「non data」を挿入
  • & を &amp; に置換(object要素内のみ)
  • br 要素に半角空白を付与

4.関連・参考

2008.09.29 Google の出力コードが変更されていたので、ツールを修正しました(frameborder/scrolling/marginheight/marginwidthが削除されない不具合の対処、&の変換削除など)。 2009.02.07 IEでGoogle マップ以降が表示されなくなる不具合を修正しました。
Comments [7] | Trackbacks [11]
2007年8月14日

Movable Type 4 の透過 PNG ロゴを IE6 以下のブラウザで透過する

August 14,2007 1:55 AM
Tag:[, , ]
Permalink

デフォルトテンプレートで新しく表示されている Movable Type 4 のロゴは透過PNGのため、IE6以下のブラウザでは透過されず、2色で表示されてしまいます(下)。

Movable Type 4 ロゴ

ここでは pngfix.js を利用して透過する方法を紹介します。

他にも透過PNGライブラリは色々出回ってます。

1.スクリプトのダウンロード・アップロード

PNG in Windows IE: How To Use の中間辺りにある pngfix.js のリンクをクリックして、pngfix.js をダウンロード。
ダウンロードした pngfix.js をサーバのブログ・ディレクトリ(index.html があるディレクトリ)にアップロード。

2.テンプレート修正

ブログ管理ページより「デザイン」→「テンプレートモジュール」→「ヘッダ」を選択し、head 終了タグの直前に下記を追加。
MT3以前のテンプレート構成を利用している場合(で新しいロゴを使っている場合)は、各テンプレートの head 終了タグの前に下記を追加。

<!--[if lt IE 7.]>
<script defer type="text/javascript" src="<$MTBlogURL$>pngfix.js"></script>
<![endif]-->

これで再構築をすれば下記のように透過されます。この設定は他の透過PNGにも有効です。

Movable Type 4 ロゴ(修正後)

Comments [2] | Trackbacks [1]
2007年6月26日

ツリー表示 JavaScript 「dTree」詳解

June 26,2007 2:27 AM
Tag:[, ]
Permalink

dTreeのサンプルへ昨日のエントリー「dTree によるサブカテゴリーリスト for Movable Type」でご紹介した dTree の詳細について、本エントリーにて紹介します。例えば、設定によってはエクスプローラー風以外のツリー表示も可能です。

内容は概ね配布サイトの説明を訳したものですが、一部、使用した観点でも記しています。

1.コンフィグレーション

下記の項目を事前に設定しておくことで、dTree の動作や表示をカスタマイズすることができます(具体的な設定の流れは3項参照)。いくつかの項目については配布元の Example のページで確認できます。

変数名デフォルト値説明
targetStringtrue全てのノードの target 属性
folderLinksBooleantruetrue の場合、フォルダ名が通常のリンクになり、false の場合は(フォルダのみ)折りたたみ用リンクになります。
useSelectionBooleantruetrue の場合、選択したノードがハイライト表示されます。
useCookiesBooleantrueツリーの状態保持のためにクッキーを使用
useLinesBooleantruetrue の場合、ツリーを表示します。
useIconsBooleantruetrue の場合、アイコンを描画します。false の場合、「+」と「-」のシンプルなアイコンだけが表示されます。ルートノードのアイコンを非表示にしたい場合はこの設定がお勧め。
useStatusTextBooleanfalsetrue の場合、ステータスバーにURLの代わりにカテゴリー名を表示します(ブラウザ依存)
closeSameLevelBooleanfalsetrue の場合、あるノードを開いた時に、他の同一階層ノードを閉じます。また、openAll() と closeAll() は機能しません。
inOrderBooleanfalse親ノードが常に子ノードより先に add される場合、ツリーのスピードアップをする(注:動作未確認です)

設定例:

mytree.config.target = "mytarget";
mytree.config.useCookies = true;

2.API

add()

概要
ツリーにノードを追加します。ツリーを描画する前に起動してください。id, pid と name は必須です。
パラメータ
名前説明
idNumberツリーの中でユニークな番号
pidNumber参照する親ノード番号。ルート番号は「-1」。
nameStringノード名
urlStringノードの URL
titleStringノードの title 属性
targetStringノードの target 属性
iconStringアイコンを使用する場合の画像ファイル名。設定しない場合はデフォルト画像が使用される。
iconOpenStringアイコン(オープンした時)を使用する場合の画像ファイル名。設定しない場合はデフォルト画像が使用される。
openBooleanノードを開いて表示
例:
mytree.add(1, 0, 'My node', 'node.html', 'node title', 'mainframe', 'img/musicfolder.gif');

openAll()

概要
全てのノードを開きます。ツリー表示前後どちらでも起動できます。
例:
mytree.openAll();

closeAll()

概要
全てのノードを閉じます。ツリー表示前後どちらでも起動できます。
例:
mytree.closeAll();

openTo()

概要
指定したノードを開くことができます。ツリーが表示された後で起動してください。
パラメータ
名前説明
idNumberノード番号
selectBoolean開いたノードをハイライト表示する
例:
mytree.openTo(4, true);

3.サンプルコード

a = new dTree('a');
a.config.useCookies=false;
a.add(0,-1,'Tree example','javascript: void(0);');
a.add(1, 0,'Node 1','javascript:void(0);');
a.add(2, 1,'Node 2','javascript:void(0);');
a.add(3, 0,'Node 3','javascript:void(0);');
a.add(4, 1,'Node 4','javascript:void(0);');
a.add(5, 2,'Node 5','javascript:void(0);');
a.add(6, 4,'Node 6','javascript:void(0);');
a.add(7, 6,'Node 7','javascript:void(0);');
a.add(8, 6,'Node 8','javascript:void(0);');
a.add(9, 4,'Node 9','javascript:void(0);');
a.add(10, 3,'Node 10','javascript:void(0);');
a.add(11, 1,'Node 11','javascript:void(0);');
a.add(12, 1,'Node 12','javascript:void(0);');
a.add(13, 8,'Node 13','javascript:void(0);');
a.add(14, 11,'Node 14','javascript:void(0);');
document.write(a);

1行目:dTree オブジェクトを生成します。この行は必須です。

a = new dTree('a');

2行目:コンフィグレーションの設定です。ここではクッキーを有効にしています。

a.config.useCookies=false;

3行目:ルートノードの設定です。この行も必須のようです。

a.add(0,-1,'Tree example','javascript: void(0);');

4行目:ノード追加です。パラメータの数字は、自ノード番号「1」で、ルートノード(0)に属することを意味します。

a.add(1, 0,'Node 1','javascript:void(0);');

もうひとつ例を挙げると、16行目の

a.add(13, 8,'Node 13','javascript:void(0);');

は、8番のノードに属することを指しています。

18行目:ツリーを表示します。document.write 以外に innerHTML もOKでした。

document.write(a);

4.CSS

設定されているスタイルは下記の通りです。

.dtree {}
.dtree img {}
.dtree a {}
.dtree a.node, .dtree a.nodeSel {}
.dtree a.node:hover, .dtree a.nodeSel:hover {}
.dtree a.nodeSel {}
.dtree .clip {}
Comments [3] | Trackbacks [0]
2007年6月25日

dTree によるサブカテゴリーリスト for Movable Type

dTreeのサンプルへdTree というエクスプローラー風のツリー表示スクリプトを利用した、Movable Type のサブカテゴリーリストのツリー化カスタマイズをご紹介します。

表示は左のスクリーンショットのようになり、「+」「-」をクリックするとツリーを開閉することができます。また、カテゴリー名をクリックすると該当のカテゴリーページにジャンプします。一番下の「open all」「close all」をクリックすると全ツリーの一括開閉もできます。

動作についてはサンプルをご利用ください。

後で気がつきましたが、「MovableType備忘録」さんでも同じようなカスタマイズを公開されています。

以下、カスタマイズ方法です。

1.スクリプトのダウンロード

Destroydrop » Javascripts » Tree の右上にある、Download の dtree.zip のリンクをクリックしてダウンロード。

dTree

2.スクリプトのアップロード

アーカイブを解凍した中にある下記のファイルまたはディレクトリを index.html と同じディレクトリにアップロード(他は使いません)。

/img
dtree.css
dtree.js

3.画像ファイルパスの修正

dtree.js を任意のエディタで開き、下記の

this.icon = {
    root        : 'img/base.gif',
    folder      : 'img/folder.gif',
    folderOpen  : 'img/folderopen.gif',
    node        : 'img/page.gif',
    empty       : 'img/empty.gif',
    line        : 'img/line.gif',
    join        : 'img/join.gif',
    joinBottom  : 'img/joinbottom.gif',
    plus        : 'img/plus.gif',
    plusBottom  : 'img/plusbottom.gif',
    minus       : 'img/minus.gif',
    minusBottom : 'img/minusbottom.gif',
    nlPlus      : 'img/nolines_plus.gif',
    nlMinus     : 'img/nolines_minus.gif'
};

を下のようにご自身のドメイン(ブログのURL)を追加します。

this.icon = {
    root        : 'http://user-domain/img/base.gif',
    folder      : 'http://user-domain/img/folder.gif',
    folderOpen  : 'http://user-domain/img/folderopen.gif',
    node        : 'http://user-domain/img/page.gif',
    empty       : 'http://user-domain/img/empty.gif',
    line        : 'http://user-domain/img/line.gif',
    join        : 'http://user-domain/img/join.gif',
    joinBottom  : 'http://user-domain/img/joinbottom.gif',
    plus        : 'http://user-domain/img/plus.gif',
    plusBottom  : 'http://user-domain/img/plusbottom.gif',
    minus       : 'http://user-domain/img/minus.gif',
    minusBottom : 'http://user-domain/img/minusbottom.gif',
    nlPlus      : 'http://user-domain/img/nolines_plus.gif',
    nlMinus     : 'http://user-domain/img/nolines_minus.gif'
};

4.script 要素追加

dTree を表示したいテンプレートに、下記の link 要素と script 要素を追加します。

<link rel="stylesheet" href="<$MTBlogURL$>dtree.css" type="text/css" />
<script type="text/javascript" src="<$MTBlogURL$>dtree.js"></script>

5.dTree サブカテゴリーリスト表示用タグ設定

テンプレートで、サブカテゴリーリストを表示したい位置に下記のタグを設定してください。

表示用タグは PHP 版と JavaScript 版を用意しました。表示される結果はどちらも同じですが、PHP 版の方がページのファイルサイズを抑えることができます。

5.1 PHP版

このタグを設定する場合、PHP化を行っていることが前提です。

<script type="text/javascript">
d = new dTree('d');
d.config.useCookies=false;
d.add(0, -1,'SubCategories','javascript: void(0);');
<?php $a = 0; $b = 0; $link = array(); ?>
<MTTopLevelCategories>
<?php $link[$b] = ++$a; if(!$b) { ?>
    d.add(<?php echo $a ?>, 0,'<$MTCategoryLabel encode_php="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
<?php } else { if(!$link[$b - 1]) { ?>
    d.add(<?php echo $a ?>, 1,'<$MTCategoryLabel encode_php="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
<?php } else { ?>
    d.add(<?php echo $a ?>, <?php echo $link[$b - 1] ?>,'<$MTCategoryLabel encode_php="1"$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
<?php }} $b++; ?>
<MTSubCatsRecurse max_depth="3">
<?php $b--; ?>
</MTTopLevelCategories>
document.write(d);
</script>
<p style="text-align:center"><a href="javascript: d.openAll();">open all</a> | <a href="javascript: d.closeAll();">close all</a></p>

5.2 JavaScript 版

こちらは JavaScript 版です。

<script type="text/javascript">
d = new dTree('d');
d.config.useCookies=false;
d.add(0, -1, 'SubCategories','javascript: void(0);');
var a = 0;
var b = 0;
var link = new Array();
<MTTopLevelCategories>
link[b] = ++a;
if(!b) {
    d.add(a, 0,'<$MTCategoryLabel$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
} else {
    if(!link[b - 1]) {
        d.add(a, 1,'<$MTCategoryLabel$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
    } else {
        d.add(a, link[b - 1],'<$MTCategoryLabel$>','<MTIfNonZero tag="MTCategoryCount"><$MTCategoryArchiveLink$><MTElse>javascript: void(0);</MTElse></MTIfNonZero>');
    }
}
b++;
<MTSubCatsRecurse max_depth="3">
b--;
</MTTopLevelCategories>
document.write(d);
</script>
<p style="text-align:center"><a href="javascript: d.openAll();">open all</a> | <a href="javascript: d.closeAll();">close all</a></p>

以上です。

関連記事:

2007.06.26
3項を追加しました。

2007.12.01
PHP版タグの MTCategoryLabel タグに encode_php="1" を追加しました。

2007.12.18
MTSubCategories タグを MTTopLevelCategories タグに変更しました。

Comments [35] | Trackbacks [1]
2007年5月24日

HighSlide JS と prototype.js の競合を解消する

May 24,2007 1:50 AM
Tag:[, ]
Permalink

サムネイル画像を拡大させる HighSlide JS(関連記事「Highslide JS でサムネイル画像を拡大表示する」)には、

  • ブラウザのウィンドウサイズに収まるように拡大(右下のアイコンをクリックすると 100% 表示)

という機能があり、この場合、拡大した画像の右下に最大化するアイコンが表示されます。

拡大した画像

このアイコンをクリックすると、ブラウザのウィンドウサイズに関わらず画像が最大化されます。最大化された画像は最大化前と同じようにドラッグや縮小することができます。

1.問題点

この最大化をすると別のページにジャンプをして元画像が表示されてしまうケースがあります。

2.原因

Highslide JS と prototype.js を同時に利用している場合、prototype.js が Array に対して拡張を行っているため、Highslide JS で使用している配列が汚染され、

for (var i in array) {
    :
}

の処理で余計なものが含まれてしまうようです。
これが原因で最大化処理に不具合が発生します。

具体的には、highslide.js の下記の部分が汚染されている模様です。

// reposition overlays
for (x in this.overlays) {
        hs.purge(this.overlays[x]);
        this.overlays[x].parentNode.removeChild(this.overlays[x]);
}

3.対処方法

for 文を

for (var i = 0; i  < array.length; i++) {
    :
}

に変更すると解消するらしいので、問題となる処理が含まれる関数のみをオーバーライドしてみました。

まず、下記の内容を丸コピーし、highslide-custom.js という名称で highslide.js と同じディレクトリに保存してください。

HsExpander.prototype.doFullExpand = function () {
    try {
        hs.purge(this.fullExpandIcon);
        this.fullExpandIcon.parentNode.removeChild(this.fullExpandIcon);
        this.focus();
        this.x.min = parseInt(this.wrapper.style.left) - (this.fullExpandWidth - this.content.width) / 2;
        if (this.x.min < hs.marginLeft) this.x.min = hs.marginLeft;        
        this.wrapper.style.left = this.x.min +'px';
        var borderOffset = this.wrapper.offsetWidth - this.content.width;        
        this.content.width = this.fullExpandWidth;
        this.content.height = this.fullExpandHeight;
        this.x.span = this.content.width;
        this.wrapper.style.width = (this.x.span + borderOffset) +'px';
        this.y.span = this.wrapper.offsetHeight - 2 * this.offsetBorderH;
        this.positionOutline(this.x.min, this.y.min, this.x.span, this.y.span);
        // reposition overlays
        for (x = 0; x < this.overlays.length; x++) {
            hs.purge(this.overlays[x]);
            this.overlays[x].parentNode.removeChild(this.overlays[x]);
        }        
        if (hs.showCredits) this.writeCredits();
        this.createCustomOverlays();
        this.redoShowHide();
    } catch (e) {
        window.location.href = hs.expanders[this.key].content.src;
    }
};

そして、ご利用のサーバにアップロードして、テンプレートに下記の青色の行を追加してください。

           :
<script type="text/javascript" src="highslide/highslide.js"></script>
<script type="text/javascript" src="highslide/highslide-custom.js"></script>
           :

この1行は、元の highslide.js を読み込む script 要素の後に記述してください。
また、src 属性部分の記述は例ですので、ご利用になっている highslide を読み込んでいる script 要素の src 属性に合わせてしてください。
例は highslide というディレクトリ配下にある場合を想定しています。

4.注意事項

IE6/iE7 では2回目以降の拡大処理がスムーズに動作しない事象が確認されています(Firefox / Opera は OK)。
またこの対処はサンプルを作って実験したものですので、動作しない場合があるかもしれません。適正な対処方法がありましたらご教示ください。

Comments [2] | Trackbacks [2]
2007年3月30日

HighSlide JS の onclick 属性を JavaScript で登録する

March 30,2007 12:38 AM
Tag:[, ]
Permalink

サムネイルをポップアップ表示する HighSlide JS で onclick 属性および onkeypress 属性を JavaScript で自動的に登録する方法です。
ここでは Movable Type と WordPress プラグインを例に説明します。

1.概略

HighSlide JS を有効にするには、「Highslide JS でサムネイル画像を拡大表示する」の5項で説明した通り、a 要素に class="highslide" に加え onclick="return hs.expand(this)" を設定する必要があります。また配布サイトでは言及されていませんが onclick 属性を設定した場合は onkeypress 属性を同時に設定することがアクセシビリティ上好ましいとされています。

つまり、HighSlide JS に対応させるためには下記の青色部分を記述する必要があります。

<a href="[画像ファイルのURL]" class="highslide" onclick="return hs.expand(this)" onkeypress="return hs.expand(this)">
<img src="[サムネイル画像のURL]" alt="..." />
</a>

が、a 要素に毎回 class 属性、onclick 属性、onkeypress 属性を設定するのは結構面倒ですし、他の画像表示ツールに移行した場合の修正稼動も懸念されます。ということで class 属性のみ設定すれば、イベントハンドラである残りの onclick 属性、onkeypress 属性は JavaScript で設定できるようにします。

当サイトでも、ひとつ前のエントリー「poEDIT の使い方」等、HighSlide JS にはこの方法を適用しています。
動作は Windows XP + IE6/IE7/Firefox2/Opera9 で確認しています。

2.Movable Type の場合

下記のスクリプトをテンプレートの </head> の前に設定するか、外部ファイルとして自身のサーバにアップロードしてください。

<script type="text/javascript">
function addHighSlideAttribute() {
  var isIE = (document.documentElement.getAttribute('style') ==
              document.documentElement.style);
  var anchors = document.getElementById('content').getElementsByTagName('a');
  for (var i = 0, len = anchors.length; i < len; i++) {
    if (anchors[i].className == 'highslide') {
      if (!anchors[i].getAttribute('onclick')) {
        isIE ? anchors[i].setAttribute('onclick', new Function('return hs.expand(this)')) :
               anchors[i].setAttribute('onclick','return hs.expand(this)');
        isIE ? anchors[i].setAttribute('onkeypress', new Function('return hs.expand(this)')) :
               anchors[i].setAttribute('onkeypress','return hs.expand(this)');
      }
    }
  }
}
</script>

外部ファイル(例えば highslide_eh.js)にする場合は先頭と末尾の script タグを除去して、</head> の前に

<script type="text/javascript" src="<$MTBlogURL$>highslide_eh.js"></script>

というようなタグを設定してください。

そしてテンプレートの </body> の直前に下記のタグを追加します。

<script type="text/javascript">
addHighSlideAttribute();
</script>

3.WordPress の場合

下記のプラグインをインストールして、有効化してください。このプラグインと WPJ-Highslide 0.2 を併用すると便利です。

highslide_eh.zip / highslide_eh.lzh

4.参考・関連サイト

Comments [13] | Trackbacks [4]
2007年3月 5日

Slider によるフォントサイズ変更でアクセシビリティを向上させる

March 5,2007 1:35 AM
Tag:[, , ]
Permalink

以前ご紹介した Slider を利用して、ページのフォントサイズを変更するカスタマイズをご紹介します。

下のサンプルをクリックし、ページ左上にある Slider を操作すると、中央カラムおよびサイドバーにある文字のフォントサイズをダイナミックに変更することができます。
Slider は矢印キー・PageUp/PageDown・マウススクロール(これは IE のみ)でも操作可能です。IE より Firefox の方がよりスムーズに動きます。

フォントサイズ変更サンプル

ここでは Movable Type 用公開テンプレートを用いて、フォントサイズ変更用 Slider の設定方法をご紹介します。Slider および本カスタマイズはブログツールやテンプレートに依存するものではありませんので、他のブログツールや異なるテンプレートでも利用可能です。
Slider のダウンロード・インストールについては「Slider の利用方法」の2項をご覧ください。

1.Slider 用ライブラリ・CSSのインクルード

テンプレートの /head の直前に下記のタグを追加します。

<link type="text/css" rel="stylesheet" href="slider/css/bluecurve/bluecurve.css" />
<script type="text/javascript" src="slider/js/range.js"></script>
<script type="text/javascript" src="slider/js/timer.js"></script>
<script type="text/javascript" src="slider/js/slider.js"></script>
<style type="text/css">
.horizontal {
    width: 155px;
    height: 20px;
}
</style>

.horizontal は Slider をサイドバーの幅に合わせるため、slider/css/bluecurve/bluecurve.css の設定を上書きしています。

2.Slider の設定

テンプレートのサイドバー部分に下記のタグを追加します。この部分に Slider が表示されます。

<div class="slider" id="slider-1" tabIndex="1">
<input class="slider-input" id="slider-input-1" name="slider-input-1" />
</div>

3.フォントサイズ用スクリプトの設定

下記のスクリプトをテンプレートの /body の直前に追加します。

<script type="text/javascript">
//<![CDATA[
var s = new Slider(document.getElementById("slider-1"), document.getElementById("slider-input-1"));
s.onchange = function () {
    document.body.style.fontSize = (100 + (s.getValue()*2)) + '%';
};
s.setValue(25);
window.onresize = function () {
    s.recalculate();
};
//]]>
</script>

フォントサイズを決定しているのは、

document.body.style.fontSize = (100 + (s.getValue()*2)) + '%';

の部分で、s.getValue() がスライドバーの移動によって実際に値を取得している部分です。
また、スライドバーのデフォルト位置については、

s.setValue(25);

で設定しています。この両者を変更することで、フォントサイズの増減率やスライドバーのデフォルト位置を変更することができます。色々試してみてください。

4.CSS 修正

スタイルシートで設定している font-size プロパティの値を px 指定から % 指定に変更します。フォントサイズ変更方式については下記の記事を参考にさせて頂きました。ありがとうございました。

Ogawa::Memorandaprototype.jsを用いたフォントサイズ変更スクリプト

以下、サンプルで使用している公開テンプレートにおける変更箇所です。青は追加または変更を示します。.blog セレクタの font-size プロパティは削除してください。
カスタマイズに無関係のプロパティは省略していますので予めご了承ください。

body {
    font-size: 100%;
}
.blog {
    font-size: small;
}
.date { 
    font-size: 55%;
}
.entry {
    font-size: 62%;
}
.entry-header {
    font-size: 93%;
}
.entry-footer {
    font-size: 72%;
}
.sidetitle {
    font-size: 52%;
}
.side {
    font-size: 52%;
}
Comments [0] | Trackbacks [2]
2007年2月19日

コメント投稿時にフォームボタンをグレーアウトする for Movable Type

本サイトで適用している、コメントを投稿時にフォームボタンをグレーアウトするためのカスタマイズです。カスタマイズ方法については以前よりリクエストを頂いておりました。公開が遅くなって申し訳ありません。

コメント投稿時にフォームボタンをグレーアウトする

ここでは Movable Type でのカスタマイズ方法を紹介致します。他のブログツールについては順次公開していきたいと思います。
カスタマイズ元記事は下記です。ありがとうございました。

1.本カスタマイズの機能

  • コメントフォームの「投稿」ボタンクリック時にフォームボタンをグレーアウトにする
  • コメントフォームの「確認」ボタンクリック時はグレーアウトにしない

「確認」ボタンクリック時にグレーアウトしないのは、下記の理由のようにユーザビリティ上好ましくないと思ったためです。

  • 「確認」でグレーアウトした場合、ブラウザの「戻る」でグレーアウトのままになる(投稿不能になる)
  • 「確認」ボタンをクリックした時に「投稿」ボタンを押してしまったと錯覚する可能性がある

以下、カスタマイズ方法です。動作は Windows XP + IE6.0 / IE7.0 / Firefox2 / Opera9 で確認しています。テンプレートは Movable Type デフォルトテンプレートで確認していますが、当サイトの公開テンプレートでも動作します。
またカスタマイズにあたってはテンプレートにできるだけ手を加えないようにしています。

2.JavaScript 外部ファイルの作成

下記の内容を disabledButton.js という名前で保存し、メインページと同じディレクトリにアップロードしてください。

var disabledFlag = 0;
var isIE = (document.documentElement.getAttribute("style") ==
               document.documentElement.style);
function addFormAttribute(form) {
  isIE ? form.setAttribute("onsubmit", new Function("if (this.bakecookie.checked) rememberMe(this);disableSubmit(this);")) :
         form.setAttribute('onsubmit','if (this.bakecookie.checked) rememberMe(this);disableSubmit(this);');
  var elements = form.elements;
  for (var i = 0; i < elements.length; i++) {
    if (elements[i].type == 'submit' && elements[i].getAttribute('name') == 'post') {
      isIE ? elements[i].setAttribute("onclick", new Function("setHiddenValue(this);")) :
             elements[i].setAttribute('onclick','setHiddenValue(this)');
    }
  }
}
function disableSubmit(form) {
  if(!disabledFlag){
    return;
  }
  var elements = form.elements;
  for (var i = 0; i < elements.length; i++) {
    if (elements[i].type == 'submit' || elements[i].type == 'button') {
      elements[i].disabled = true;
    }
  }
}
function setHiddenValue(button) {
  if (button.name) {
    var q = document.createElement('input');
    q.type = 'hidden';
    q.name = button.name;
    q.value = button.value;
    button.form.appendChild(q);
    disabledFlag = 1;
  }
}

3.テンプレート修正

エントリー・アーカイブ/コメント・プレビューの </head> の直前に下記を追加します。

<script type="text/javascript" src="<$MTBlogURL$>disabledButton.js"></script>

また、同じテンプレートの body 要素に下記の青色部分を追加します。

<body class="layout-two-column-right individual-entry-archive" onload="individualArchivesOnLoad(commenter_name);addFormAttribute(document.comments_form);">

addFormAttribute の直前のセミコロン ";" もお忘れなく。

4.注意事項

コメント・プレビュー画面に本カスタマイズを適用する場合、コメント・プレビュー・テンプレートに必ず下記のタグ(青色部分)をフォームに追加してください。これを追加しないとグレーアウトしません。

  :
<p>
   <label for="comment-url">URL:</label>
   <input id="comment-url" name="url" size="30" value="<$MTCommentPreviewURL$>" />
</p>
<p>
   <label for="comment-bake-cookie"><input type="checkbox"
      id="comment-bake-cookie" name="bakecookie" onclick="if (!this.checked) forgetMe(document.comments_form)" value="1" />
      この情報を登録しますか?</label>
</p>
<p id="comments-open-text">
  :

5.補足

グレーアウトする仕組み
「投稿」ボタンのクリックにより onclick イベントハンドラを起動します。ハンドラから起動された setHiddenValue でクリックされたボタンを hidden 型の input 要素として追加します。続いて onsubmitイベントハンドラが起動され、ハンドラから起動された disableSubmit でフォームボタンを disabled にします。
「確認」ボタンクリック時にグレーアウトしない仕組み
setHiddenValue の中で、変数 disabledFlag に 1 を設定し、disableSubmit の処理で、disabledFlag フラグが 1 の場合のみ button 要素を disabled にします(もっと良い実装があると思いますが)。
onsubmit 属性の再書き込み
form 要素の onsubmit 属性を用いて disableSubmit 関数を起動していますが、属性値には "if (this.bakecookie.checked) rememberMe(this)" が元から設定されているため、追加スクリプトで元関数と新たに加えた関数の両方を起動するように上書きしています。
IE の不具合対処
IE では、JavaScript の getAttribute / setAttribute で class ・style・イベント属性などを操作できないというバグがあり、その対処を施しています。IE 不具合対処の参考サイトは下記です。ありがとうございました。
Comments [6] | Trackbacks [0]
2007年2月 6日

Slider の利用方法

February 6,2007 12:50 AM
Tag:[, ]
Permalink

Ajax ライブラリとしてスライダーの API が色々と公開されていますが、それとは関係なく、1年近く前にみつけてエントリーしていなかったWebFXSlider を紹介したいと思います。

Value:

Slider は Mozzila 系ブラウザで動作しなかった、同サイトで公開されていた slidebar を新しく作り直したものです。
なお、WebFX は、国内ではグラフ描画の Chart Usage がブログ等で紹介されています。

1.機能

Slider は下記の機能があります。

  • スライダーを操作することにより、予め設定した最小値?最大値の値を取得
  • 予め設定したデフォルト値の位置にスライダーハンドルを固定
  • 値の途中変更が可能
  • スライド方向(縦・横)を指定可能

また

  • マウスサポート(ドラッグだけでなくクリックによる操作も可能)
  • キーボード操作のサポート(矢印キーやPageUp/PageDown による操作が可能)
  • ホイール操作のサポート(IEのみ)
  • CSSによるスキン変更(Demoのページでサンプルを見ることができます)

と、スライダーとしては結構良い仕上がりです。

2.ダウンロード・インストール

Slider の一番下にある「Download」をクリック。ダウンロードしたアーカイブを解凍し、中にある slider というフォルダを index.html のディレクトリに丸ごとアップロードします。
動作に必要なのは下記です。

slider/css/bluecurve/*
slider/css/luna/*
slider/css/swing/*
slider/js/range.js
slider/js/slider.js
slider/js/timer.js

css ディレクトリは使用するスキン別に分けられています。例えば bluecurve を使用するのであれば luna / swing ディレクトリはアップロード不要です。

3.スライダーの表示

</head> の直前に下記を追加します。

<link type="text/css" rel="stylesheet" href="slider/css/bluecurve/bluecurve.css" />
<script type="text/javascript" src="slider/js/range.js"></script>
<script type="text/javascript" src="slider/js/timer.js"></script>
<script type="text/javascript" src="slider/js/slider.js"></script>

1行目はサンプルで用意されているスキンから「bluecurve」を利用した場合です。他に「winclassic」「luna」「swing」がありますのでお好きなデザインを選んでください(winclassic は winclassic.css ファイルのみ)。

スライダーを表示させたい位置に下記のタグを追加します。tabIndex 属性は TAB キーによる選択を可能にします。

<div class="slider" id="slider-1" tabIndex="1">
<input class="slider-input" id="slider-input-1" name="slider-input-1" />
</div>

上記タグのすぐ下に、下記のデバグ用タグ(青色)を表示させておくと良いでしょう(不要になったら削除します)。

<div class="slider" id="slider-1" tabIndex="1">
<input class="slider-input" id="slider-input-1" name="slider-input-1" />
</div>
<p>
Value: <input id="h-value" onchange="s.setValue(parseInt(this.value))"/>
Minimum: <input id="h-min" onchange="s.setMinimum(parseInt(this.value))"/>
Maximum: <input id="h-max" onchange="s.setMaximum(parseInt(this.value))"/>
</p>

4.script タグの追加

4.1 Horizontal (水平方向にスライド)の場合

2項で設定した位置より後方に下記の script タグを追加します。ここでは上記のデバグ用 input タグにスライダーの値を表示するだけのサンプルを示します。

<script type="text/javascript">
var s = new Slider(document.getElementById("slider-1"), document.getElementById("slider-input-1"));
s.onchange = function () {
 
    // デバグ用
    document.getElementById("h-value").value = s.getValue();
    document.getElementById("h-min").value = s.getMinimum();
    document.getElementById("h-max").value = s.getMaximum();
};
window.onresize = function () {
    s.recalculate();
};
</script>

4.2 vertical (垂直方向にスライド)の場合

4.1項のコンストラクタ(new ?の行)の第3パラメータに下記を追加します。

<script type="text/javascript">
var s = new Slider(document.getElementById("slider-1"), document.getElementById("slider-input-1"), "vertical");
    :

または次のように setOrientation を追加します。

<script type="text/javascript">
var s = new Slider(document.getElementById("slider-1"), document.getElementById("slider-input-1"));
s.setOrientation("vertical");
    :

5.各値の変更

下記の API を利用して値を変更します。

  • デフォルト値:setValue
  • 最大値:setMaximum
  • 最小値:setMinimum

以下、設定例です。

<script type="text/javascript">
var s = new Slider(document.getElementById("slider-1"), document.getElementById("slider-input-1"));
s.setValue(10);
s.setMaximum(100);
s.setMinimum(0);
    :

6.API

Slider で提供されている各 API です(間違っていたらご指摘ください)。

Timer

setTimeout のオブジェクト指向カプセル化

getPauseTime:ポーズ時間(ms)取得
isStarted:タイマー開始可否を返却
setPauseTime:ポーズ時間(ms)設定
start:タイマー開始
stop:タイマー終了

Range

スライダー・スクロールバー・プログレスバーの動作で使用されるデータのモデル化。 Sun Java によって定義された javax.swing.BoundedRangeModel インタフェースの考えに基づいています

getMaximum:最大値を取得
getMinimum:最小値を取得
getValue:スライダーの値を取得
setMaximum:最大値を設定
setMinimum:最小値を設定
setValue:スライダーの値を設定

Slider

最大値?最小値の値を変えるためにハンドルをドラッグずるスライダーコントロール

getBlockIncrement:PageUp/PageDownキーの増減値を取得
getMaximum:最大値を取得
getMinimum:最小値を取得
getOrientation:スライダーの縦・横を取得
getUnitIncrement:矢印キーの増減値を取得
getValue:スライダーの値を取得
ontimer:タイマー設定
recalculate:*スライダーがリサイズされた後にこのAPIを使用
setBlockIncrement:PageUp/PageDownキーの増減値を設定
setMaximum:最大値を設定
setMinimum:最小値を設定
setOrientation:スライダーの縦・横を設定
setUnitIncrement:矢印キーの増減値を指定
setValue:スライダーの値を設定

7.スキン用 CSS

スキンは下記のセレクタで設定されています。

/* スライダー全体 */
.dynamic-slider-control {}
 
/* スライダー外側(horzontal用) */
.horizontal {}
 
/* スライダー外側(vertical用) */
.vertical {}
 
/* スライダー内側 */
.dynamic-slider-control input {}
 
/* ハンドル */
.dynamic-slider-control .handle {}
 
/* ハンドルの画像(horizontal用) */
.dynamic-slider-control.horizontal .handle {}
.dynamic-slider-control.horizontal .handle div {}
.dynamic-slider-control.horizontal .handle.hover {}
 
/* ハンドルの画像(vertical用) */
.dynamic-slider-control.vertical .handle {}
.dynamic-slider-control.vertical .handle.hover {}
 
/* スライダーバー */
.dynamic-slider-control .line {}
 
/* スライダーバー幅(vertical用) */
.dynamic-slider-control.vertical .line {}
 
/* スライダーバー幅(horizontal用) */
.dynamic-slider-control.horizontal .line {}
 
/* スライダーバーのドロップシャドウ */
.dynamic-slider-control .line div {}

2008.04.21
サンプルのマークアップを変更(IE6で表示できなかったため)

Comments [0] | Trackbacks [2]
2007年1月18日

Highslide JS でサムネイル画像を拡大表示する

January 18,2007 12:51 AM
Tag:[, , ]
Permalink

サムネイル画像をクールに拡大表示する Highslide JS を利用する方法を紹介します。内容は Movable Type をサンプルにしていますが、他のブログ等でも応用できると思います。
WordPress ではプラグイン WPJ-Highslide 0.2 が利用できるみたいです。

とりあえず下記のサンプル画像をクリックしてください。拡大表示された画像の上でクリックすると元に戻ります。

Highslide JS

拡大ツールでは、当サイトでも紹介している Lightbox JS が有名ですが、この Highslide JS は下記の特徴があります。

  • 拡大画像の下にキャプション(タイトル)の挿入が可能
  • ウィンドウサイズに収まるように拡大(右下のアイコンをクリックすると 100% 表示)
  • 拡大画像のドラッグが可能

以下、カスタマイズ方法です。ここではダウンロード時のバージョン 2.2.74.0.6 で話を進めます。

1.ダウンロード

Highslide JS の「Download」のリンクをクリック

Highslide JS のサイト

バージョンを選択して「Download Now!」をクリック

Highslide JS ダウンロードバージョン選択

商用の場合は購入、非商用の場合はドネーションの有無を選択して、「Highslide Download」の Yes をクリック。

Highslide JS ダウンロード

2.アップロード

解凍した中にある、highslide フォルダを丸ごとアップロードします。Movable Type の場合はブログディレクトリ(ブログのトップページとなる index.html が出力されるディレクトリ)にアップロードした手順で説明します。

highslide フォルダと同じ階層にある images / example-xx.html 等はアップロード不要ですが、サンプルの動作確認を行いたい場合はアップロードしてください(詳細は7項参照)。

3.スクリプトのインクルード設定

次の script 要素を </head> の直前に設定します。Movable Type 3 の場合は head 要素が記述されている各テンプレートに設定してください。Movable Type 4 では、head 要素部分がモジュール化(部品化)されているため、次のテンプレートに設定してください。

  • MT4.0~4.1x のデフォルトテンプレート:「ヘッダー」テンプレートモジュール
  • MT4.2x~ のデフォルトテンプレート:「HTMLヘッダー」テンプレートモジュール(テンプレート内に head 要素はありませんが問題ありません)
  • MT4.x~ の小粋空間テンプレート:「ヘッダー」テンプレートモジュール
<script type="text/javascript" src="http://user-domain/highslide/highslide.js"></script>

赤色部分はアップロード先のドメインを指定してください。Movable Type の場合は、次のようにテンプレートタグを利用すると良いでしょう。

<script type="text/javascript" src="<$MTBlogURL$>highslide/highslide.js"></script>

4.ポップアップ用空要素設定

Highslide JS でポップアップする画像を表示させるための div 空要素を設定します。そして div 要素の id 属性に "highslide-container" を設定します。

注:HighSlide の最新バージョンではこの設定は不要です。

<div id="highslide-container"></div>

サンプルの説明では「このタグは body 要素の後に直接設定してください」と書かれています。

ちなみに、この div 要素は id 属性つきですので、HTML ページに一つ以上の記述があってはいけません。Movable Type でエントリーにこのタグを記述すると、トップページやアーカイブページで同じ id 属性値が複数存在する可能性があるため、各テンプレートに直接記述してください。

5.タグ設定

5.1 基本

記事本文中に、次のように (X)HTML 要素を記述することで、Highslide JS の機能が有効になります。

まず、サムネイル画像表示用の img 要素を書き、それを a 要素で括ります。a 要素の href 属性には元画像の URL を設定してください。
そして a 要素に class 属性 "highslide" と、onclick 属性を追加します。

<a href="画像ファイルのURL" class="highslide" onclick="return hs.expand(this)">
<img src="サムネイル画像のURL" alt="..." />
</a> 

設定した class 属性はサムネイル画像用のスタイル設定に利用するためのものです。
なお、ユーザビリティを考慮して onkeypress 属性も追加しておくと良いでしょう。

<a href="画像ファイルのURL" class="highslide" onclick="return hs.expand(this)" onkeypress="return hs.expand(this)">
<img src="サムネイル画像のURL" alt="..." />
</a> 

5.2 キャプション(画像のタイトル)を表示する場合

下のリストのように、青色部分を追加すればキャプションが表示されます。

<a href="画像ファイルのURL" class="highslide" onclick="return hs.expand(this)">
<img src="サムネイル画像のURL" alt="..." id="image" />
</a> 
<div class="highslide-caption"><p>タイトル</p></div>

キャプションは a 要素の直後に記述し、キャプションを括る要素に class="highslide-caption" を追加してください(div 要素でなくても大丈夫です)。
また、1ページに複数の画像がある場合でも、追加したキャプションは直前の画像に対応づけられます。

5.3 キャプションにコントローラーを追加する場合

複数の画面を制御する場合にコントローラーを追加します。これはキャプション部分に追加する場合です。

<div class='highslide-caption' id='the-caption'>
<a href="javascript:void(0)" onclick="return hs.previous(this)" class="control" style="float:left; display: block">
Previous<br/>
<small style="font-weight: normal; text-transform: none">left arrow key</small></a>
<a href="javascript:void(0)" onclick="return hs.next(this)" class="control" style="float:left; display: block; text-align: right; margin-left: 50px">Next<br/>
<small style="font-weight: normal; text-transform: none">right arrow key</small></a>
<a href="javascript:void(0)" onclick="hs.close(this)" class="control">Close</a>
<a href="javascript:void(0)" class="highslide-move control">Move</a>
<div style="clear:both"></div>
</div>

5.2項同様、画像の下に追加してください。

5.4 画像内にコントローラーを追加する場合

注:この項目は過去の Highslide バージョンのものです

次のリストは画像内にコントローラーを追加する場合の設定です。

<div id="controlbar" class="highslide-overlay controlbar">
<a href="javascript:void(0)" onclick="return hs.previous(this)" title="Previous (left arrow key)"></a>
<a href="javascript:void(0)" onclick="return hs.next(this)" title="Next (right arrow key)"></a>
<a href="javascript:void(0)" class="highslide-move" title="Click and drag to move" style="margin-left: 10px"></a>
<a href="javascript:void(0)" onclick="hs.close(this)" title="Close"></a>
</div>

6.script 要素と CSS の設定

最後に、デザインを設定するための script 要素と CSS を設定します。script 要素は3項で設定した script 要素の直後に、CSS はスタイルシートにそれぞれ追加してください。

設定前の予備知識として、HighSlide JS には何パターンかのサンプルが提供されています。サンプルは上記のキャプションやコントローラーの有無に加え、ズームインしたときの様々なデザインが用意されています。
ここでは、それらの中からとりあえずひとつを選んで設定してみてください。

ということで、やや長くなりますが、HighSlide JS のサンプルで利用されている CSS を全て掲載しておきます。太字タイトルは、7項に記してあるサンプルの各メニュー名に対応しています(間違ってたらすいません)。

注:script 要素内の hs.graphicsDir および CSS の cusor プロパティの URL には ご自身のドメイン(http://~)を追加してください。サンプルでは highslide ディレクトリからパスが開始しているので、このままの状態では highslide ディレクトリと異なるパスにあるページで正常に動作しません。

最低限必要な設定(MT4の設定例)

ズームを全ページで有効にするためのパスの設定と、画像のローディング画像、ズームイン時、および画像を最大化するとき(ブラウザの幅が画像の最大幅より小さい時に表示)のポインタを表示します。

script 要素(3項の直後に追加)

<script type="text/javascript">    
    hs.graphicsDir = '<$MTBlogURL$>highslide/graphics/';
</script>

CSS

.highslide {
    cursor: url(<$MTBlogURL$>highslide/graphics/zoomin.cur), pointer;
}
.highslide-loading {
    display: block;
    color: black;
    font-size: 8pt;
    font-family: sans-serif;
    font-weight: bold;
    text-decoration: none;
    padding: 2px;
    border: 1px solid black;
    background-color: white;
    padding-left: 22px;
    background-image: url(<$MTBlogURL$>highslide/graphics/loader.white.gif);
    background-repeat: no-repeat;
    background-position: 3px 1px;
}
a.highslide-full-expand {
    background: url(<$MTBlogURL$>highslide/graphics/fullexpand.gif) no-repeat;
    display: block;
    margin: 0 10px 10px 0;
    width: 34px;
    height: 34px;
}
White 10px border and drop shadow(ボーダー・角・影つき)

ボーダー・角・影つき

script 要素(3項の直後に追加)

<script type="text/javascript">    
    hs.graphicsDir = 'highslide/graphics/';
</script>

CSS

.highslide-wrapper div {
    font-family: Verdana, Helvetica;
    font-size: 10pt;
}
.highslide {
    cursor: url(highslide/graphics/zoomin.cur), pointer;
    outline: none;
    text-decoration: none;
}
.highslide-active-anchor img {
    visibility: hidden;
}
.highslide-wrapper, .drop-shadow {
    background: white;
}
.highslide img {
    border: 2px solid gray;
}
.highslide:hover img {
    border: 2px solid white;
}
.highslide-wrapper {
    background: white;
}
.highslide-image {
    border: 10px solid white;
}
.highslide-image-blur {
}
.highslide-caption {
    display: none;
    border: 5px solid white;
    border-top: none;
    padding: 5px;
    background-color: white;
}
.highslide-loading {
    display: block;
    color: black;
    font-size: 8pt;
    font-family: sans-serif;
    font-weight: bold;
    text-decoration: none;
    padding: 2px;
    border: 1px solid black;
    background-color: white;
    padding-left: 22px;
    background-image: url(highslide/graphics/loader.white.gif);
    background-repeat: no-repeat;
    background-position: 3px 1px;
}
a.highslide-credits,
a.highslide-credits i {
    padding: 2px;
    color: silver;
    text-decoration: none;
    font-size: 10px;
}
a.highslide-credits:hover,
a.highslide-credits:hover i {
    color: white;
    background-color: gray;
}
a.highslide-full-expand {
    background: url(highslide/graphics/fullexpand.gif) no-repeat;
    display: block;
    margin: 0 10px 10px 0;
    width: 34px;
    height: 34px;
}
Drop shadow and no border(ボーダーなし・影つき)

ボーダーなし・影つき

script 要素(3項の直後に追加)

<script type="text/javascript">    
hs.graphicsDir = 'highslide/graphics/';
</script>

CSS

.highslide-wrapper div {
    font-family: Verdana, Helvetica;
    font-size: 10pt;
}
.highslide {
    cursor: url(highslide/graphics/zoomin.cur), pointer;
    outline: none;
    text-decoration: none;
}
.highslide-active-anchor img {
    visibility: hidden;
}
.highslide img {
    border: 2px solid gray;
}
.highslide:hover img {
    border-color: silver;
}
.highslide-wrapper, .drop-shadow {
    background: white;
}
.highslide-image {
    border-bottom: 1px solid white;
}
.highslide-image-blur {
}
.highslide-caption {
    display: none;
    border-bottom: 1px solid white;
    font-family: Verdana, Helvetica;
    font-size: 10pt;
    padding: 5px;
    background-color: silver;
}
.highslide-loading {
    display: block;
    color: black;
    font-size: 8pt;
    font-family: sans-serif;
    font-weight: bold;
    text-decoration: none;
    padding: 2px;
    border: 1px solid black;
    background-color: white;
    padding-left: 22px;
    background-image: url(highslide/graphics/loader.white.gif);
    background-repeat: no-repeat;
    background-position: 3px 1px;
}
a.highslide-credits,
a.highslide-credits i {
    padding: 2px;
    color: silver;
    text-decoration: none;
    font-size: 10px;
}
a.highslide-credits:hover,
a.highslide-credits:hover i {
    color: white;
    background-color: gray;
}
a.highslide-full-expand {
    background: url(highslide/graphics/fullexpand.gif) no-repeat;
    display: block;
    margin: 0 10px 10px 0;
    width: 34px;
    height: 34px;
}
.highslide-overlay {
    display: none;
}
White outline with rounded corners(角丸ボーダー・ドロップシャドウ)

角丸ボーダー・ドロップシャドウ

script 要素(3項の直後に追加)

<script type="text/javascript">    
    hs.graphicsDir = 'highslide/graphics/';
    hs.outlineType = 'rounded-white';
</script>

CSS

.highslide-wrapper div {
    font-family: Verdana, Helvetica;
    font-size: 10pt;
}
.highslide {
    cursor: url(highslide/graphics/zoomin.cur), pointer;
    outline: none;
    text-decoration: none;
}
.highslide-active-anchor img {
    visibility: hidden;
}
.highslide img {
    border: 2px solid gray;
}
.highslide:hover img {
    border: 2px solid white;
}
.highslide-wrapper, .rounded-white {
    background: white;
}
.highslide-image {
    border: 2px solid white;
}
.highslide-image-blur {
}
.highslide-caption {
    display: none;
    border: 2px solid white;
    border-top: none;
    font-family: Verdana, Helvetica;
    font-size: 10pt;
    padding: 5px;
    background-color: white;
}
.highslide-loading {
    display: block;
    color: black;
    font-size: 8pt;
    font-family: sans-serif;
    font-weight: bold;
    text-decoration: none;
    padding: 2px;
    border: 1px solid black;
    background-color: white;
    padding-left: 22px;
    background-image: url(highslide/graphics/loader.white.gif);
    background-repeat: no-repeat;
    background-position: 3px 1px;
}
a.highslide-credits,
a.highslide-credits i {
    padding: 2px;
    color: silver;
    text-decoration: none;
    font-size: 10px;
}
a.highslide-credits:hover,
a.highslide-credits:hover i {
    color: white;
    background-color: gray;
}
a.highslide-full-expand {
    background: url(highslide/graphics/fullexpand.gif) no-repeat;
    display: block;
    margin: 0 10px 10px 0;
    width: 34px;
    height: 34px;
}
Dark design with outer glow(ダーク系・ボーダー・ドロップシャドウ)

ダーク系・ボーダー・ドロップシャドウ

script 要素(3項の直後に追加)

<script type="text/javascript">    
    hs.graphicsDir = 'highslide/graphics/';
    hs.outlineType = 'outer-glow';
</script>

CSS

.highslide-wrapper div {
    font-family: Verdana, Helvetica;
    font-size: 10pt;
}
.highslide {
    cursor: url(highslide/graphics/zoomin.cur), pointer;
    outline: none;
    text-decoration: none;
}
.highslide img {
    border: 2px solid gray;
}
.highslide-active-anchor img {
    visibility: hidden;
}
.highslide:hover img {
    border: 2px solid white;
}
.highslide-wrapper, .outer-glow {
    background: #444;
}
.highslide-image {
    border: 5px solid #444444;
}
.highslide-image-blur {
}
.highslide-caption {
    display: none;
    font-family: Verdana, Helvetica;
    font-size: 10pt;
    border: 5px solid #444444;
    border-top: none;
    padding: 5px;
    background-color: gray;
}
.highslide-loading {
    display: block;
    color: white;
    font-size: 9px;
    font-weight: bold;
    text-transform: uppercase;
    text-decoration: none;
    padding: 3px;
    border-top: 1px solid white;
    border-bottom: 1px solid white;
    background-color: black;
    padding-left: 22px;
    background-image: url(highslide/graphics/loader.gif);
    background-repeat: no-repeat;
    background-position: 3px 1px;
}
a.highslide-credits,
a.highslide-credits i {
    padding: 2px;
    color: silver;
    text-decoration: none;
    font-size: 10px;
}
a.highslide-credits:hover,
a.highslide-credits:hover i {
    color: white;
    background-color: gray;
}
a.highslide-full-expand {
    background: url(highslide/graphics/fullexpand.gif) no-repeat;
    display: block;
    margin: 0 10px 10px 0;
    width: 34px;
    height: 34px;
}
No graphic outline(アウトラインなし)

アウトラインなし

script 要素(3項の直後に追加)

<script type="text/javascript">    
    hs.graphicsDir = 'highslide/graphics/';
    hs.outlineType = null;
</script>

CSS

.highslide {
    cursor: url(highslide/graphics/zoomin.cur), pointer;
    outline: none;
    text-decoration: none;
}
.highslide-active-anchor img {
    visibility: hidden;
}
.highslide img {
    border: 2px solid gray;
}
.highslide:hover img {
    border: 2px solid white;
}
.highslide-wrapper {
    background: white;
}
.highslide-image {
    border: 2px solid white;
}
.highslide-image-blur {
}
.highslide-caption {
    display: none;
    border: 2px solid white;
    border-top: none;
    font-family: Verdana, Helvetica;
    font-size: 10pt;
    padding: 5px;
    background-color: white;
}
.highslide-loading {
    display: block;
    color: black;
    font-size: 8pt;
    font-family: sans-serif;
    font-weight: bold;
    text-decoration: none;
    padding: 2px;
    border: 1px solid black;
    background-color: white;
    padding-left: 22px;
    background-image: url(highslide/graphics/loader.white.gif);
    background-repeat: no-repeat;
    background-position: 3px 1px;
}
a.highslide-credits,
a.highslide-credits i {
    padding: 2px;
    color: silver;
    text-decoration: none;
    font-size: 10px;
}
a.highslide-credits:hover,
a.highslide-credits:hover i {
    color: white;
    background-color: gray;
}
a.highslide-full-expand {
    background: url(highslide/graphics/fullexpand.gif) no-repeat;
    display: block;
    margin: 0 10px 10px 0;
    width: 34px;
    height: 34px;
}

7.サンプル

ダウンロードしたアーカイブの中にサンプルファイル(下記)があります。

  • example-white-10px.html (White 10px border and drop shadow)
  • example-no-border.html (Drop shadow and no border)
  • example-white-rounded-outline.html (White outline with rounded corners)
  • example-outer-glow.html (Dark design with outer glow)
  • example-no-outline.html (No graphic outline)

まずはこれらを一緒にアップロードしてお気に入りの動作・スタイルを探しましょう。同じフォルダにある index.htmimage フォルダも忘れずにアップロードしてください。

アップロードした index.htm にアクセスすると、各サンプルのメニューが表示されます(カッコ内がメニュー名)。
また各 html ファイルをエディタで開けば中に設定方法が書かれています。色々お試しください。

2007.01.24
3項の説明を修正しました。

2007.03.18
5.1項の説明を修正しました。

2007.11.13
5.2項に、1ページに複数のキャプション画像を表示する場合の説明を追加しました。

2008.10.09
HIghSlide 4.0.6 を元にデータを修正しました。また、Movable Type 4 に適用する場合の記述を追加しました。

2010.03.28
説明を一部修正しました。

Comments [96] | Trackbacks [36]
2006年12月 7日

JavaScript で文字をトリミングする(改善版)

December 7,2006 1:55 AM
Tag:[]
Permalink

JavaScript で文字をトリミングするJavaScript を用いてエントリータイトル等の文字をトリミング(指定した文字数だけ表示する)するカスタマイズです。前回の「JavaScript で文字をトリミングする」は文字数だけでトリミングしたものですが、今回の改善版はバイト数で計算します。全角はそのまま1文字として数え、半角英数は2文字(2バイト)を1文字としてカウントします。

左のスクリーンショットが5文字でトリミングしたサンプルです。上は全角のみなので5文字でトリミングし、下は半角を含むので計7文字でトリミングしています。

さらにスクリプトを修正すれば、特定の半角文字("M"とか"W"のような幅の広い文字)を全角として数えることも可能と思われます。完璧に横幅を揃えることはできませんが、かなり精度の良いトリミングができると思います。

今回も「id 属性名」と「要素名+ class 属性名」で指定したタグの中に記述された文字列をトリミングする、JavaScript を書いてみました。

Windows + IE6/Firefox 2 で実験した限りでは、全角・半角いずれも1文字で計算してトリミングしてくれるようですが、コードに不具合等ありましたらお知らせください。

1.スクリプトの追加

次のリストを </head> の直前に追加します。外部ファイルにしても構いません。

<script type="text/javascript">
var rest = '...';
function cutStringById(id, size) {
  var str = document.getElementById(id).innerHTML;
  if(str.length > size){
    document.getElementById(id).innerHTML = str.substring(0, size) + rest;
  }
}
 
function cutStringByTagNameAndClassName(tagName, className, size) {
  var elements = document.getElementsByTagName(tagName);
  for (i=0; i < elements.length; i++) {
    if (elements[i].className == className) {
      var str = elements[i].innerHTML;
      elements[i].innerHTML = trim(str,size);
    }
  }
}
 
function cutStringByIdAndTagName(id, tagName, size) {
  var element = document.getElementById(id);
  var elements = element.getElementsByTagName(tagName);
  for (i=0; i < elements.length; i++) {
    var str = elements[i].innerHTML;
    if(str.length > size){
      elements[i].innerHTML = trim(str,size);
    }
  }
}
 
function cutStringByClassNameAndTagName(className, tagName, size) {
  var elements = document.getElementsByTagName(tagName);
  for (i=0; i < elements.length; i++) {
    if (elements[i].parentNode.className == className) {
      var str = elements[i].innerHTML;
      elements[i].innerHTML = trim(str,size);
    }
  }
}
 
function trim(str, size) {
  if(str.length > size){
    var cutstring = str.substring(0, size);
    var byte = countByte(cutstring);
    var tmp = "";
    if (byte < size*2) {
       for(k=0; k < (size*2-byte)*2; k++){
         tmp = str.substring(0,size + k);
         if (countByte(tmp) >= size*2) {
           break;
         }
       }
    }
    if(tmp){
      return tmp + rest;
    } else {
      return str.substring(0, size) + rest;
    }
  } else {
    return str;
  }
}
 
function countByte(str) {
  var byte = 0;
  for (j=0; j < str.length; j++) {
    str.charCodeAt(j) < 0x100 ? byte++ : byte += 2;
  }
  return byte;
}
</script>

2.スクリプトを起動する

スクリプトを起動するため、2.1~2.4のいずれかの script 要素を 、トリミングしたい文字列の直後、または </body> の直前に追加します。

2.1 要素名+ class 属性名で指定

<script type="text/javascript">
cutStringByTagNameAndClassName('[要素名]', '[class 属性名]', トリミングサイズ);
</script>

2.2 id 属性名で指定

<script type="text/javascript">
cutStringById('[id 属性名]', トリミングサイズ);
</script>

2.3 id 属性名+ 要素名で指定

<script type="text/javascript">
cutStringByIdAndTagName('[id 属性名]', '[要素名]', トリミングサイズ);
</script>

2.4 親要素の class 属性名+ 要素名で指定

<script type="text/javascript">
cutStringByClassNameAndTagName('[親要素の class 属性名]', '[要素名]', トリミングサイズ);
</script>

具体的な起動方法は3項をご覧ください。

3.サンプル

3.1 要素名+ class 属性名で指定

次の(X)HTMLマークアップ、

<a href="http://domain.com/" class="hoge">文字をトリミングする</a>

の「文字をトリミングする」の文字を先頭から 5 文字だけ表示(「文字をトリ...」にする)する場合は、2.1のリストを利用し、赤色部分を、

cutStringByTagNameAndClassName('a', 'hoge', 5);

とします。

3.2 id 属性名で指定

次の(X)HTMLマークアップ、

<p id="hoge">文字をトリミングする</p>

の「文字をトリミングする」の文字を先頭から 5 文字だけ表示(「文字をトリ...」にする)する場合は、2.2のリストを用い、その赤色部分を

cutStringById('hoge', 5);

とします。

3.3 id 属性名+ 要素名で指定

次の(X)HTMLマークアップ、

<div id="hoge"><a href="http://domain.com/">文字をトリミングする</a></div>

の「文字をトリミングする」の文字を先頭から 5 文字だけ表示(「文字をトリ...」にする)する場合は、2.3のリストを利用し、赤色部分を、

cutStringByIdAndTagName('hoge', 'a', 5);

とします。

3.4 親要素の class 属性名+ 要素名で指定

次の(X)HTMLマークアップ、

<div class="hoge"><a href="http://domain.com/">文字をトリミングする</a></div>

の「文字をトリミングする」の文字を先頭から 5 文字だけ表示(「文字をトリ...」にする)する場合は、2.4のリストを利用し、赤色部分を、

cutStringByClassNameAndTagName('hoge', 'a', 5);

とします。

4.トリミング後の追加文字列を変更する

トリミング後の追加文字列を変更するには、冒頭のリスト2 行目を他の文字に変更してください。何も表示させたくない場合は赤色部分を削除してください。

var rest = '...';

5.特定の半角文字のバイト数を変更する

1項のスクリプトに青色のような行を追加します(間違ってたらすいません)。赤色部分は "0xXX" という、16進数を設定します。

function countByte(str) {
  var byte = 0;
  for (j=0; j < str.length; j++) {
    str.charCodeAt(j) < 0x100 ? byte++ : byte += 2;
    if(str.charCodeAt(j) == [該当文字の16進数]) byte++;
  }
  return byte;
}

charCodeAt は指定した文字の Unicode を返却する関数です。JavaScript 1.2 と 1.3 で振る舞いが異なるようです。

2006.12.28
id 属性名+要素名で検索できるコードを、スクリプトおよびリスト2.3項に追加しました。

2007.02.15
トリミング文字列が短い場合に正常に表示されない不具合を修正しました。

2008.08.03
cutStringByClassNameAndTagName を追加しました。

Comments [12] | Trackbacks [1]
2006年12月 4日

JavaScript で文字をトリミングする

December 4,2006 1:50 AM
Tag:[, ]
Permalink

JavaScript で文字をトリミングするJavaScript を用いてエントリータイトル等の文字をトリミング(指定した文字数だけ表示する)するカスタマイズです。

以前、「Movable Type のようなトリミングを、他のブログで実現できないでしょうか」というご質問の回答です。大変遅くなりましたが、このエントリーで回答に替えさせて頂きます。

ここでは文字数でトリミングする方法を紹介していますが、半角・全角が混在している場合のサイズを調整したい場合は、下記のエントリーを参照ください。

JavaScript で文字をトリミングする(改善版)

とりあえず「id 属性名」と「要素名+ class 属性名」で指定したタグの中に記述された文字列をトリミングする、簡単な JavaScript を書いてみました。

Windows + IE6/Firefox 2 で実験した限りでは、全角・半角いずれも1文字で計算してトリミングしてくれるようですが、コードに不具合等ありましたらお知らせください。

1.スクリプトの追加

リスト 1.1 のリストを </head> の直前に追加します。外部ファイルでも構いません。

リスト 1.1 トリミング用スクリプト

<script type="text/javascript">
var rest = '...';
function cutStringById(id, size) {
  var str = document.getElementById(id).innerHTML;
  if(str.length > size){
    document.getElementById(id).innerHTML = str.substring(0, size) + rest;
  }
}
function cutStringByTagNameAndClassName(tagName, className, size) {
  var elements = document.getElementsByTagName(tagName);
  for (i=0; i < elements.length; i++) {
    if (elements[i].getAttribute('class') == className ||
      elements[i].getAttribute('className') == className) {
      var str = elements[i].innerHTML;
      if(str.length > size){
        elements[i].innerHTML = str.substring(0, size) + rest;
      }
    }
  }
}
</script>

2.スクリプトを起動する

リスト 2.1 またはリスト 2.2 のいずれかを 、トリミングしたい文字列の直後、または </body> の直前に追加します。

要素名+ class 属性名で指定

リスト 2.1 要素名+ class 属性名で指定

<script type="text/javascript">
cutStringByTagNameAndClassName('[要素名]', '[class 属性名]', トリミングサイズ);
</script>

id 属性名で指定

リスト 2.2 id 属性名で指定

<script type="text/javascript">
cutStringById('[id 属性名]', トリミングサイズ);
</script>

具体的な起動方法は3項をご覧ください。

3.サンプル

リスト 3.1 のようにHTMLマークアップされた文字列

リスト 3.1 サンプル1

<a href="http://domain.com/" class="hoge">文字をトリミングする</a>

の「文字をトリミングする」の文字を先頭から 5 文字だけ表示(「文字をトリ...」にする)する場合は、リスト 2.1 を利用し、その赤色部分を、

リスト 3.2 サンプル2

cutStringByTagNameAndClassName('a', 'hoge', 5);

とします。

リスト 3.3 のようにHTMLマークアップされた文字列

リスト 3.3 サンプル2

<p id="hoge">文字をトリミングする</p>

の「文字をトリミングする」の文字を先頭から 5 文字だけ表示(「文字をトリ...」にする)する場合は、リスト 2.2 を用い、その赤色部分を

リスト 3.4 サンプル2

cutStringById('hoge', 5);

とします。

4.トリミング後の追加文字列を変更する

リスト 1.1 の 2 行目(リスト 4.1 の赤色部分)を他の文字に変更してください。何も表示させたくない場合は赤色部分を削除してください。

リスト 4.1 トリミング後の文字列

var rest = '...';
Comments [0] | Trackbacks [1]
2006年10月18日

BlogPeople 等のリンクリストによる表示の遅延を解消する(その1:JavaScript編)

October 18,2006 12:25 AM
Tag:[]
Permalink

BlogPeople やドリコム RSS がサービスとして提供しているリンクリスト。ご自身のページに直接HTMLでリンク集を作成するより、表示件数のカスタマイズやサイトの更新状況がわかる等、大変便利なサービスなので利用されている方はかなり多いと思います。

しかしながら、リンクリストはサーバに一旦アクセスしてから表示される仕組みになっているため、少なからずタイムラグが発生します。
このタイムラグはHTMLページの表示に大きく影響します。その理由は次の通りです。

例えばIEでサイトを閲覧する場合、そのサイトのページはHTMLソースの先頭から記述された順番に表示されるようになっています *1。つまり、ページの最初や途中にこのリンクリストを表示するタグが記述されている場合、サーバの応答が返ってくるまでそれ以降のHTMLソースの内容が表示されないという問題があります。
サーバからの応答がある場合はまだ良いのですが、サーバダウン等といった不測の事態が発生すると、それ以降のページがしばらく表示されなくなる可能性もあり、閲覧者にとってはかなりのストレスになります。

したがって、リンクリストを表示する位置についてはページの(少なくとも本文より)後方やリンクリスト専用のページに配置したり、あるいは「中継君関連記事)」を利用されているのではないでしょうか。

前置きが長くなりましたが、このエントリーではごく簡単な JavaScript を用いてリンクリスト表示のタイムラグを解消する方法をご紹介します。*2
仕組みを説明しますと、リンクリストのタグはとりあえずページの一番最後に埋め込み、それを JavaScript を使って別の位置に再表示するという作戦です。これだけではリストが2ヶ所に表示されてしまうため、ページの最後に埋め込んだ方のリストはCSSで非表示にします。

下記にサンプル(カスタマイズ前・後)がありますので、IEでページを表示した後、ブラウザをリロードして表示の違いを比べてみてください(ページサイズが小さいため、カスタマイズ前のものも比較的スムーズに表示されます。ご容赦ください)。

  • サンプル1:リンクリストタグをHTMLの前方に記述・表示
  • サンプル2:リンクリストタグを後方に記述して前方に表示

このスクリプトを用いることで、

  • ページが速やかに表示される
  • サーバ側のリンクリスト更新にリアルタイムに対応
  • リンクリストのアクセス数がPV(ページビュー)単位にカウントされる

といったメリットを享受することができます。
ただし、リスト配布元のサーバがダウンしている場合等はリンクリストは表示されませんので、必ず表示したいということであれば中継君の利用をお勧めします。

またリストを非表示にすることについての妥当性についてはここでは言及しておりませんので、ご利用の判断はご自身で行ってください。なお当サイトでは以前(数ヶ月前)よりこの方法で表示しています。

以下、カスタマイズ方法です。

1.リンクリスト表示用タグの追加

次のような空要素(ここでは div)を、リンクリストを表示したい位置へ設定します。

<div id="blogpeople"></div>

ここで重要なのは、id="xxx" という id 属性の記述です。ここでは属性値を "blogpeople" としておきます。

2.リンクリスト表示のスクリプト設定

div タグで括ったリンクリスト用のタグを、 </body> の直前に記述します(青色 *3)。ここでは BlogPeople のリンクリストを表示する例で示しています。

<div id="linklist"><script type="text/javascript" src="http://www.blogpeople.net/display/usr/0f0d42505b5dxxxx.js"></script></div>
</body>

ここでも外側の div 要素に任意の id 属性値を記述します。ここでは "linklist" とします。

3.表示用スクリプト設定

2項で設定したタグと </body> の間に、1項で設定したタグの位置に表示するためのスクリプトを記述します(青色)。

<div id="linklist"><script type="text/javascript" src="http://www.blogpeople.net/display/usr/0f0d42505b5dxxxx.js"></script></div>
<script type="text/javascript">
if(document.getElementById('blogpeople')){
    document.getElementById('blogpeople').innerHTML = document.getElementById('linklist').innerHTML;
}
</script>
</body>

赤色の部分が1項および2項で設定したid 属性値になります。1項・2項の id 属性値は任意ですが、設定した文字はこのサンプルのようにそれぞれ対応するよう反映させてください(id 属性値を変更する前にこのままお使いになることをお勧めします)。

4.CSS設定

スタイルシートに下記を追加します。

#linklist {
    display: none;
}

スタイルシートが編集できないブログサービスであればHTMLページの <head>~</head> の間に

<style type="text/css">
#linklist {
    display: none;
}
</style>

を追加すれば良いでしょう。

5.カスタマイズ

5.1 他の情報を埋め込む場合

「私を登録」等のリンクやバナー等を表示する場合は、それらを2項のタグにまとめて記述しておくと良いでしょう。1項のタグに記述することもできますが、その場合は、元の div 要素の中ではなく、

<div id="blogpeople"></div>
[ここに記述]

となります。スタイルを与える場合はさらに div 要素等で括ってください。

5.2 複数のリンクリストを表示する場合

このカスタマイズは設定を加えることで複数のリンクリストを表示することができます。
例えばドリコム RSS のリンクリストをさらに追加する場合、1項の id 属性名を変えたタグ

<div id="drecom"></div>

を作り、2項・3項の表示用スクリプトに下記の青色部分を追加します。id 属性名にご注意ください。

<div id="linklist"><script type="text/javascript" src="http://www.blogpeople.net/display/usr/0f0d42505b5dxxxx.js"></script></div>
<div id="linklist2"><script type="text/javascript" src="http://list.blog.rss.drecom.jp/yujiro/" charset="UTF-8"></script></div>
<script type="text/javascript">
if(document.getElementById('blogpeople')){
    document.getElementById('blogpeople').innerHTML = document.getElementById('linklist').innerHTML;
}
if(document.getElementById('drecom')){
    document.getElementById('drecom').innerHTML = document.getElementById('linklist2').innerHTML;
}
</script>
</body>

CSS は4項と同じもの(IDセレクタは #linklist2)を作ってください。3つ以上のリンクリストを表示する場合も同様の手順で追加します。

注:1項・2項の id 属性名はページ内で一意でなければいけません。

5.3 ローディング状態を表示

2項の設定に任意のテキスト文字、例えば、

<div id="blogpeople">Now loading...</div>

としておけば、リンクリスト表示までの間はローディング状態を表示することができます。ただしサーバからの応答がない場合は表示がずっと残ってしまいますのでご注意ください。


*1:全てのブラウザが同じ動作であるかについては未確認です。実際、Firefox/Opera ではストレスなく表示されます。
*2:IE以外での効果は未確認です。
*3:色覚障害等で色が識別できない場合は、サイト右上の「Styles」メニューにある Gray Scale をクリックしてください。IEではグレースケール表示され、青色部分が下線表示、赤色部分が二重下線で表示されます。Firefox/Opera ではカラー表示のままですが下線表示に切り替わります。なお設定の都合上、リンクとテキスト表示が判断できなくなりますので予めご容赦ください。

Comments [2] | Trackbacks [4]
2006年9月28日

ドラッグ&ドロップできるサイドメニューの折りたたみ(その2:ブログへの適用)

September 28,2006 2:00 AM
Tag:[, ]
Permalink

ドラッグ&ドロップできるサイドメニューの折りたたみその1では Docking boxes の基本的な設定方法を紹介しましたが、今回は当サイトの公開テンプレート(Movable Type/FC2ブログ)および Movable Type のデフォルトテンプレートに適用してみます。

他のブログサービスでも利用可能ですが、HTMLが編集可能・CSSファイル/JavaScriptファイル/画像ファイルがアップロード可能・HTMLにあるサイドバーの各サイドメニューが独立して編集できること、が条件です。

Movable Type の公開テンプレートおよびデフォルトテンプレートを利用したサンプルを作成しましたので、動作をご確認ください。

以下、カスタマイズ方法です。あわてて書いたため考慮もれ等あるかもしれません。説明通りに設定して正常に動作しない場合は適宜ご質問ください。

1.スクリプトのダウンロード

ドラッグ&ドロップできるサイドメニューの折りたたみ」の1項を参照ください。
なお dbx.css / dbx-key.js は本記事の4項および5項で指定したものをお使いください。

ダウンロードしたファイルは、Movabe Type の場合はメインページと同じディレクトリに、FC2ブログの場合は何も考えずにアップロードしてください(dbx.css は後述の画像ファイルをインクルードする関係で内容の修正が必要な場合があります)。

2.link 要素と script 要素の設定

アップロードした dbx.css / dbx.js / dbx-key.js をインクルードするための設定です。以下、各ブログでの設定内容を示します。

2.1 Movable Type の場合

<link rel="stylesheet" href="<$MTBlogURL$>dbx.css" type="text/css" />
              :
<script type="text/javascript" src="<$MTBlogURL$>dbx.js"></script>
<script type="text/javascript" src="<$MTBlogURL$>dbx-key.js"></script>

2.2 FC2 ブログの場合

<link rel="stylesheet" href="<%url>file/dbx.css" type="text/css" />
              :
<script type="text/javascript" src="<%url>file/dbx.js"></script>
<script type="text/javascript" src="<%url>file/dbx-key.js"></script>

3.HTML の設定

ここでは公開テンプレート(Movable Type / FC2 ブログ)および Movable Type デフォルトテンプレートを用いたサンプル(「最近のエントリー」と「最近のコメント」に Docking boxes を適用)を紹介します。
dbx-content 部分のタグ構造は ul - li を利用していますが、CSS(dbx.css)の設定で他のタグも利用可能と思います。ご自身で色々試してみてください。

3.1 公開テンプレートの場合

3.1.1 Movable Type
<div id="left" class="dbx-group">
 
<div class="dbx-box">
  <div class="dbx-handle">Recent Entries</div>
  <ul class="dbx-content">
    <MTEntries lastn="10">
      <li><a href="<$MTEntryPermalink$>" title="e<$MTEntryID$>"><$MTEntryTitle$></a></li>
    </MTEntries>
  </ul>
</div><!-- /dbx-box -->
 
<div class="dbx-box">
  <div class="dbx-handle">Recent Comments</div>
  <ul class="dbx-content">
    <MTEntries lastn="5" recently_commented_on="5">
      <li><a href="<$MTEntryLink$>"><MTEntryTitle></a>
        <ul>
        <MTComments lastn="5">
        <li><a href="<$MTEntryLink$>#c<$MTCommentID$>" title="c<$MTCommentID$>"><MTCommentAuthor></a> <$MTCommentDate format="%m/%d"$></li>
        </MTComments>
        </ul>
      </li>
    </MTEntries>
  </ul>
</div><!-- /dbx-box -->
 
</div><!-- /dbx-group -->
3.1.2 FC2 ブログ
<div id="left" class="dbx-group">
 
<div class="dbx-box">
  <div class="dbx-handle">Recent Entries</div>
  <ul class="dbx-content">
<!--recent-->
    <li><a href="<%recent_link>" title="<%recent_title>"><%recent_title></a> <span class="new"><%recent_year>:<%recent_month>:<%recent_day>:<%recent_hour>:<%recent_minute>:<%recent_second></span></li>
<!--/recent-->
  </ul>
</div><!-- /dbx-box -->
 
<div class="dbx-box">
  <div class="dbx-handle">Recent Comments</div>
  <ul class="dbx-content">
<!--rcomment-->
    <li><%rcomment_etitle><br />└<a href="<%rcomment_link>#c<%rcomment_no>" title="<%rcomment_body>"><%rcomment_title></a> <%rcomment_name> <%rcomment_month>/<%rcomment_day></li>
<!--/rcomment-->
  </ul>
</div><!-- /dbx-box -->
 
</div><!-- /dbx-group -->

3.2 Movable Type デフォルトテンプレートの場合

デフォルトの2カラムレイアウトの適用部分をまとめて示します。

   :
<div id="beta">
   <div id="beta-inner" class="pkg">
      <div class="module-search module">
         <h2 class="module-header">検索</h2>
         <div class="module-content">
            <form method="get" action="http://10.133.83.54/blog/MT-3.32-ja/mt-search.cgi">
               <input type="hidden" name="IncludeBlogs" value="1" />
               <label for="search" accesskey="4">ブログを検索: </label><br />
               <input id="search" name="search" size="20" />
               <input type="submit" value="検索" />
            </form>
         </div>
      </div>
      
   <div id="right" class="dbx-group">
      <div class="dbx-box">
         <div class="module-archives module">
            <div class="dbx-handle"><h2 class="module-header">最近のエントリー</h2></div>
            <ul class="dbx-content">
            <MTEntries lastn="10">
               <li class="module-list-item"><a href="<$MTEntryPermalink$>"><$MTEntryTitle$></a></li>
            </MTEntries>
            <li style="margin-left:-17px;list-style-type:none;"><a href="http://10.133.83.54/blog/MT-3.32-ja/atom.xml">このブログのフィードを取得</a><br />
            [<a href="http://www.sixapart.jp/about/feeds">フィードとは</a>]</li>
            </ul>
         </div>
      </div><!-- /dbx-box -->
 
      <MTIfArchiveTypeEnabled archive_type="Category">
      <div class="dbx-box">
         <div class="module-categories module">
            <div class="dbx-handle"><h2 class="module-header">カテゴリー</h2></div>
            <MTTopLevelCategories>
            <MTSubCatIsFirst><ul class="dbx-content"></MTSubCatIsFirst>
               <MTIfNonZero tag="MTCategoryCount">
               <li class="module-list-item"><a href="<$MTCategoryArchiveLink$>" title="<$MTCategoryDescription$>"><MTCategoryLabel></a>
               <MTElse>
               <li class="module-list-item"><MTCategoryLabel>
               </MTElse>
               </MTIfNonZero>
                  <MTSubCatsRecurse>
               </li>
            <MTSubCatIsLast></ul></MTSubCatIsLast>
            </MTTopLevelCategories>
         </div>
      </div><!-- /dbx-box -->
      </MTIfArchiveTypeEnabled>
 
      <MTIfArchiveTypeEnabled archive_type="Monthly">
      <div class="dbx-box">
         <div class="module-archives module">
            <div class="dbx-handle"><h2 class="module-header"><a href="http://10.133.83.54/blog/MT-3.32-ja/archives.html">アーカイブ</a></h2></div>
               <MTArchiveList archive_type="Monthly">
                  <MTArchiveListHeader><ul class="dbx-content"></MTArchiveListHeader>
                     <li class="module-list-item"><a href="<$MTArchiveLink$>"><$MTArchiveTitle$></a></li>
                  <MTArchiveListFooter></ul></MTArchiveListFooter>
               </MTArchiveList>
            </div>
         </div>
      </div><!-- /dbx-box -->
      </MTIfArchiveTypeEnabled>
   </div><!-- /dbx-group -->
   :

4.CSS の設定

下記のリンクよりそれぞれの dbx.css をダウンロードしてお使いください。

公開テンプレートは styles-site.css の下記の部分を変更しています(赤色を削除・青色を追加)。

/* 順序なしリスト */
ul, ol {
    padding-left: 16px;
}
ul li {
    list-style-type: none;
    padding-left: 10px;
    background: url(images/lmark.gif) no-repeat 1px 0.5em;
}

5.JavaScript の設定

下記のリンクよりそれぞれの dbx-key.js をダウンロードしてお使いください。

基本的に配布サイトの dbx-key.js でも構いませんが、コンテナIDの部分が3項で設定したHTMLタグの id 属性値と一致するようにしてください(詳細は「その1」の5項参照)。

6.折りたたみマークの設定

サンプルで使っているものを配布しますので、よければご利用ください。
下記の折りたたみマーク画像を右クリックして「名前をつけて画像を保存」を選択するとダウンロードできます。

デフォルトテンプレート用
折りたたみマーク
公開テンプレート用
折りたたみマーク

ダウンロードした画像ファイルは適宜アップロードしてください。サンプルでは Movable Type のディレクトリを想定して、mt-static/images 配下にアップロードしています。FC2はファイルのアップロード機能を利用してください。

アップロードしたパスは、 dbx.css の a.dbx-toggle セレクタの background 属性(青色)

/* toggle images */
a.dbx-toggle, a.dbx-toggle:visited {
    display:block;
    width:20px;
    height:20px;
    overflow:hidden;
    background:url(mt-static/images/toggle.gif) no-repeat;
    position:absolute;
    top:0px;
    right:0;
    text-indent:-50px;
    text-decoration:none;
    }

に反映する必要があります。

パスはアップロードするディレクトリによって適宜変更してください。また上記の設定例では dbx.css と異なるディレクトリに配置されているページからは画像を表示することができませんので、パスは URL で指定してください。
FC2ブログの場合も同様です。

Comments [2] | Trackbacks [0]
2006年9月27日

ドラッグ&ドロップできるサイドメニューの折りたたみ(その1:基本設定)

September 27,2006 2:22 AM
Tag:[, ]
Permalink

ドラッグ&ドロップできるサイドメニューの折りたたみDocking boxes」という、JavaScript + CSS でサイドメニューの折りたたみとドラッグ&ドロップを実現したスクリプトの紹介です。WordPress をお使いの方は管理画面で利用されているのでご存知の方も多いのではないかと思います。
本記事では一般的な設定方法を紹介し、「その2:ブログへの適用」で Movable Type 等への設置方法について説明します。

配布元にサンプルがありますのでお試しください。

1.スクリプトのダウンロード

Docking boxes(dbx) のページの「Get the Script」からアーカイブをダウンロードします。アーカイブを解凍した中から下記のファイルのみを使用します。

  • dbx.css(または dbx-allrules.css)
  • dbx.js
  • dbx-key.js

他のファイルおよび画像はサンプルのためのものです。全てをアップロードして各HTMLにアクセスすればサンプルを確認できます。

2.link 要素と script 要素の設定

Docking boxes を使用したいテンプレートの <head> ? </head> の間に下記を追加します。

<link rel="stylesheet" href="dbx.css" type="text/css" />
              :
<script type="text/javascript" src="dbx.js"></script>
<script type="text/javascript" src="dbx-key.js"></script>

dbx.css / dbx.js./ dbx-key.js とパスが異なるページで利用する場合は dbx.css / dbx.js./ dbx-key.js に URL を指定します。

3.HTML の設定

Docking boxes の HTML マークアップは下記の構造になります。

<div id="menu1" class="dbx-group">
    <div class="dbx-box">
        <div class="dbx-handle">サイドメニュー1</div>
        <ul class="dbx-content">
            <li>リスト1-1</li>
            <li>リスト1-2</li>
              :
              <li>リスト1-n</li>
        </ul>
    </div>
    <div class="dbx-box">
        <div class="dbx-handle">サイドメニュー2</div>
        <ul class="dbx-content">
            <li>リスト2-1</li>
            <li>リスト2-2</li>
              :
              <li>リスト2-n</li>
        </ul>
    </div>
   :
</div>

Docking boxes は各要素に設定した class 属性(青色)によって動作します。それぞれの class 属性値は次の役割をもっています。

  • dbx-group:Docking boxes を使用したい箇所に指定
  • dbx-box:サイドメニュー(最近のエントリー・最近のコメント等)単位に指定
  • dbx-handle:サイドメニュータイトルに指定
  • dbx-content:サイドメニューのリストに指定

ポイント

  • dbx-group は赤色で示した id 属性と対応し(後述)、複数指定できます
  • サンプルの dbx-content は ul 要素ですが、div 要素と p 要素の組み合わせ等でも大丈夫です

4.CSSの設定

サイドメニューのスタイルは dbx.css で設定します。dbx-allrules.css がデフォルトで利用するための(空の)CSS ですが、ここではサンプル用で設定されている dbx.css を用いて説明します。
以下、ファイルを上から順に見ていく形で説明します(CSSハック等、一部省略しています)。

以下のコードは変更や上書きをしてはいけません。

/****************************************************************
  docking boxes core CSS: YOU MUST NOT CHANGE OR OVERRIDE THESE 
*****************************************************************/
.dbx-clone {
    position:absolute;
    visibility:hidden;
}
.dbx-clone, .dbx-clone .dbx-handle-cursor {
    cursor:move !important;
}
.dbx-dummy {
    display:block;
    width:0;
    height:0;
    overflow:hidden;
}
.dbx-group, .dbx-box, .dbx-handle {
    position:relative;
    display:block;
}

dbx-box と clone(=ドラッグ中のサイドメニュー)の間の視覚違いをなくすために、dbx-box への padding、marginまたはborderの設定は避けてください。視覚的に、dbx-box はスタイルを設定しない方が良いでしょう。

/****************************************************************
  avoid padding, margins or borders on dbx-box, 
  to reduce visual discrepancies between it and the clone.  
  overall, dbx-box is best left as visually unstyled as possible 
*****************************************************************/
.dbx-box {
    margin:0;
    padding:0;
    border:none;
}

その他(以下)は自由に設定してください。

/****************************************************************
  otherwise, do what you like :) 
*****************************************************************/
             :

#purple-outer はサンプルの dbx.html 用なので削除します。
dbx-group は width / background / padding プロパティでサイドバー全体の幅・背景・パディングを調整しています。

/* group container(s) */
#purple-outer {
    border:1px solid #a382c0;
    margin:0 10px 0 0;
    float:left;
    position:relative;/* additional outer containers must also have position:relative */
    }
.dbx-group {
    clear:both;
    width:150px;
    background:#c5a4e0;
    padding:0 10px 10px 10px;
    }

dbx-handle でサイドメニューのタイトル部分のスタイルを指定します。cursor プロパティはドラッグ位置にマウスオーバーした時に表示するカーソル(move は十字矢印)を指定します。

/* handles */
.dbx-handle {
    font:normal normal bold 1em tahoma,sans-serif;
    text-align:center;
    position:relative;
    margin:0;
    padding:16px 0 6px 0;
    background:url(images/purple-handle.gif) no-repeat 0 0; 
    color:#fff;
    }
 
/* handle cursors are in a class of their own
   so they only get applied if the script is supported */
.dbx-handle-cursor {
    cursor:move;
    }

a.dbx-toggle は折りたたみマークのスタイルを指定します。サンプルの折りたたみマークは次のようなもので、4種類の状態を表せるようになっています。

折りたたみマーク

  • 左上:開いている時
  • 右上:開いている時にフォーカス
  • 左下:閉じている時
  • 右下:閉じている時にフォーカス

CSS に精通されている方は有名なテクニックとですが、ひとつの画像フィイルに複数の画像をまとめておくことで、ページ表示に全ての画像がロードされるので、画像の表示切り替え時にタイムラグが発生しません。
画像の切り替えは、次の5つのセレクタのうち、下の4つがそれぞれの状態に対応しており、画像の表示位置をずらすことで表示する画像を切り替えます。

「クロスブラウザを保つために、デフォルトと visited 疑似クラスを一緒に定義すべきです」という説明がされています。

/* toggle images */
a.dbx-toggle, a.dbx-toggle:visited {
    display:block;
    width:20px;
    height:20px;
    overflow:hidden;
    background:url(images/purple-toggle.gif) no-repeat;
    position:absolute;
    top:14px;
    right:3px;
    text-indent:-50px;
    text-decoration:none;
    }
     
     
a.dbx-toggle-open, a.dbx-toggle-open:visited {
    background-position:0 0;
    }
a.dbx-toggle-closed, a.dbx-toggle-closed:visited {
    background-position:0 -20px;
    }
a.dbx-toggle-hilite-open, a.dbx-toggle-hilite-open:visited {
    background-position:-20px 0;
    }
a.dbx-toggle-hilite-closed, a.dbx-toggle-hilite-closed:visited {
    background-position:-20px -20px;
    }

dbx-tooltip はツールチップのスタイルです。

/* keyboard navigation tooltip */
.dbx-tooltip {
    display:block;
    position:absolute;
    margin:36px 0 0 125px;
    width:185px;
    border:1px solid #000;
    background:#ffd;
    color:#000;
    font:normal normal normal 0.85em tahoma, arial, sans-serif;
    padding:2px 4px 3px 5px;
    text-align:left;
    }

dbx-content はメニューリストのスタイルを設定します。

.dbx-content li {
    width:130px;
    margin:0;
    padding:0 10px 1px 10px;
    list-style-type:none;
    font:normal normal normal 0.85em verdana,sans-serif;
    background:url(images/purple-content.gif) #bca2cf repeat-y;
    }
 
.dbx-content a, .dbx-content a:visited {
    color:#000;
    text-decoration:none;
    }
 
.dbx-content a:hover, .dbx-content a:focus, .dbx-content a:active {
    color:#306;
    text-decoration:underline;
    }

下はメニューリストが閉じている時のリストスタイルです。

/* toggle state of inner content area */
.dbx-box-closed .dbx-content {
    display:block;
    height:10px;
    padding:0;
    overflow:hidden;
    }

dbx-clone クローンはドラッグしている時のリストです。サンプルでは透過するようにしています。この設定を削除するとドラッグしている時に、下に隠れるオブジェクトが見えなくなります。

/* additional clone styles */
.dbx-clone {
    opacity:0.8;
    -moz-opacity:0.8;
    -khtml-opacity:0.8;
    filter:alpha(opacity=80);
    }

5.JavaScript の設定

dbx-key.js に、3項で設定した id 属性(赤色)に対応するオブジェクトを作成します。それらしき役割を日本語で示しておきます。青色の hogehoge は任意の名称でいいみたいです。コンテナIDが id 属性になります。

//create new docking boxes group
var hogehoge = new dbxGroup(
    'menu1',     // コンテナID [/-_a-zA-Z0-9/]
    'vertical', // ドラッグ方向 ['vertical':縦|'horizontal':横]
    '7',        // ドラッグ開始する移動ピクセル(マウスが指定px移動するとドラッグ開始)['n' pixels]
    'no',       // コンテナのドラッグ範囲外への移動許可 ['yes'|'no']
    '10',       // ドラッグ時, 他のサイドバーが移動するアニメーション効果(フレーム数指定, '0'は効果なし)
    'yes',      // 開閉ボタン表示(非表示の場合、開閉不可) ['yes'|'no']
    'open',     // 開閉のデフォルト状態 ['open'|'closed']
    'open',     // 閉じている時に下の %toggle% に挿入するメッセージ
    'close',    // 開いている時に下の %toggle% に挿入するメッセージ
    'click-down and drag to move this box',    // ドラッグエリアにマウスオーバーした時のツールチップ
    'click to %toggle% this box',              // 開閉エリアにマウスオーバー時のツールチップ
    'use the arrow keys to move this box',     // ドラッグエリアのキーボード操作時のツールチップ
    ', or press the enter key to %toggle% it', // 開閉エリアにキーボード操作時のツールチップ
    '%mytitle%  [%dbxtitle%]'                  // title属性が競合した場合(?)
    );

サイドバーを左右に配して、どちらもドラッグ&ドロップできるようにするには、上と同じオブジェクト(hogehoge)をもうひとつ作ります('hogehoge2' 等)。コンテナID(menu1)は必ず変えて、変えたコンテナIDが id 属性となるようにHTMLマークアップを行ってください。

6.注意事項

リストマークはクリックを契機に大きくなってしまう現象が起きるので、list-style-type で指定したマークが大きくなるので background 指定すると良いでしょう。

Comments [4] | Trackbacks [0]
2006年8月 2日

カレンダースクリプト不具合のお知らせ

August 2,2006 4:07 PM
Tag:[, ]
Permalink

当サイトで公開している「休日表示付きカレンダースクリプト」について、コメントで「8月の本日表示ができません」という頂き、調査したところ、スクリプトの不具合であることが判明しました。ご迷惑をおかけして大変申し訳ございません。

原因は、本日の日付を判定する際、月の判定に parseInt() を利用しているのですが、この関数の第2引数に進数指定をしておらず、このため8月および9月の場合、正しい値が取得できなかった("0"を取得)ようです。

参考:JavaScript コラム『parseInt()について』

お急ぎの方は dayChecker.js に対し、下記の修正を行ってください。

修正前

function isToday(year, month, day) {
    if (year == currentYear && parseInt(month) == currentMonth && day == currentDay) {
        return true;
    }
    return false;
}

修正後

function isToday(year, month, day) {
    if (year == currentYear && parseInt(month,10) == currentMonth && day == currentDay) {
        return true;
    }
    return false;
}

ダウンロードスクリプトにつきましては、修正ができ次第このエントリーでお知らせ致します。

Comments [6] | Trackbacks [1]
2006年6月26日

サイドバーの折りたたみ

June 26,2006 2:02 AM
Tag:[, , ]
Permalink

マルチカラムレイアウトでサイドバーを丸ごと折りたたむカスタマイズを紹介します。動作は Windows XP+IE6.0/Firefox1.5/Opera8.0 で確認しています。
下記にサンプルを用意しましたのでお試しください。

サイドバーの折りたたみサンプル

タイトル下の両端にあるリンクをクリックすると、サイドバーの表示・非表示が切り替わります。また折りたたみ時にリンクの内容を変更することができます。サンプルは3カラムですが、2カラムレイアウトでの折りたたみも可能です。

1.動作条件

下記の条件で動作します。

  • cookieが有効であること
  • 固定レイアウト(3カラムおよび2カラム)であること

また公開テンプレートで動作するように設定していますので、公開テンプレート以外でご利用になる場合はスクリプトを修正する必要があります。

2.機能概要

下記のような動作でサイドバーを折りたたみます。

  1. 折りたたみ用リンクをクリック
  2. JavaScript起動
  3. cookieより現在のレイアウト名を取得
  4. クリックされたリンク位置(右または左)と現在のレイアウトを判定し、新しいレイアウトに変更
  5. カラム幅がどのレイアウトでも同一になるように、レイアウトに応じて中央カラム幅を変更
  6. 変更したレイアウトに応じてクリックされたテキストリンクを変更
  7. 変更したレイアウト名をcookieに保持

3.ドネーション

カスタマイズ内容のご利用および質問に対する回答等について、ご支援・ご賛同くださる方からの寄付をお待ち申し上げます。
将来に向けてのご寄付(例:ドネーションによる機能追加や改善要望)は、それらが実現しない可能性があるため、ご遠慮ください。

  • 現状のコンテンツで役立った
  • 質問の回答で疑問や不具合が解消された
  • エントリーの修正等で要望内容が満たされた

等の後に判断して頂ければ結構です。
参考:Web投げ銭

上記の「寄付」のリンクをクリックすると Paypal によるお支払いページにジャンプします。

4.スクリプトのダウンロード・アップロード

下記のリンクより sidebarfolder.js をダウンロードし、ご利用のブログのディレクトリにアップロードしててください(ブログツール・ブログサービスによってアップロード先は若干異なります)。

sidebarfolder.js

なお、このスクリプトの先頭に使用するレイアウトを設定する行があります。

var layout = 'layout-three-column';

デフォルトは3カラムになっていますので、2カラムで利用する場合は下記のように変更してください。

2カラム(左サイドバー)

var layout = 'layout-two-column-left';

2カラム(右サイドバー)

var layout = 'layout-two-column-right';

5.テンプレートの修正(スクリプトのインクルード)

サイドバーの折りたたみを設定するテンプレートの <head> ? </head> の部分に下記を追加します。

Movable Type の場合

<script type="text/javascript" src="<$MTBlogURL$>sidebarfolder.js"></script>

Serene Bach の場合

<script type="text/javascript" src="{site_top}sidebarfolder.js"></script>

FC2ブログの場合

<script type="text/javascript" src="<%url>file/sidebarfolder.js"></script>

6.テンプレートの修正(折りたたみ用ナビゲーション追加)

6.1 3カラムレイアウトの場合

    :
<!-- タイトル -->
<div id="banner">
<h1 id="banner-header"><a href="<$MTBlogURL$>" accesskey="1"><$MTBlogName encode_html="1"$></a></h1>
<h2 id="banner-description"><$MTBlogDescription$></h2>
</div>
 
<div id="navi">
<ul><li id="leftmark"><a href="javascript:void(0);" onclick="changeSidebar('left');"><</a></li></ul>
<ul><li id="rightmark"><a href="javascript:void(0);" onclick="changeSidebar('right');">></a></li></ul>
</div>
 
<!-- 左カラム開始 -->
<div id="links-left-box">
<div id="links-left">
    :

6.2 2カラムレイアウト(左サイドバー)

下記を追加してください(6.1の追加部分を変更)。

<div id="navi">
<ul><li id="leftmark"><a href="javascript:void(0);" onclick="changeSidebar('left');"><</a></li></ul>
</div>

6.3 2カラムレイアウト(右サイドバー)

下記を追加してください(6.1の追加部分を変更)。

<div id="navi">
<ul><li id="rightmark"><a href="javascript:void(0);" onclick="changeSidebar('right');">></a></li></ul>
</div>

7.テンプレートの修正(JavaScript 追加)

サイドバーの折りたたみを設定するテンプレートの <head> ? </head> の部分に、A List Apart: Articles: Alternative Style: Working With Alternate Style Sheetsの一部を追加します。すでにご利用になっている場合は不要です。

<script type="text/javascript">
<!--
function createCookie(name,value,days) {
  if (days) {
    var date = new Date();
    date.setTime(date.getTime()+(days*24*60*60*1000));
    var expires = "; expires="+date.toGMTString();
  }
  else expires = "";
  document.cookie = name+"="+value+expires+"; path=/";
}
 
function readCookie(name) {
  var nameEQ = name + "=";
  var ca = document.cookie.split(';');
  for(var i=0;i < ca.length;i++) {
    var c = ca[i];
    while (c.charAt(0)==' ') c = c.substring(1,c.length);
    if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
  }
  return null;
}
//-->
</script>

8.スタイルシート修正

スタイルシートに下記を追加します。

#navi {
    padding: 3px;
    border-bottom: 1px solid #666699;
    text-align:center;
    font-size: 12px;
}
#navi ul {
    margin: 0;
    padding: 0;
    display: inline;
}
#navi ul li {
    display: inline;
}
#leftmark {
    margin-right: 395px;
}
#rightmark {
    margin-left: 395px;
}
Comments [8] | Trackbacks [1]
2006年5月 8日

ブログタイトルを分割してCSSで異なるスタイルを設定する

May 8,2006 11:53 PM
Tag:[, , ]
Permalink

ブログタイトルは Movable Type/Serene Bach 等のブログツールや FC2ブログ/Seesaa ブログ等のブログサービスに関わらず、HTMLページとしては概ね下記のようなマークアップが生成されます。

<h1><a href="~">First Weblog</a></h1>

つまりこのブログタイトルは、ツールがHTMLを自動生成するため、文字の途中にHTMLタグを埋め込んで任意のスタイルを設定する、というようなことができません。

ブログタイトルを分割して異なるスタイルを設定するこのエントリーでは、ブログタイトルを2分割して前半と後半で異なるスタイルを設定可能にするカスタマイズをご紹介します。
このカスタマイズを行うことでスクリーンショットのように「First Weblog」という文字に対して、「First」と「Weblog」に異なるスタイルを設定することができます。

1.スクリプトの追加

必要なテンプレートに下記のスクリプトを追加します。挿入位置は任意ですが、必ず h1 タグよりも後方に挿入してください。

<script type="text/javascript">
//<![CDATA[
var number = 5;
var title = (document.getElementsByTagName('h1'))[0].childNodes[0].innerHTML;
(document.getElementsByTagName('h1'))[0].childNodes[0].innerHTML =
'<span class="titleA">' + title.toString().substring(0,number) + '</span>' + '<span class="titleB">' + title.toString().substring(number) + '</span>';
//]]>
</script>

赤色の数字は分割する任意の文字数を設定します。「5」の場合は最初の5文字と残りの文字に分割します。全角・半角それぞれ1文字を「1」として計算してください。Windows のIE/Firefox/Opera では全角・半角混合のタイトルでも正常に分割することを確認しています。

2.スタイルの追加

スタイルシートに下記の設定を追加します。

.titleA {
    color: #ffffff;
}
.titleB {
    color: #000000;
}

titleA が文字前半、titleB が文字後半のスタイルに対応します。上記は文字色のみの設定ですが、フォントやフォントサイズ等の各種文字装飾を追加すれば、バリエーション豊かな表示が可能になります。

3.タイトルを 3 分割する

1項のスクリプトを下記のように修正します。追加部分を青色で示していますが、そのままコピーしてください。

<script type="text/javascript">
//<![CDATA[
var number1 = 3;
var number2 = 6;
var title = (document.getElementsByTagName('h1'))[0].childNodes[0].innerHTML;
(document.getElementsByTagName('h1'))[0].childNodes[0].innerHTML =
'<span class="titleA">' + title.toString().substring(0,number1) + '</span>' + '<span class="titleB">' + title.toString().substring(number1,number2) + '</span>' + '<span class="titleC">' + title.toString().substring(number2) + '</span>';
//]]>
</script>

スタイルシートも追加します。

.titleA {
    color: #ffffff;
}
.titleB {
    color: #000000;
}
.titleC {
    color: #ff0000;
}

2007.01.10 追記
3項を追加しました。

Comments [3] | Trackbacks [0]
2005年12月19日

表示するデータを周期的に切り替える

December 19,2005 11:56 PM
Tag:[, ]
Permalink

お知らせ等のちょっとしたデータの表示を周期的に切り替えるカスタマイズです。サンプルでは3秒周期でデータを切り替えるように設定しています。テンプレートに依存しませんので、JavaScript が使えればどのツールでも利用可能です。

以下、カスタマイズ方法です。

1.本文の設定

テンプレートの任意の位置、例えばお知らせに使用するのであれば、中央カラム上部等に下記の設定を挿入します。

<div id="info1">
お知らせ1
</div>
 
<div id="info2">
お知らせ2
</div>
 
<div id="info3">
お知らせ3
</div>

例は3種類のお知らせ用フォーマットを用意していますので、青色の部分にお好きな内容を設定してください。

2.イベントハンドラの設定

body 要素に青色のように onload イベントハンドラの設定をします。

<body onload="setInterval('changeLink()',10000)">

中に設定されている「10000」の部分は、msec(1/1000秒)を表す単位を設定します。「10000」は10秒周期を示しています。setInterval は JavaScript で用意された関数で、起動する関数と、周期を設定します。onload イベントハンドラでこの設定が実行されます。

3.スクリプトの設定

1項で設定した部分のすぐ下に、下記のスクリプトを追加します。

<script type="text/javascript">
var max = 3;
var n = 1;
function changeLink() {
    for(i = 1; i < max+1; i++){
        document.getElementById('info'+i).style.display = 'none';
    }
    if(!n || n > max) n = 1;
    document.getElementById('info'+n).style.display = 'block';
    n++;
}
changeLink();
</script>

4.フォーマットを増やす

フォーマットを増やす場合は、1項で設定した本文の下に、

<div id="info4">
お知らせ4
</div>
 
<div id="info5">
お知らせ5
</div>
    :

という具合に、同じタグ構造のものを追加します。赤色の n には上から順番に数字を振ってください。最初のリストでは info3 まで割り振られているので、新しく追加する場合は順に info4、info5、… と割り振ります。

それから、フォーマットの合計数を、3項の2行目にある max の右辺に設定します。5種類のフォーマットを表示する場合は

var max = 3;

となっている部分、下記のように

var max = 5;

「5」に修正してください。

5.注意事項

アフィリエイトの商品リンク切り替えに使用される場合、利用規定で禁止されている場合もありますので、十分ご注意ください。

6.その他

2項のイベントハンドラの設定を行わずに、setInterval を3項のリストの最後に追加して

   :
changeLink();
setInterval('changeLink()',10000)";
</script>

とする手もあります。

Comments [0] | Trackbacks [0]
2005年11月23日

商品リンクをランダムに切り替える

November 23,2005 11:57 PM
Tag:[]
Permalink

Amazon 等の商品リンクをランダムに切り替えて表示する方法です。具体的な動作は、JavaScript の乱数を利用して、ページを表示する毎に乱数に対応する id 属性で括られたHTML(=商品リンク)を表示するという方法です。当サイトのエントリー・アーカイブで試しに使っています。
以下、設定方法です。

まず表示したい商品のリンクを、テンプレートの任意の位置に並べて記述します。その際、リストのように id 属性を付与してください。ここでは amazon0、amazon1、amazon2 という名称にしています。属性名につけられた数字は必須で、0 から開始させてください。ここではリンクを3つにしていますが、いくつ作って構いません。

<div id="amazon0">
商品Aのリンク
</div>
<div id="amazon1">
商品Bのリンク
</div>
<div id="amazon2">
商品Cのリンク
</div>

次に、商品リンクの下に下記の JavaScript を追加してください。赤色部分に商品リンクの合計数を設定します。サンプルでは3つの商品を記述していますので、「3」を設定します。

<script type="text/javascript">
n = Math.floor(Math.random() * 3);
for(i = 0; i < 3; i++){
    document.getElementById('amazon'+i).style.display = 'none';
}
document.getElementById('amazon'+n).style.display = 'block';
</script>

保存・再構築すれば完成です。設定したページをリロードして、商品リンクが切り替わることを確認してください。
なお id 属性名を hogehoge0、hogehoge1… という風に設定したい場合は、リスト内の amazon という文字を

    document.getElementById('amazonhogehoge'+i).style.display = 'none';
}
document.getElementById('amazonhogehoge'+n).style.display = 'block';

と変更してください。

Comments [4] | Trackbacks [1]
2005年11月10日

JavaScript エラーを解消する

November 10,2005 11:50 PM
Tag:[]
Permalink

JavaScriptエラーWindows IE6.0 でページを表示した時、ステータスバー左下に画像のような黄色いアイコンと「ページでエラーが発生しました」という情報が表示されることがあります。これがいわゆる「JavaScript エラー」で JavaScript の実装に問題があることを示しています。
エラーが発生するのは体裁の良いものではなく、場合によってはページが正常に表示されない場合もありますので、できれば解消したいところです。

ということで、JavaScript エラーの解消方法をご紹介します。ただしエラーを解消するには JavaScript の修正を伴うケースが少なくないため、プログラミングが苦手な方については原因発見までとなります(後はスクリプト配布元に問い合わせましょう)。

1.エラー詳細の表示

IEのJavaScriptエラー詳細IEの場合、JavaScript エラーが発生している状態でステータスバーに表示されている部分をダブルクリックすると左のようなダイアログが開き、そこにJavaScript エラーの詳細が表示されます(表示されていない場合は[詳細の表示]をクリックします)。
Firefox であれば [ツール]-[JavaScript コンソール] を選択します。Netscape7.1 は[ツール]-[Web開発]-[JacaScriptコンソール]です。Opera8 は[ツール]-[詳細ツール]-[JavaScriptコンソール]です。
以下、利用者が多く、エラーの確認が一番分かりやすい(と思われる) Firefox によるエラー原因の確認方法を説明します。

2.エラー原因の確認

FirefoxのJavaScriptエラー詳細Firefox で[ツール]-[エラーコンソール]を選択すると画像のようなダイアログが開き、現在のページで発生している JavaScript エラーが表示されます。何も表示されなければそのページに問題はありません(ただし4項に例外を記しています)。
この時、エラーコンソール左上のメニューが[すべて] または [エラー]が選択されている状態にしてください。[警告]や[メッセージ]ではエラーが表示されません。また エラーコンソールを開くと、それまでのページ表示で発生したエラーがすべて表示される可能性があります。この場合はコンソール右側にある[クリア] をクリックして情報を一旦クリアし、ページをリロードすれば現在のページのエラーだけが表示されます。

サンプルでは「func is not defined」というエラーが表示されています。これは 「func というスクリプトを起動しようとしているが、func 自体がみつからない」ということを示すエラーです。このようなエラーが発生した場合は、func というスクリプトが記述されている外部ファイルが正常に読み込まれていないか、あるいは起動元のスクリプト(関数)名が誤っていないか等を確認しましょう。

FirefoxのJavaScriptエラー詳細 また左の「element has no properties」というエラーは、「スクリプトは存在するが処理が誤っている」というエラーです。エラー画面のURL部分をクリックするとエラーとなっているファイルを表示し、エラー発生箇所を反転表示してくれます(下はその抜粋です)。

FirefoxのJavaScriptエラー詳細

具体的には、hogehoge という ID属性のスタイルを非表示にしようとしているのですが、hogehoge という ID属性自体が存在しないため、element という変数には何も設定されません。で、次の行で何も設定されていない変数(=スタイル)のプロパティを制御しようとしているためエラーになります。
この場合はスクリプトに hogehoge という ID属性がページに存在しないケースを考慮する if 文を追加して

function func() {
    element = document.getElementById("hogehoge");
    if (element) {
        element.style.display = 'none';
    }
}

とします。スクリプト修正後、コンソール右側にある[クリア] をクリックして情報を一旦クリアしてからブラウザを更新すればエラーは解消します。

3.外部ファイルが存在しない場合のエラーを発見する

下記リストのように JavaScript を外部ファイルとして読み込む場合があります。

<script type="text/javascript" src="http://www.koikikukan.com/menufolder.js"></script>

この menufolder.js 自体が存在しない場合、外部ファイルに書かれたスクリプトを起動する箇所で JavaScript エラーが発生し、結果的に外部ファイルが正常に読み込まれていないことが分かります。が、外部ファイルを単に読み込むだけで、ファイルに書かれたスクリプトをページで一切使用していない場合、Firefox のコンソールでは正常に読み込まれているかどうかまではチェックできません。

NetscapeのJavaScriptエラー詳細そもそも script タグ自体が冗長なのですが、Netscape7.1 の[ツール]-[Web開発]-[JavaScriptコンソール]を利用すれば、外部ファイルを引き込めない部分でエラーを発見することが可能です。Netscape では左図のように「syntax error」として表示され、リンクをクリックするとファイルが存在しない旨のHTMLソースが表示されます(IE/Firefox/Opera ではエラーは表示されませんでした)。

Netscape であれば2項のエラー解析も Firefox と同様の操作が可能なので、JavaScript エラー解消には Netscape7.1 をお勧めします。

2007.02.02 追記
Firefox の記述を Firefox 2 用に修正しました。

Comments [14] | Trackbacks [1]
Now loading...
Introduction
List of "JavaScript"
Recent Entries
Recent Comments
Recent Trackbacks
QRcode

現在停止中です
携帯電話からこのQRcodeを撮影することで携帯用URLを取得することができます

URI for cellular phones
ギターに入った猫
Styles
Font Size
Default
For defective color vision
Gray Scale
RGB Color
Search this site
loading ...
Categories
Monthly Archives
BlogPeople
Syndicate this site
FeedBurner(RSS1.0/RSS2.0/Atom)
Counter
これまでのアクセス
クリエイティブ・コモンズ・ライセンス
Powered by
Movable Type 5.12