1.023world - ヤドカリパークとマリンアクアリウム -

海洋の仕組みと細菌・微生物から学ぶマリンアクアリウムサイト

1.023world Facebook

結果 Oh! Life (旧ブログ)

懲りずに書いてみたりする結果オーライな日記

嘘の通らないご時世

さて。役に立たない(?)トリビアを。

先月の 1.023world の利用者のうち、性別が男性の方は全体の72パーセント、女性は28パーセントでした。また、年収が300万未満の方は全体の16パーセント、700万円台の方は10パーセントでした。

え?何言ってんの!?

実はこれ、Google Ad Planner と呼ばれる神の声によるものです(笑)
さあ、真偽のほどは。。。?

興味のある方は、こちらでどうぞ。
但し、独自ドメインのみ調査可能です。
(左上の「View a site listing:」のフォームへドメインを入力すればOKで、右側のログインは不要です)

Google Ad Planner

元々このツールは、広告主が広告の掲載先サイトを調べるためのものですが、上記のような情報やサイトのPVなんかも調査できるので、ちょっとしたウェブの興信所(笑)として使い道があるようです。そのため、それまでクライアントに対して「うちのサイトは月間100万PVなんですよ♪」なんて宣伝していた広告代理店さんあたりは、このツールの出現で青ざめているとかなんとか(爆)

さて、肝心の精度に関してですが、例えばユニークユーザー数について実データと比較してみたところ、およそ信頼できそうな値のようです。さすがグーグル先生。

1.023world - 2009/05 サーバーログ Google Analytics Google Ad Planner
ページビュー(PV) 975,359 131,592 620,000
ユニークユーザー数 138,454 19,286 18,000

サーバーのログでは、各検索エンジンからのクロールや携帯からのアクセスなど全てのアクセスが含まれるので、どうしても値が大きくなりますが、Analytics の値はブラウザベースで集計されているので、より正確であると思われます。
しかし、PVの方は Analytics と Ad Planner とでは、かなりの開きがありますね。どんなアルゴリズムなんでしょう。Ad Planner のPVの方はサーバーログにより近い見方をしているのかな?

それにしても、改めてびっくりです。
10年やってるとは言え、まさか 1.023world が今や月間ユーザー2万人、ページビューも10万PV越えだなんて。。。有り難くて有り難くてお星様になりそうです。

でもみなさん、一体どこ見てるんでしょう?(汗)

こちらのエントリーもどうぞ♪

フルスクリーンとembedタグ

ウェブ用の動画プレーヤーと言えば、僕もお仕事用サイトで配布してます。
そう言えばそろそろ新しいバージョンを作らなきゃアカン時期だよね。
問い合わせにも「今年の春には・・・」なんて答えまくってるし。
でも暇がない。。。

そんな中、仕事の依頼として先日からFLVプレーヤーをこしらえてます。
あぁ、自分のも作りたくてウズウズしちゃう。。。

で、今時なフルスクリーンの搭載でつまづいた。
と言うか納得いかない。

なんで <embed> タグ書かなきゃならんの!?

これ書かないと、フルスクリーンがクロスブラウザにできないみたい。
でもさ、これ W3C で非推奨タグなんだけど。。。
ブラウザさん、なんでこんな実装なの?
・・・仕方がないので JavaScript で吐かせるか。

ん。待て。
別に、タグ貼るのはクライアントさんだから、そこまで心配しなくても良いか。
でもなぁ。。。気持ち悪いなぁ。。。

ちなみに、FLASHでフルスクリーンを実現するには、ボタンイベントで以下を実行。

Stage['displayState'] = 'fullScreen';

んで、<object> タグに以下のパラメータを追加

<param name="allowFullScreen" value="true" />

で、<embed> にも以下の属性を追加。

allowFullScreen="true"

これでOK。

なにがOKなもんかいっ。

こちらのエントリーもどうぞ♪

そろそろ透過PNG?

IE 7.0

IE 7.0 がリリースされてから、もうかれこれ2年以上が経過し、一方、IE 6.0 のシェアはそろそろ20%を切ったあたりだそうです。・・・って、まだ全然多いんですけど(汗)

とは言え、IE 7.0 になってから、ひとつだけ助かったことがあります。それは、24ビット PNG のアルファチャンネルに対応してくれたことです。これでようやく透過 PNG が貼れるようになりました。

