— boreal-kiss.com

Archive
Tag "JavaScript"

FLASHをブログパーツにして配布する場合にはJavaScriptに収めてしまってJSスクリプトを配布する方法がある。しかし自分が今までやっていた方法だとJS経由でFLASHに変数を渡す場合に問題が起こる可能性があることがわかったのでその解決方法について。まず今までの問題のある書き方の場合、例えばJSファイルを以下のように記述していた。

//"http://example.com/showme.js"
function showMe(userid){
    //swfを表示するのに必要な<object>タグ全体。実際は改行無し
    var obj = '<objcet>
            ...略...
            <param name="FlashVars" value="userid='+userid+'" />
            ...略...
            <embed ...略...FlashVars="userid='+userid+'"></embed></object>';
    document.write(obj);
}

配布用ソースをは以下のような書式。

//配布用html貼付けソース
<script type="text/javascript" src="http://example.com/showme.js"></script>
<script type="text/javascript">showMe("borealkiss");</script>

この場合、(万が一)ユーザーがすでにshowMeという関数を他で定義していると関数名がコンフリクトを起こす(以下の例ではユーザーの期待に反しブログパーツが二個表示される)。

<html>
<head>
<!--ユーザー定義のshowMe関数-->
<script type="text/javascript">
function showMe(name){
    alert("Welcome, " + name + "!");
}
</script>
</head>

<body>
<!--ブログパーツのshowMe関数-->
<script type="text/javascript" src="http://example.com/showme.js"></script>
<script type="text/javascript">showMe("borealkiss");</script>

<!--ユーザー定義のshowMe関数を実行させるつもりだったのに!-->
<script type="text/javascript">showMe("borealkiss");</script>
</body>
</html>

このコンフリクトはこちらが定義した関数を匿名関数(無名関数)でラップしてしまい、その場で匿名関数を実行させることで回避できる(special thx: YungSang)。

//"http://example.com/showme.js" 修正版
(function(){
    function showMe(userid){
        var obj = '<objcet>
                ...略...
                <param name="FlashVars" value="userid='+userid+'" />
                ...略...
                <embed ...略...FlashVars="userid='+userid+'"></embed></object>';
        document.write(obj);
    }
    showMe(window._com_example_showMe_userid);
})();

配布ソースは以下のように修正。

//配布用html貼付けソース修正版
<script type="text/javascript">var _com_example_showMe_userid = "borealkiss"</script>
<script type="text/javascript" src="http://example.com/showme.js"></script>

ポイントは匿名関数でラップしてしまうことでブログパーツ表示用関数をローカルスコープにすること;

function(){
    function showMe(...){
        ...
    }
    showMe(***);
}

それと匿名関数をその場で実行させることだ;

(function(){...})();

これでwindow上で定義した変数”_com_example_showMe_userid”がコンフリクトしなければユーザーに迷惑をかけることはないはず。そのためにできるだけユニークな変数名にするとよい(例えば自ドメイン名に由来するものetc.)。

[関連リンク]
JavaScript++かも日記: 【JavaScript】匿名関数で匿名スコープ&インスタンス

Read More

さっきGoogle Adsenseのサーバーが意外と長いこと落ちてたみたいで、このサイトもGoogle Adsenseのコード読み込めずにそこでページの表示がとまってやんの。こりゃいかんと思って手元のJavaScriptの本見てたら「defer(遅延)という属性を書くと、そのスクリプト部分の読み込みがその他のページコンテンツが読み込み完了するまで後回しにされる」って書いてあったから便利と思って試しにページの頭に


<script type="text/javascript" defer="defer">
alert("hello, world");
</script>

て書いて表示させてみたら、いきなり「hello, world」って出るんですけど(Mac Firefox)!Firefoxがダメなだけ?というかGoogle Adsenseはコード改変するのダメっぽいのでこの方法は結局使えない。調べてみると遅延描画ライブラリなんてものがあるらしい。これでGoogle Adsenseの表示問題は一応解決できそう。

よく考えたら自分とこのブログパーツも外部JavaScriptファイルとして読み込んでもらってるんだけど同じようなサーバーダウン時の対処を何も施してない。jsファイルの読み込みを遅延するいい方法はないのかな。こっちのホストサーバー落ちたら、ブログパーツ貼付けてるユーザーのサイトの表示に問題が生じるわけだから無視はできない。うちCoreserverだから超心配。例えば


<script type="text/javascript">
window.onload = function(){
処理内容
}
</script>

みたいに書いておけばページ読み込み完了まで実行が延期できるけど、もしこのスクリプトを書いてあるjsファイルそのものがサーバーダウンで読み込めなかった場合の対処にはならんよね。ファイルそのものが読み込めてないんだから。うーむ。

追記(2008/03/06):IEではdefer属性で遅延実行可能らしい。Mac Firefoxじゃ遅延せんかった。

* IEでは確かにHTMLのHello World!!が出た後に数秒後(ここでは2秒)にalert(“Hello World!!”);
* fxなどでは2秒間待たされた後にalert(“Hello World!!”);してその直後にHello World!!が描画されている。

script要素のdefer属性の実装 – Thousand Years

追記(2008/03/07): defer=”defer”付けたらブログパーツがIE7で表示されなくなった。何で!

Read More

PhotoNotesというJavaScriptライブラリに簡易セーブ機能を加えて実用度をアップさせました。配布ファイル一式を使えばFlickrのように画像に直接コメントが書けるツールを手軽に使えます。しかもファイルサイズがたったの44kb!自分のイラストにもっと感想が欲しいと思ってる絵師の方、Lightboxの展示方法に飽きたって方、結構遊べると思うんで是非お試しを。サーバーサイドでPHPが使える必要があります。

