2008/09/12

wordpressで簡単にthickboxを利用する方法

今までDOM操作は「基本を覚えるうちはベタ書きだ!」と、
jQueryやprototype等のライブラリを使わず、チマチマ書いてましたが、
まぁ、そろそろ次のステップに進もうかな、と。
まずはお手軽簡単jQueryから。

今までwordpressに記事を書くとき、画像を入れ込んだときは、別窓で開きたいなーと思って、
わざわざ投稿時にリンクタグに手入力でクラスを振ってました(‘A`)
で、このクラスを振るwordpressのプラグインをつくろうかなと思って挫折w
wp-admin\includes\media.phpを直接いじれば簡単なんですが、過去の記事とかは変更できないし。

なので、jQuery使っちゃうぞ。
まず本家からjQuery本体その他モロモロを拾ってきます。
thickbox.js
thickbox.css
loadingAnimation.gif
jquery-latest.js

ちなみにローディング用のgif画像はhttp://www.ajaxload.info/でお手軽簡単に好きなのが作れて(ι゜ω゜)ィィ・・

環境によってthickbox.jsの8行目あたりにあるloadingAnimation.gifへのパスを、
書き換えなきゃいけないと思います。
僕の場合、パーマリンクをちょいといじっているので、フルパスに書き換えました。

さて、テーマも変更します。
ヘッダ部分に以下の4行追加。

<link href="<?php bloginfo(’stylesheet_directory’); ?>/thickbox.css" rel="stylesheet" type="text/css" />
<script src="<?php bloginfo(’stylesheet_directory’); ?>/js/jquery.js" type="text/javascript" charset="utf-8"></script>
<script src="<?php bloginfo(’stylesheet_directory’); ?>/js/common.js" type="text/javascript" charset="utf-8"></script>
<script src="<?php bloginfo(’stylesheet_directory’); ?>/js/thickbox.js" type="text/javascript" charset="utf-8"></script>

common.jsは記事内のリンクにthickbox呼び出し用のクラスを追加するスクリプトです。
スクリプトの呼び出し順は必ずjQuery本体→初期化スクリプト→thickBoxの順じゃないとダメです。

common.jsに記述する初期化の内容は以下。

$(function(){
$("div.post a[href$='.jpg']").addClass("thickbox");
$("div.post a[href$='.gif']").addClass("thickbox");
$("div.post a[href$='.png']").addClass("thickbox");
$("div.post a[href$='.jpeg']").addClass("thickbox");
});

記事はdiv.post内にあるので、その中のjpgやpngなど、リンク先が画像のものにthickboxと言うクラスを付加しています。
以上。
あとは、/wp-content/themes/の自分の使ってるテーマの中にアップロードするだけ。
簡単(´・ω・`)
こんな感じ。

カテゴリー: JavaScript, Web Design, WordPress, jQuery — 2:07:46

2008/02/08

アクティブなメニューに自動でclassを付加する

グローバルメニューやサイドバーなんかで、
現在のページを示すために色を変える、なんて事をしたりしますが、
毎回これをどうやって楽にすべぇ、とか思ってました。
1ページ1ページに手作業でつけてくのも面倒だし、
ページが多くなればミスも増えそうです。

何よりこんな単純作業に時間を費やすぐらいなら、
お気に入りの音楽聴きながらコーヒー飲んでタバコ吹かしてるほうが100倍有意義ってもんです。

なので、アクティブなメニューにclassを付加するJavascriptを作ってみました。

考え方としては、ページ内のリンク先と、自ページとのアドレスを比較、
一致するならばクラスを付加って感じです。
大抵こういったメニューはリストなどで記述してると思うので、
今回はaタグに直接クラスをつけるのではなく、
親要素に対してクラスを付加してます。

まずはグローバルメニュー用

