[ Tags :: JavaScript ]

画像なしで吹き出しみたいなもの

category-icon

 この頃は、リッチなツールチップ(バルーンヘルプ)が増えてきたように思います。中には、派手すぎて逆に分かりづらかったりするものもありますが、まぁそういうので遊んでみるのもたまには良いかなと思います。

 自分なりに実装するとしたら、どのようなものが良いか考えてみました。

  1. シンプルであること
  2. 軽快であること
  3. 吹き出しっぽく見せたいな
  4. 角丸コーナーが良いな
  5. 出来ればドロップシャドウぐらいは付けたい

という感じで、矛盾をはらんだリストですが、これを実装するにはどんなが良いか考えてみました。

  1. シンプルであること → 画像ファイルを使わずにやれるか?
  2. 軽快であること → フェードなどのエフェクトはなしで
  3. 吹き出しっぽく見せたいな → あのニョロっとした尻尾みたいなのをどうやって作るか?
  4. 角丸コーナーが良いな → CSS3に対応していないIEはどうするか?
  5. 出来ればドロップシャドウぐらいは付けたい → 同上

 いつものようにCSS3のサポートが貧弱なIEが足かせとなります。でも、IEでも同じように見せるために四苦八苦するのがweb開発の面白いところでしょう。画像を使わずに、角丸コーナーやドロップシャドウ効果を付けるには、IEのVMLやfilter機能を使うのが良いでしょう。

 角丸コーナーは、VMLのroundrectGを使って実現できます [参考記事: VMLやSVGを用いた角丸コーナーLink ]。ドロップシャドウは、IEのフィルター機能のひとつであるBlurを使うことでOKです[参考記事: IEでCSS3のドロップシャドウを使いたいLink ]。問題は、吹出しには必須とも言える、あのしっぽみたいなやつですが、これはCSSのボーダー属性を使うことで可能です。トリッキーな(でも正統派)手法ですが、これに関して、レファレンスともいうべきサイトがありますLink 。このサイトは、以前から知っていていつか利用しようと思っていたんですが、ようやくお世話になる時が来ました:)

 とりあえず、試験的なモデル(プロトタイプ)を作ってみて、それが意図したように実現可能であれば、それを自動化すべくスクリプト化という流れが良いでしょう。プロトタイプが、よさげな感じに仕上がったのでスクリーンショットをば。
cutePop
なかなか良い感じでは。FirefoxですがIEでもほぼ同じ。
 

実際のデモのページはこちら。Link

 で、かなり手抜きですが、これを元にスクリプト実装したのが以下。

実際のデモのページはこちら。Link

 ppBlogで、これらをどれくらい採り入れるかは未定ですが、引き出しは多ければ多いほど良いでしょう

   


— posted by martin at 01:57 am   commentComment [2]  pingTrackBack [0]

表示オンオフ制御周りの改良

category-icon

 ppBlogのoParts.jsにtweenアニメーションみたいな動きを取り入れてみました。まだ試作段階ですが、テーマ:Basicであれば、左側のサイドバーの展開や、ソーシャルブックアイコンで、ちょっとした動きをみることが出来ます。

 写真のポップアップにも。
IMG_0285
モン・サン・ミシェル

 

— posted by martin at 11:31 pm   commentComment [0]  pingTrackBack [0]

メソッドチェーンで遅延処理をしたい

category-icon

 こんばんは、martinです。タイトル通りなんですが、要は以下のようなことを簡単に実装したい。

foo.await(2000).say("Hello, ").await(1500).say("world !");

 まぁfooという関数オブジェクトがあるとして、2秒後に「Hello, 」を出力して、そこで小休止、で1.5秒後に「world !」を出力すると。それをメソッドチェーンに拘ってやりたい。簡単な例を挙げてみます(うまく行かないサンプルです)。

var foo = function(){}; // 関数オブジェクトを作成

foo.prototype = { // プロトタイプを設定
 say : function(s){
  alert(s);
  return this;
 },
 await : function(ms){ // ここで遅延処理をゴニョゴニョしたい
  // var _this = this;
  // setTimeout(function(){
  // return _this; # まぁ、これはダメだけど、こんな感じでやれたらいい
  // }, ms);
   return this;
  }
}

