Get Utility: Getting CSS Style Sheets
先の例で使ったYUIのGet Utilityには、cssをダイナミックにロードする機能がついてる。
今回は、そのサンプル(Getting CSS Style Sheets)を解析して、若干のmodifyを行う。
このExampleでは、CSSのダイナミックロードとともに、先の例と同様にGet.scriptを使って、YAHOO! News Search APIで提供されるWebServiceが利用されている。
(YAHOO! News Search APIの仕様はこちら)
この部分のJavascriptは、YUIのサーバー上にあるが(こちらからみえる)、先ほどの例にならって、module patternで実装してみた。
(結果的に、同じようなコードになったが。。。)
サンプルの初期画面は以下。YUIのサンプルでは、初期画面で「San Francisco」をキーにして検索が実行されるが、このサンプルでは、キーワードにイチローと入れるだけで、検索は「Search YAHOO! News」ボタンを押すまで、検索させないようにした。
検索は10レコードだけfetchするようにした(画面に入りきるようにするため)。以下が、検索を実行した画面である。
また、ダイナミックにロードするcssは、YUIのダウンロードファイルに含まれていないので、以下からダウンロードし、HTMLをおくディレクトリ下のscript/yui/get/assetに保管した。
ボタンを押したときの挙動は、YUIのExampleと同じである。
以下は、「Background CSS」ボタンを押したときのイメージ。
以下に、javascriptを含むソースの全文を示す。
今回の例は、app_id=YahooDemoで動かした。また、Inbound Linkの例と同様に、このAPIの利用にも、1つのIPアドレスあたり5000サーチ/日で、非商用であることが、APIドキュメントのRATE LIMITSに示されている。
CSSをダイナミックに変えられるということは、
- スキンの選択
- 簡易ズーム(フォントサイズ変更)
などが可能ということだ。
<HTML> <HEAD> <META http-equiv="Content-Type" content="text/html; charset=UTF-8"> <TITLE>Ajax_Sampling</TITLE> <style type="text/css"> body { margin:0; padding:0; } </style> <link rel="stylesheet" type="text/css" href="scripts/yui/fonts/fonts-min.css" /> <link rel="stylesheet" type="text/css" href="scripts/yui/button/assets/skins/sam/button.css" /> <!-- id="styleoverrides"を指定。Get.cssでinsertBeforeするため。 --> <style type="text/css" id="styleoverrides"> #container .hd { background-image:url(http://us.i1.yimg.com/us.yimg.com/i/us/nt/ma/ma_nws_1.gif); background-position:top right; background-repeat:no-repeat; background-color:none; } #container h2 { border:none; margin-top:0; } #container h3 { color:#999999; } #buttonContainer { padding-bottom:.5em; } #container .module { padding:.5em 1em 1em 1em; overflow:hidden; } </style> <!-- 読み込むjs --> <script type="text/javascript" src="scripts/yui/yahoo/yahoo-min.js" > </script> <script type="text/javascript" src="scripts/yui/yahoo-dom-event/yahoo-dom-event.js" > </script> <script type="text/javascript" src="scripts/yui/utilities/utilities.js" > </script> <script type="text/javascript" src="scripts/yui/button/button-min.js" > </script> <script type="text/javascript"> YAHOO.namespace("EGP"); //関数オブジェクトBottunChangerの定義 //モジュールパターンで実装する。 YAHOO.EGP.BottunChanger = function() { // Alias var Button = YAHOO.widget.Button, Event = YAHOO.util.Event, Dom = YAHOO.util.Dom, Get = YAHOO.util.Get, elContainer, borderButton, backgroundButton, textButton, tIds = {}; // // checkBottunのイベントハンドラーの定義 // // Checkbox buttonは、状態として"checked"と"unchecked"がある。 // この状態が変わると、"onCheckedChange"イベントが発火する。 // このイベントをトリガーにして、Get UtilityでCSSをloadしたり、unloadしたりする。 var onCheckedChange = function() { // thisはイベントのおこったBottunをあらわす。 // name属性で、イベントの起こったボタンを判別する。 var name = this.get("name"); // Bottunが、"checked"な状態であれば、必要なCSSをloadする。 if(this.get("checked")) { // data パラメータを指定して、onSuccessハンドラーに渡す。 // dataには、CSS名を渡し、CSSを取り除くときのために格納しておく。 // // insertBeforeプロパティーを指定する。 // 値には、どのCSSの前に差し込むか、を指定する。 // そのために、style タグにid(=styleoverrides)を指定する。 Get.css("scripts/yui/get/assets/" + name + ".css", { data: name, insertBefore: "styleoverrides", onSuccess: onSuccess }); } else { // checkが外されたら、保管していた状態にもどす。 tIds[this.get("name")].purge(); // ある種のA-Grade Browserでは、purgeがうまくいかないので、 // なにも書いてないCSSをGet.cssでloadする。 Get.css("scripts/yui/get/assets/neutral.css"); } }; // Get UtilityのonSuccessハンドラー var onSuccess = function(o) { //alert("読み込み成功; " + o.data); // o.dataには、ボタン名が入ってる。purgeのときのために保管しておく。 tIds[o.data] = o; }; return{ // DOMReadyで最初に呼ばれる初期化関数。 init: function() { // (注意) // DOMReady後でなければできない、メンバー変数の定義。 elContainer = Dom.get("container"), // Bottunを動的に生成して、Containerに突っ込む。 // Checkbox Buttonの定義 borderButton = new Button({ id: "borderButton", type: "checkbox", name: "border", label: "Border CSS", container: "buttonContainer" }); backgroundButton = new Button({ id: "backgroundButton", type: "checkbox", name: "background", label: "Background CSS", container: "buttonContainer" }); textButton = new Button({ id: "textButton", type: "checkbox", name: "text", label: "Text CSS", container: "buttonContainer" }); YAHOO.EGP.BottunChanger.buttons = [borderButton, backgroundButton, textButton]; // BottunのcheckedChangeイベントに、 // onCheckedChangeハンドラーをsubscribeする。 borderButton.on("checkedChange", onCheckedChange); backgroundButton.on("checkedChange", onCheckedChange); textButton.on("checkedChange", onCheckedChange); } }; }(); //DOMは完全にloadされたら、サンプルを初期化する。 YAHOO.util.Event.onDOMReady( //DomReadyイベントで発火するハンドラ YAHOO.EGP.BottunChanger.init, //ハンドラに渡すオブジェクト(関数) YAHOO.EGP.BottunChanger, //ハンドラは、上記のオブジェクトのスコープをもつ。 true ); //------------------------------------------------------------- // // YAHOO! NewsをとってくるScriptが書かれていないので、GetScriptで書いてみる。 // サンプルの本物は、 // http://developer.yahoo.com/yui/examples/get/assets/getNews.js // を参照のこと。 // module patternで書くことにする。 YAHOO.EGP.NewsPicker = function() { var Event = YAHOO.util.Event, Dom = YAHOO.util.Dom, Button = YAHOO.widget.Button, Get = YAHOO.util.Get, elResults; var onNewsPickerSuccess = function(o) { } var onNewsPickerFailure = function(o) { var html = "<h3>通信に失敗しました</h3>"; elResults.innerHTML = html; } var getNewsPickerData = function() { elResults.innerHTML = "<h3>次のキーワードを検索しています。 " + Dom.get("searchString").value + ":</h3>" + "<img src='http://l.yimg.com/us.yimg.com/i/nt/ic/ut/bsc/busybar_1.gif' " + "alt='お待ちください...'>"; // YAHOO! News APIを利用するURLを準備する。 // V1の仕様は、http://developer.yahoo.com/search/news/V1/newsSearch.html // 面倒なので、outputはjson、リターンのリストは20個を指定する。 var sURL = "http://search.yahooapis.com/NewsSearchService/V1/newsSearch" + "?appid=YahooDemo&output=json&results=10" + "&callback=YAHOO.EGP.NewsPicker.callback" + "&query=" + encodeURIComponent(Dom.get("searchString").value); // Get Utilityを使い、Web Serviceからデータを取得するcallbak定義。 var transactionObj = Get.script(sURL, { onSuccess: onNewsPickerSuccess, onFailure: onNewsPickerFailure, scope : this } ); // ScriptメソッドはトランザクションIDを含む、single-fieldオブジェクトを戻す。 // トランザクションIDを保管する。 current = transactionObj.tId; } // まず、無名関数を定義する。 return { // DOMReadyで最初に呼ばれる初期化関数。 init: function() { // (注意) // DOMReady後でなければできない、メンバー変数の定義。 elContainer = Dom.get("container"); elResults = Dom.get("results"), //id=siteExplorerのsubmitイベントにハンドラーを仕掛ける。 Event.on("newsSearch", "submit", function(e) { // submit formのデフォルトの動きを抑止する。 Event.preventDefault(e); // WebServiceの呼び出しを実行する。 getNewsPickerData(); }, this, true ); // input type=submit にbuttonをインスタンス化する。 var oButton = new Button("getNewsData"); }, // WebServiseのコールバック関数。 // (??) Get utilityの場合、レスポンスからのresultのとり方がわからない。 // 以下のようにして、YAHOO Web ServiceのCallbackを使えば取れる。 callback: function(results) { // 返却値から有用なフィールドを取得する。 var aResults = results.ResultSet.Result; var totalLinks = results.ResultSet.totalResultsAvailable; var returnedLinkCount = results.ResultSet.totalResultsReturned; if(aResults) { // inbound linkがある場合;処理と表示をする。 var html = "<h4>" + totalLinks + " のリンクが取得できた; 以下に最初の " + returnedLinkCount + "リンクを表示</h4><ol>"; // inboound linkの処理 for (var i=0; i < aResults.length; i++) { html += "<li><strong>" + aResults[i].Title + ":</strong> <a href='" + aResults[i].Url + "'>" + aResults[i].Url + "</a></li>"; } // inbound liskのlistの終端 html += "</ol>"; } else { // inbound linkがない場合。 var html = "<h3>リンクが見つかりませんでした。</h3>"; } //insert string into DOM: elResults.innerHTML = html; } }; }(); //DOMは完全にloadされたら、サンプルを初期化する。 YAHOO.util.Event.onDOMReady( //DomReadyイベントで発火するハンドラ YAHOO.EGP.NewsPicker.init, //ハンドラに渡すオブジェクト(関数) YAHOO.EGP.NewsPicker, //ハンドラは、上記のオブジェクトのスコープをもつ。 true ); </script> </HEAD> <!-- class=" yui-skin-sam"の指定はbuttunのskin適用に必要 --> <BODY class=" yui-skin-sam"> <div id="container"> <div id="buttonContainer"> <!-- bottunインスタンスを動的に作成して、突っ込む。 --> </div> <div class="module"> <div class="hd"><h2>In the News:</h2></div> <div class="bd" id="results"> <!--News stories will be displayed here.--> </div> <div class="ft"> <div id="searchControls"> <!--Use a real form that works without JavaScript:--> <form id="newsSearch" method="GET" action="xxx"> <label for="searchString">Search Yahoo! News:</label> <input id="searchString" type="text" name="p" value="イチロー" size="40"> <input id="getNewsData" type="submit" value="Search Yahoo! News"> </form> </div> </div> </div> </div> </BODY> </HTML>