// グローバルメニュー用
function addActiveGlobal(){
if (!document.getElementsByTagName){
return;
}
var gMenu = document.getElementById(“global”);
if(!gMenu){
return;
}
var uri = location.href.split(‘#’)[0];
// index.html等ファイル名を無視する
var file= uri.substring(uri.lastIndexOf(‘/’,uri.length)+1,uri.length);
if(file.length>0){
uri = uri.split(file)[0];
}
var gLinks = gMenu.getElementsByTagName(“a”);
addActive(uri,gLinks.length, gLinks);
}

globalというID以下の要素に対し、処理を行います。
ページ内リンクの#は要らない子なので捨てます。
親コンテンツなので、下層のファイルに対してもアクティブである必要があります。
つまり、
example.com/hoge/
example.com/hoge/index.html
example.com/hoge/index2.html
example.com/hoge/example.html
これら全てでアクティブである必要があります。
なので、最後のスラッシュ以降の文字をsubstringで切り飛ばし、ディレクトリで判別する必要があります。
この処理だけちょっとめんどい。
あ、2階層以上潜るのは今回考えてません(‘A`)

// サブメニュー用
function addActiveURI(){
if (!document.getElementsByTagName){
return;
}
var sMenu = document.getElementById(“sidemenu”);
if(!sMenu){
return;
}
var uri = location.href.split(‘#’)[0];
var sLinks = sMenu.getElementsByTagName(“a”);
addActive( uri,sLinks. length, sLinks );
}

sidemenuというID以下の要素に対し、処理を行います。
サブメニューは自分だけでいいので、#以下を捨てる以外のアドレスの加工は要りません。
ただ、index.htmlなど、ファイル名が省略可能な場合、ちょっと注意が必要で、
他のページから、hoge/でリンクされてるのに、
自ページではhoge/index.htmlなどと書かれていると、
アドレスが一致しないことになってしまいます。
省略できるものは書くのか書かないのか、そこだけ取り決めをしておかないと切ないことになります。
まぁ、index.htmlやindex.phpなど、これらが出てきたら無視するって風に作ればいいんですが。

んで最後。

// クラス名付加共通パーツ
function addActive(uri,len,links){
for( var i=0; i<len ; i++){
if(links[i].href == uri){
var parentObj= links[i].parentNode;
if(parentObj.getAttribute(“class”)){
var oldClass = parentObj.getAttribute(“class”)
parentObj.setAttribute( “class”, “active ” + oldClass);
}
else if(parentObj.getAttribute(“className”)){
var oldClass = parentObj.getAttribute(“className”)
parentObj.setAttribute(“className”, “active ” + oldClass);
}
}
}
}

IEだけはclass名を取得するときclassNameじゃないとダメなので、面倒ですが2個記述。
setAttributeでクラス名をそのままセットしてしまうと、今まで付いてたクラス名が上書きされてしまうので、
一旦保存しておいて、今回付加するactiveというクラス名と文字列連結してセットしてあげます。
activeのあとに半角スペースを入れておかないと文字がつながってしまうので、
そこだけ注意。

そんな訳で出来たもの。
グローバルメニューは赤、サイドメニューは緑になります。
サンプル
javascript
Firefoxの方は、最初にそのままソースを表示、
次に、ctrl+Aを押して全選択したあと選択部分のソースを表示ってな風にしてもらうと、
違いが分かるかもしれません(゜ヮ゜)
  _、_ 
( ,_ノ` ) じゃあ、コーヒーを頂こうか。
     ζ
    [ ̄]’E
      ̄

カテゴリー: JavaScript, Web Design, XHTML — 0:42:58

2008/01/24

イベントリスナーをかっちょよく実装する。

今、このブログではJavaScriptのトリガーにwindow.onloadを使用してましたが、
あんまりオススメじゃないというか、スマートじゃないとか、そんな感じらしい(‘A`)
addEventListenerを使え!ってな感じの話を聞いたので、
ちょいとオサレに実装を!

/***************************************
addEvent
***************************************/
function addEvent(elm, evType, fn, useCapture) {
if (elm.addEventListener) {
elm.addEventListener(evType, fn, useCapture);
return true;
}
else if (elm.attachEvent) {
var r = elm.attachEvent(‘on’ + evType, fn);
return r;
}
else {
elm['on' + evType] = fn;
}
}

function hoge() {
window.alert(“hogeが呼ばれたよ\(^o^)/”);
}
addEvent(window,’load’,hoge,false);

こんな感じかな?

↓を増やしてけば何ぼでもいけます。
addEvent(window,’load’,ここに実行したいファンクション,false);

今までは

function initFunctions(){
hoge1();
hoge2();
hoge3();
}
window.onload = initFunctions;

てな感じで1つ余計に咬ませてたし。
addEvent()を共通で読んでおけばどこででも呼び出せてちょっと便利かな?

カテゴリー: JavaScript, Web Design, XHTML — 4:05:43

2007/09/03

javascriptで画像置換え

スタイルシートでtextindent:-9999pxとかやりつつ、
背景に画像を置くのが一番手軽ではあるけれど、
画像Offだとまったく見えなくなるとか、あるいは印刷時に印刷されないとか、
手軽な反面、いろいろと罠が潜んでいるから困る。

んで、普通に単なる画像にしても良いんだけど、例えば、
list.gif
みたいなリストなどの場合、画像1枚貼って終わらせるより

<h2>お気に入り戦闘機</h2>
<ul>
<li>F-15</li>
<li>F-14</li>
<li>Su-37</li>
</ul>

とかやりたいわけで。

さてこれをどうしよう。
ということで、いっそjavaScriptで画像に置き換えてやれば良いのではないかと。
コードはこんな感じ・・・かな?

function imgReplace(){
var imgRepList = getElementByClassName(‘img_swp’);
var imgHeight;
var imgWidth;
for( var i=0, j=imgRepList.length; i<j; i++){
var altTxt = imgRepList[i].textContent||imgRepList[i].innerText;
var myId = imgRepList[i].id;
var chg = document.getElementById(myId);

var repImg= new Image();
repImg.src = “img/”+myId+’.gif’;

if(repImg.src){
var newImg= document.createElement(‘img’);

newImg.setAttribute(’src’,repImg.src);
newImg.setAttribute(‘alt’,altTxt.replace(/\s/g, “”));

if(imgHeight!=0 && imgWidth!=0 ){
newImg.setAttribute(‘height’,imgHeight);
newImg.setAttribute(‘width’,imgWidth);
}

if(chg.tagName == “DL” ||
chg.tagName == “OL”||
chg.tagName == “UL”){
var newP = document.createElement(‘p’);
var boxParent = chg.parentNode;
boxParent.replaceChild (newP,chg);
newP.setAttribute(“class”,chg.getAttribute(“class”)||chg.getAttribute(“className”));
newP.setAttribute(“id”,chg.getAttribute(“id”));
chg = newP;
}
else{
var newP = document.createElement(chg.tagName);
var boxParent = chg.parentNode;
boxParent.replaceChild (newP,chg);
newP.setAttribute(“class”,chg.getAttribute(“class”)||chg.getAttribute(“className”));
newP.setAttribute(“id”,chg.getAttribute(“id”));
chg = newP;
}
chg.appendChild(newImg);
}
}
}

function getElementByClassName(name){
var elements=[];
var allElements = document.getElementsByTagName(‘*’);

for(var i=0,len=allElements.length; i<len; i++){
if(allElements[i].className == name){
elements.push(allElements[i]);
}
}
return elements;
}

img_swpというクラス名のついた要素を取得して、そのID+.gifを画像名として使用。
んで、ID付き要素の中にimg要素を生成して、画像を当て込む感じ。
中のテキストをaltに代入。
IDとクラス、タグ名を引き継いだ上で、いったん中身を消すために、replaceChildする。
ただし、リストに関しては、pタグで生成しなおし。
実行前:<p class=”img_swp” id=”text” >置き換えるテキスト</p>
実行後:<p class=”img_swp” id=”text”><img scr=”text.gif” alt=”置き換えるテキスト” /></p>
生成後のコードはこんな感じになるかな。

とりあえずザクザクっと組んでみたんだけど・・・問題が2点。
まず1点。
IEだけなぜか画像サイズがうまく取れてこない。
初回の時はいいんだけど、いったん作った画像をリサイズしてアップしなおしたとき、
いつまでも古いサイズで表示されて、どうしようもならない。
サイズの設定をしていなくても駄目。
キャッシュ消したり、ブラウザ立ち上げなおしたり、PC再起動しても駄目。
何なんだいったい・・・

2点目は画像の取得をミスったとき。
これは運用で気をつけていれば良いんだろうけど。
出来れば画像がないときはそのまま~にしておきたい。
ファイルの有無を調べればよさげな感じだけど。

基本はこれで良いと思うんだけど、上記2点を解消しないと気軽に使えないなぁ・・・

カテゴリー: CSS, JavaScript, Web Design, XHTML — 11:09:20

2007/08/16

SWFObjectとjQueryでHTMLを汚さずにFlashを埋め込む

ちょっと前は一時期そこらじゅうの企業や店舗のHPのトップに
巨大なFlashが張られていたり、
メニューそのものがFlashで作られてて、
非Flash環境じゃリンクたどれねーよハゲとか、
しょうもないイメージ映像見るために
いちいちプラグインのインストールさせるんじゃねぇ!とか思ってたんですが。
Youtubeのおかげかどうか知りませんが、爆発的にFlashが普及したおかげで、
最近またそんなサイトが増えてきた気がします。

とはいえ、アクセシビリティやSEOの点から考えると、
バージョンアップを促されたり、
最近のIEの場合だと警告が出てきたり、
ページのアタマにダラダラとFlashの埋め込み構文が書かれていたり、
と、鬱陶しいことこの上なし。

Flashそのものを見せたいのじゃなければ、
非対応環境のユーザーにはただの画像やプレーンなテキストで情報を提供すべき、
という考えの元、シンプルにFlashを埋め込む方法を考えてみる。

そんなわけでSWFObjectjQueryを利用。

これがすごい簡単。
とりあえずサンプルのHTMLを見てもらえればわかるんですが、
元のコード内には一切スクリプトもObjectタグも書かれていません。
validかつプレーンなHTMLで非対応ユーザーには代替文章や画像で情報を提供しつつ、
対応ユーザーには、リッチなインターフェースを提供できるというすばらしさ。
まぁ、要はDOMで書き換えてるわけですが。

これだけならSWFObjectのみで出来るんですが、
例えばいくつもバナーがあったりして、表示に時間がかかる場合、
Flashに挿し変わるまでの間に、代替画像や文字が表示されてちょいとかっこ悪い。
そこで、jQueryの$(function());を使って、DOMツリーが出来上がった直後の画像読み込み前に書き換えてやる。
そうするときれいに最初からFlashの表示ができる。

初期化スクリプトはこんな感じ

$(function(){
var so = new SWFObject(“swfsample.swf”, “sample”, “300″, “300″, “8″);
so.addParam(“quality”, “autohigh”); //
so.addParam(“wmode”, “opaque”); // フレームレートがあがるらしい・・・
so.write(“swf_img”);          // Flashを差し込む場所のID
});

そんなわけで、ヘッダーにSWFObject.jsとjQuery.js、それから初期化用のスクリプトを読み込んでやればOK。

てことでサンプル。
サンプルHTML
初期化スクリプト

参考:
trick7.com blog: SWFObjectのドキュメントを日本語に翻訳してみたよ

カテゴリー: CSS, JavaScript, Web Design, XHTML — 16:12:39

2007/08/04

submitとreset buttonを画像にしてロールオーバーもつけてみる

前回のやったinput buttonを画像にしてロールオーバーもつけてみるの改良版です。

今回はリセットボタンも付けてみよう、ということで。
こないだ書いたスクリプトじゃ複数のボタンがあったとき動きませんね(‘A`)

てなわけで、DOM Scriptはこんな感じです。

var inputs = document.getElementsByTagName(“input”);
for( var i=0,j=inputs.length; i&<j ; i++){
var btn = inputs[i];
if(btn.getAttribute(“class”) == “input_btn”){
btn.onmouseover = function(){
this.style.backgroundPosition = ‘left -30px’;
return false;
}
btn.onmouseout = function(){
this.style.backgroundPosition = ‘left top’;
return false;
}
}
if(btn.getAttribute(“className”) == “input_btn”){
btn.onmouseover = function(){
this.style.backgroundPosition = ‘left -30px’;
return false;
}
btn.onmouseout = function(){
this.style.backgroundPosition = ‘left top’;
return false;
}
}
}

style.backgroundPosition をthisにしているところが前回と違うだけで、あとは一緒です。
てなわけで、
動作サンプル
script
css

カテゴリー: CSS, JavaScript, Web Design, XHTML — 2:01:38

2007/07/23

input buttonを画像にしてロールオーバーもつけてみる

フォーム関係はあんまりいじりたくないんだけど、
企業関係のページだと、メールフォームなんかで結構使うので、私用じゃ使わないのに需要は多い。
特にsubmitボタンを画像にして、さらにオールオーバーさせてくれとか言われたりするとテラメンドクサス。
で、buttonタグだとボタンのごとく(というかボタンだけど)クリックでベコベコ動くのが気に入らない。
ギリギリの幅と高さにするとFirefoxでクリック時に見切れるし(‘A`)

inputでtype=”image”も
type=”reset”とかやりたいときに困る。

ってことで、inputでtype=”image”以外の方法。

とりあえずHTMLコードはこんな感じ。

<input class=”input_btn” id=”btn_send” name=”btn_send” value=”送信” title=”送信” type=”submit” />

type=”reset”でもいける。
スタイルが無けりゃ普通にボタンになる。
スクリプト使えない環境ではロールオーバーしないだけ。

んで、こいつにかませるCSSが

form input#btn_send{
background:url(btn.gif) no-repeat left top;
width: 100px;
height: 30px;
border: none;
overflow: hidden;
cursor: pointer; /* カーソルを指マークに Operaはなぜか効かない*/
text-indent: -9999px; /*ボタンの文字を消す*/
text-align: left;
display: block; /*IEで背景が消えてしまう*/
}
/* Operaのみ適用 */
*+html:first-child body form input#btn_send {
padding-left: 300px; /*適当*/
}

operaだけbuttonのvalueをtext-indent:-9999pxで飛ばせない。
その代わりpaddingがvalueのみに効くので、これで代用。

んで、javaScriptを使ってロールオーバーさせる。

function btnConform(){
if (!document.getElementsByTagName) return;
var inputs = document.getElementsByTagName(“input”);
for( var i=0,j=inputs.length; i<j; i++){
var btn = inputs[i];
if(btn.getAttribute(“class”) ){
if(btn.getAttribute(“class”) == “input_btn”){
btn.onmouseover = function(){
btn.style.backgroundPosition = ‘left -30px’;
return false;
}
btn.onmouseout = function(){
btn.style.backgroundPosition = ‘left top’;
return false;
}
}
}
else if(btn.getAttribute(“className”)){
if(btn.getAttribute(“className”) == “input_btn”){
btn.onmouseover = function(){
btn.style.backgroundPosition = ‘left -30px’;
return false;
}
btn.onmouseout = function(){
btn.style.backgroundPosition = ‘left top’;
return false;
}
}
}
}
}

HTMLを一切汚さず画像化できるので便利。
画像OFFのとき見えないのは背景置換え全般の弱点だからなぁ・・・。
背景色を何かしておけば、最悪の場合でもそこになにかある、というのをアピールできるかもしれない・・・(‘A`)

というわけで
動作サンプル
CSS
JavaScript

いちおうIE6/7、Firefox、Safari、Operaすべてで動くハズ・・・

複数ボタン対応版はこっち

カテゴリー: CSS, JavaScript, Web Design, XHTML — 20:07:59

ページTOPへ