var bar = new foo();
bar.await(2000).say("Hello"); // すぐに「Hello」が出力される

 メソッドチェーンを実装するとなると、return this;をかまして、用意した関数オブジェクト自身を返すようにする必要があります。上のawait関数内で、setTimeoutを用いて遅延処理をしようと思いましたが、どうもうまい方法が思いつかず、とあるサイトで質問してみましたLink 。すると、数分後(!)に返答があって、「それ、jQueryで出来るよっ!」と(--)(そのコメントは今は消されたようなんですが) まぁ確かにそうなんですが(なのであえて.delayという単語を選んだ)何かすごい技があって、それで解決!みたいなことを期待していたわけです(jQueryを使わずに)。

 2つ目に付いたコメントで、簡単に済ませる方法はなくて、何か別のキューシステム(待ち行列システム?)を用意する必要があるよ、と。やっぱりそうか。で、沢山ヒントを頂いたんで、自分なりに作ってみました。次のようなキューシステムを用意しました。

Queue = {
 entries : [], // 関数を登録する配列を用意
 inprocess : null,
 enqueue : function(entry){ // 関数を登録する
  Queue.entries.push(entry);
 },
 flush : function(){ // 配列に登録された関数群を一気に実行
  if(Queue.inprocess) return; // 「待ち中」なら実行しない
  while (Queue.entries.length){
   var entry = Queue.entries.shift(); // 配列の頭から取り出す(つまり登録順)
   if(entry.toString().indexOf('await:') !== -1){ // 「待ち」のマークを見つけたら
    var ms = Number(entry.split(':')[1]);
    Queue.inprocess = setTimeout(function(){
     Queue.inprocess = null;
     Queue.flush(); // 指定時間後に処理を再開
    }, ms);
    return;
   }
   entry(); // 取り出された関数を実行
  }
 }
}
 こいつを最初のサンプルに適用すると以下のような感じになります。
var foo = function(){};

foo.prototype = {
 say : function(s){
  Queue.enqueue(function(){ // 配列に関数を登録
   alert(s);
  });
  Queue.flush();
  return this;
 },
 await : function(ms){
  Queue.enqueue('await:' + ms); // 配列に「await:2000」みたいなマークを登録
  return this;
 }
}

 自分のスキルではこの程度です(--) キューシステムに頼らずに自己完結できる目から鱗な手法がないですかねぇ。

とりあえず動作サンプルを以下に。ボタンを押すと、

var bar = new foo();
 bar.await(1500).say('Hello, ').await(2000).say('world!');
ってのが実行されます。ここでは、ボタンを押して1.5秒後に「Hello, 」、更に2秒後に「world !」とボタンの右側に表示されます。
 何か、「こうしたらいいよ」とかのアドバイスあればよろしくお願いします。

 


— posted by martin at 08:29 am   commentComment [0]  pingTrackBack [1]

IEでもCSS3ドロップシャドウのアップデート

category-icon

 こんばんは、martinです。以前、IEでもCSS3のドロップシャドウ(text-shadowbox-shadow)を使いたいということで、それを可能にするスクリプトを書きましたLink

 で、コメントLink で、IE7以下では、text-align:centerを指定すると影がすごくズレるというご指摘をいただきました(IE8では問題ない)。調べてみると、どうも「text-align:centerの指定が内包されるボックス要素にも適用されてしまう」という、懐かしいIEのバグが原因のようなので、それを修正しました。ついでに、画面のリサイズ(window.onresize)にも対応させました。以下のスクリーンショットのように、Firefox3.6など今時のブラウザに引けを取らない感じで、ボックスシャドウやテキストシャドウが可能になります。
Firefox3
Firefox3.6でのスクリーンショット。ChromeやOperaでもほぼ同じ。
IE7-compatible
IE8で、後方互換モード(IE7相当)表示。遜色ないレベルで再現。

実際のデモのページはこちら。→http://p2b.jp/demo/CSS3dropshadow.htmlLink

 使い方は簡単で、CSS3なページのHEAD要素内に、IE(IE9未満)だけ読み込むような外部JavaScript(実態はHTCファイル)を記述するだけです。最新版を添付しておきますね。

 <!--[if lt IE 9]>
  <script type="text/javascript" src="path/to/css3shadow.htc"></script>
 <![endif]-->

 デモページにもありますが、box-shadowinset(内側ドロップシャドウ)や複数のtext-shadow指定にも対応しています。