透過PNGのサンプル

と言いたいところですが、まだ IE 6.0 ユーザーが残ってます。
そんなモン早く窓から放り投げてください(笑)

ちなみに IE 6.0 では、こんな風に表示されちゃいます。

透過PNGをIE6.0で表示した場合

なので、もし現時点で透過 PNG をウェブで使おうと思ったら、AlphaImageLoader フィルター(IE独自拡張)を活用せざるを得ないのが現状です。
(IE6ユーザーを切り捨てるなら話は別ですが)
幸いこれを使えば、辛うじて IE 6.0 でも透過 PNG を表示させることができます。

と言ってもコレ、ちょい面倒くさいんですよね。。。

AlphaImageLoader をどう使うか

例えば、透過 PNG を CSS の background 属性に限定して記述するなら、通常の background 属性の記述に続いて、filter 属性への AlphaImageLoader の設定と、アンダースコアハック(underscore hack)による background の消去を行うことで適用できます。(アンダースコアハックはIE6のみに適用させる場合に用いるハック方法)
但し、縦横のサイズが PNG と同一のレイヤに対しては問題ありませんが、PNG よりも大きなレイヤに背景として配置するような場合には注意が必要です。(AlphaImageLoader フィルターの sizingMethod オプションを crop にするか scale にするか等)

しかし、AlphaImageLoader フィルターを、HTML 内の <img> タグで貼られた透過 PNG に適用させる場合は、単に <img> タグに対して AlphaImageLoader フィルターを適用させただけでは、src 属性で指定された元々の PNG が残ったままなので、IE6 では相変わらず非透過の PNG が表示されたままとなります。これは外部 CSS ファイルで記述した場合でも、 <img> タグへ style属性で記述した場合でも同様です。そのため <img> タグの src 属性に透明 GIF を割り当てる等の最終処理が必要になります。そしてこの場合は何らかの JavaScript での処理に頼ることになります。

また、W3C に準拠した Valid でクリーンなソースを壊したくない場合や、ブラウザの独自拡張になるべくなら頼りたくない場合など、おかしなハックやコメントの記述をためらうこともあるでしょう。そう言う理由からも、このようなややこしい処理は初めからすべて JavaScript に丸投げする方法を推奨します。そうすることで、必要悪は最小限に抑えられるでしょう(苦笑)

ちょっと検索してみたら、この機能を持った JavaScript モジュールがいくつか配布されているようでした。ただ、実際にコードを見てみると、必要のない機能が多かったり、無駄にファイルサイズが大きかったりするので、PNG だけの処理には持てあますかも知れません。たかだか IE6 のためだけに資源を無駄に使うこともありませんし。

PNG → AlphaImageLoader 自動転換 JavaScript コード

そこで、PNG だけを処理してくれる JavaScript を組んでみました。(昔組んだものを少しいじっただけですが)
例によって、ページのヘッダに事前に読み込んでおくだけで、あとは自動的に処理してくれるものです。

このコードは、外部 CSS ファイルや HTML 内の <style> タグによる CSS や <img> タグの PNG をスキャンして、自動的に AlphaImageLoader を適用します。但し、<img> タグへの置換用に、予め透明 GIF をサーバーのどこかにアップロードして、ie-png.js 内の gif 変数に絶対パスで設定しておいてください。

変換対象
外部 CSS ファイル
  • background:url(PNG-URL) [color repeat position]
  • background-image:url(PNG-URL)
  • PNG 画像パスは自動的に解析し割り当てるので相対パスでもOK
  • PNG 画像パスをクオート(シングル・ダブル)で囲んであってもOK
内部 <style> タグによる CSS
  • background:url(PNG-URL) [color repeat position]
  • background-image:url(PNG-URL)
  • PNG 画像パスは自動的に解析し割り当てるので相対パスでもOK
  • PNG 画像パスをクオート(シングル・ダブル)で囲んであってもOK
<img> タグの PNG
  • 予め透明 GIF をサーバーにアップロードして、JavaScript コードにその透明 GIF 画像パス(絶対パス推奨)を設定してください
    var gif = 'アップロードした透明GIFの絶対パス';
  • PNG 画像パスは自動的に解析し割り当てるので相対パスでもOK