?PN with easy saving
http://labs.picovideo.jp/pn/

Read More

サムネイル画像をクリックするとその場で画像がロードされるLightbox 2っていうJavaScriptライブラリを導入してみた。ActionScriptもJavaScriptも似たような言語なのに、JavaScriptの方が即戦力になるからいいな。しっかり勉強したいところ。

サムネイルだけ並べて表示の方がキレイに見えると思ったので、作者情報は全てロード画像に納めました。どう、お洒落っぽい?ドット絵のテイストとはちょっと違うかな。まだまだイラスト募集中〜。

http://blog-lvup.com/gallery

Read More

JavaScriptのソースコードのみで任意のドメイン上に設置できる外部RSSリーダー(FLASH)作成に関するメモ。このRSSリーダーによりドメインA上に、ドメインB上のFLASHファイルを用いて、ドメインC上のRSSフィード情報を表示することができる。FLSHは「FLASHファイルのあるドメイン」と異なるドメイン上のXMLファイルを普通読むことができないので、FLASHファイルのあるドメイン上に 外部XMLファイルを擬似的に生成してFLASHファイルにロードしてやる必要がある。以下はそのクロスドメインの問題に関する、JavaScript – PHP – FLASHの連携について自分がつまずいたところを強調して解説してある。

ユーザー側JavaScriptソースコード。”http://boreal-kiss.com/js/url_request_rss20.js”にて定義された関数url_request()の引数に取得したいRSSフィードURL(例えば “http://blog.borel-kiss.com/index.xml”)を記述。これによりこのソースコードを記述した地点にFLASHファイル(“http://boreal-kiss.com/flash/rss/rss_reader_20_load_php.swf”)が表示され取得情報を表示する。

<script type="text/javascript" src="http://boreal-kiss.com/js/url_request_rss20.js"></script>
<script type="text/javascript" language="JavaScript">
url_request("http://blog.borel-kiss.com/index.xml");
</script>

関数url_request()の中身。FlashVars属性を用いてJavaScriptからFLASHファイル内で定義された変数に値を渡しFLASHファイルを表示。ここではJavaScript内の変数urlの中身をFLASH内の変数url_xmlに渡している。

function url_request(url){

var flash_obj = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" width="176" height="60" id="rss_reader_20_load_php" align="middle">'
+ '<param name="allowScriptAccess" value="always" /">'
+ '<param name="movie" value="http://boreal-kiss.com/flash/rss/rss_reader_20_load_php.swf" /">'
+ '<param name="quality" value="high" /">'
+ '<param name="wmode" value="opaque" /">'
+ '<param name="FlashVars" value="url_xml='+url+'" /">'
+ '<embed src="http://boreal-kiss.com/flash/rss/rss_reader_20_load_php.swf" quality="high" wmode="opaque" bgcolor="#333333" width="176" height="60" name="rss_reader_20_load_php" align="middle" allowScriptAccess="always" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" FlashVars="url_xml='+url+'" /">'
+ '</object">';

document.write(flash_obj);
}

FLASH内ActionScriptのソースコード(抜粋)。JavaScriptから受け取った値をurl_xmlに格納、そして同じ内容をLoadVarsクラス内オブジェクトmyData.url_inに格納しなおす(起動時にmyData.url_inに格納しようとしたらうまくいかなかった)。sendAndLoadメソッドでmyDataの情報(ここではmyData.url_in)をPHPファイルに送信し処理後のPHPファイルの内容をXMLクラスnewsXMLに格納する。格納後内容の解析をスタート。ここでPHPファイルは絶対パスで指定する必要がある。異なるドメイン間で通信する場合、相対パスで表記したファイルをFLASHが認識できなかった。

//XMLクラス
var newsXML:XML = new XML();

//ファイル読み込み時に空白を無視(今回は必要ないかも?)
newsXML.ignoreWhite = true;

//FLASHファイル起動時にJavaScriptから値を受け取っている。
var url_xml:String;

//LoadVarsクラス内のオブジェクトmyData.url_inにurl_xmlを格納。
var myData:LoadVars = new LoadVars();
myData.url_in = url_xml;

//PHPファイル("load.php")にmyDataの中身を送り、
//PHPファイルで処理後の内容をnewsXMLに格納する。
//PHPファイルは絶対パスで指定。
myData.sendAndLoad("http://boreal-kiss.com/flash/rss/load.php", newsXML);

newsXML.onLoad = function(result:Boolean){
(newsXMLロード後の処理)
}

サーバー側PHPソースコード(“load.php”<body>タグ内の内容)。FLASHから変数url_in(RSSフィードURL。例えば “http://blog.borel-kiss.com/index.xml”)を受け取り、その内容をその場に表示。このPHPファイル自体がFLASHファイルの置かれている同一ドメインに生成された疑似XMLファイルの役割を果たす。PHPのソースコードはHTMLファイル内に表記されているため、この疑似XMLファイルには取得したいXMLファイルの内容の他に<html>や<body>タグ等も含まれる。FLASHでこの疑似XMLファイルの中身を解析する際に注意が必要。

<?php
$url = $_POST["url_in"];
readfile($url);
?>

追記(2007/12/17):上記内容の場合、読み込んだXMLファイルのエンコーディング(EUC-JPなど)によっては文字化けしてFLASHに格納される。文字化けを回避する具体的な方法についてはこちらを参照。

Read More