Box-shadow-inset
IE7互換モードでの表示。まぁ悪くない。

 スクリプト自体はそんなに凝ってるわけではないのですが、あまり気合の入った指定をしなければ、それなりに動いてくれるかなと思います

   


— posted by martin at 07:36 am   commentComment [7]  pingTrackBack [0]

IE8でのHTML5要素有効化あれこれ

category-icon

 もう7月も終わりですね、martinです。相変わらず時の流れは速いもので。

 このサイトのブログの基本テーマ(スキン)「Basic」では、試験的にHTML5を導入しています。HTML5では新しい要素がいくつか追加Link されていますが、IE9未満のブラウザでは、articleheader, navなどのクールで新しい要素に対するスタイルシート指定が効かない、という事が昔から知られています。これに対するアプローチとして、 document.createElementを使うとスタイルシートでの指定が可能になるよ、というのがよく知られています。初出は Sjoerd VisscherLink さんあたりでしょうかねぇ。
document.createElement(”article”); // 未知の要素articleに対してIEでもCSS指定が可能になる

 このdocument.createElementを使うテクニックは、いろんなところで見かけることができて、有名どころでは、Remy sharp氏のhtml5.jsLink あたりですね。

 もっとも、このテクニックを使っただけでは、IEでHTML5化を効かせたページを印刷したときまでは反映されないので、これに対しては、IE Print Protector Link がよく知られていると思います(個人的には、印刷のサポートまではあまり興味がありませんが)。

 で、このcreateElementを使うテクニックは、ベタに書けば以下のような感じになります。

// ここでは簡潔化のため、以下の6個の新要素に絞ってます。
<!--[if lt IE 9]>
var html5_elements = ["header", "nav", "article", "section", "aside", "footer"]; 
for (var i = 0, len = html5_elements.length; i < len; i++){
 document.createElement(html5_elements[i]); // 各要素に適用
}
<![endif]-->
 どこで最初に見かけたのか失念しましたが、これを一行(ワンライナー)で簡潔に済ませたスクリプトを見たときはいたく感心しました。Dean Edwards氏のブログLink もこうなっています。
"header,nav,article,section,aside,footer".replace(/¥w+/g, function(a){document.createElement(a)});
 上のポイントは、replaceメソッドの引数に関数を指定できて、その関数内では、正規表現にマッチした要素を適宜適用していく点です。ループみたいなことを勝手にやってくれる点ですね。おそらくこれ以上短くは書けないのではないかと思うのですが、息抜きに自分なりにいくつか考えてみました。
"header,nav,article,section,aside,footer".split(',').sort(function(a){return document.createElement(a)*1});
 これも、似たような発想からですね。自動でなんかやってくれるという。
with("header,nav,article,section,aside,footer".split(',')))while(length)document.createElement(pop());
 ここではwith構文を使ってみました。これもなかなかシンプルです。同じくwithと、Enumeratorを使って、
with(new Enumerator("header,nav,article,section,aside,footer".split(',')))for(;!atEnd();moveNext())document.createElement(item());
 これは、ちょっと長いし、Enumerator ObjectLink はマイナーですかね。

 短さ命で、グローバル変数の汚染なんて気にしないぜっ、という向きには以下のようなものもありかと思います。

s="header,nav,article,section,aside,footer".split(',');while(s[0])document.createElement(s.pop());

 for文関連では、

for(i in s="header,nav,article,section,aside,footer".split(','))document.createElement(s[i]);
とか
for(i=0;n="header,nav,article,section,aside,footer".split(',')[i++];document.createElement(n));
とかですかねぇ。

 ちなみに、配列を作るのに、文字列にsplit()をかませるというのは、よく見かける手法です。ここでの、6個ぐらいの要素数ではあまり差は出ませんが、要素数が増えてくると、逐一ダブルクォート(or シングルクォート)で括っていくやり方と大きく差が付いてきます。

var html5_elements = ["header", "nav", "article", "section", "aside", "footer"]; // これより
var html5_elements = "header,nav,article,section,aside,footer".split(','); // こっちが記述が短い 

 正規表現から配列も出来ますね。

var html5_elements = "header,nav,article,section,aside,footer".match(/¥w+/g);

 以上、トリビアルなエントリーでした

   


— posted by martin at 12:18 pm   commentComment [0]  pingTrackBack [1]

T: Y: ALL: Online:
Created in 0.0136 sec.
prev
2025.10
next
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31