テスト結果:サンプルページ * IE 6.0 で見ないと効果が判りません
ダウンロード:ie-png.js

ひとりごと

確か、IE 6.0 だけじゃなくて、IE 5.5 とかにも AlphaImageLoader は使えたと思ったのですが、今手元の IETester で試してみると IE 5.5 では AlphaImageLoader による透過 PNG が表示されません(汗)
一応、コード自体は IE 5.5 でも走るように書いたつもりですが、もし動作確認がとれた方はご一報いただけると嬉しいです。

また、インライン CSS 分の画像パスや絶対パスによる記述分は良いとして、外部 CSS ファイル内の相対パスによる画像パスについて、なんかもっとうまく処理する方法はないかしら。例えば、外部 CSS ファイルを HTML とは別の階層から呼び出していた場合に、相対パスだと AlphaImageLoader に渡す画像パスがずれてしまうので、今は地道に生成するようにしてあります。

その他、background 関係以外の画像適用 CSS プロパティ(list-style-image とか)までは面倒なので実装を省略しました(汗)

以下、一応 ie-png.js のコードです。

var gif = 'null.gif';

var env = new Object;
env.ua = navigator.userAgent.toLowerCase();
env.win = (env.ua.indexOf('windows') != -1)? 1: 0;
env.ie = (!window.opera && env.ua.indexOf('msie') != -1)?
           Number(env.ua.charAt(env.ua.indexOf('msie ') + 5)): 0;

var url = new Object;
url.host = 'http://' + window.location.host;
url.path = window.location.pathname.replace(/^(.*?)/[^/]*$/,'$1') + '/';

function setOnload(func){
  (window.addEventListener)? window.addEventListener('load',func,false):
  (window.attachEvent)? window.attachEvent('onload',func):
  window.onload = func;
}

var checkPNG = {
  CSS: function() {   // background, background-image propaty only.
    if(!env.win || env.ie > 6 || env.ie < 5) return false;
    var path = new Array();
    var num = 0;
    var node = document.getElementsByTagName('head')[0].childNodes;
    for(var i=0;i<node.length;i++){
      if(node[i].nodeName.match(/^style$/i))
        path[num] = url.host + url.path;
      else if(node[i].nodeName.match(/^link$/i) &&
          node[i].getAttribute('rel') &&
          node[i].getAttribute('rel').match(/stylesheet/i)){
        var href = node[i].getAttribute('href');
        if(href.match(/^//)) path[num] = url.host + href;
        else if(!href.match(/^https?:///))
               path[num] = url.host + url.path +
                 href.replace(/^(([^/]*/)*).*?$/,'$1');
        else path[num] = href;
      }
      if(path[num]) num++;
    }
    for(var i=0;i<document.styleSheets.length;i++){
      var rule = document.styleSheets[i].rules;
      for(var j=0;j<rule.length;j++) {
        var png = checkStyle(rule[j],'background');
        if(!png) png = checkStyle(rule[j],'backgroundImage');
        if(!png) continue;
        png = (png.match(/^//))? url.host + png:
          (!png.match(/^https?:///i))? path[i] + png: png;
        rule[j].style['filter'] =
          'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' +
          png + ',sizingMethod=crop)';
      }
    }
    function checkStyle(obj,propaty){
      var value = obj.style[propaty];
      if(!value || !value.match(/.png/i)) return false;
      var png = value.replace(/^.*?url(["']*([^"']+.png)["']*).*$/i,'$1');
      obj.style[propaty] = '';
      return (!png.match(/^[^"']+.png$/i))? '': png;
    }
  },
  HTML: function(){   // '<img>' elements only.
    if(!env.win || env.ie > 6 || env.ie < 5) return false;
    var img = document.getElementsByTagName('img');
    for(var i=0;i<img.length;i++){
      var src = img[i].getAttribute('src');
      if(!src.match(/.png/i)) continue;
      if(!src.match(/^https?:///i)) src = url + src;
      img[i].setAttribute('src',gif);
      img[i].style.filter =
        'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' +
        src + ',sizingMethod=scale)';
    }
  }
}

function onloads(){
  checkPNG.HTML();
}

checkPNG.CSS();

setOnload(onloads);

こちらのエントリーもどうぞ♪