AJAX流行中
AJAXアプリ特集
RSSを辿っていたら、たまたまAJAX関連が多かったので、今日は僕が使っているAJAXのWebアプリをご紹介したいと思います。
ところでみなさんは、『AJAX』って何て読んでますか? 僕は「えいじゃっくす」ですけど、「あじゃっくす」派もいるみたいですね。 まぁ、「りなっくす」か「らいなっくす」か、みたいな物でしょうか。
※ブログ移転しました。 → hamashun.me
RSSを辿っていたら、たまたまAJAX関連が多かったので、今日は僕が使っているAJAXのWebアプリをご紹介したいと思います。
ところでみなさんは、『AJAX』って何て読んでますか? 僕は「えいじゃっくす」ですけど、「あじゃっくす」派もいるみたいですね。 まぁ、「りなっくす」か「らいなっくす」か、みたいな物でしょうか。
Youtubeを簡単にBlogに貼り付ける方法として、ページ中央カラム上部のEmbed内のソースを貼り付けるという方法があります。
しかしこのソースには<embed>タグが使用されているので、XHtmlではNot Validなマークアップになってしまいます。
これを回避する方法はいくつかあると思うんですけど、今回はJavaScriptを使って安易に解決してみたいと思います。
という流れ。 正直、楽しかった。 でも、やっぱりネタ度でグリモンに負けちゃうなあ。
なので、自分の中のグリモン熱が上昇中。
JavaScriptとかjQueryとか勉強中なので、勘違いしている部分があるかもしれません。 もし誤りがあったら、ご指摘頂けると嬉しいです。
前回と前々回では、CSSで半ば無理やりグラデーション角丸+リキッドレイアウトを組んでみました。 この種類の角丸デザインはCSSを書く上で必要な要素の数が多くなってしまうので厄介、というのがこれまでのあらすじ。
今回はCSSだけにこだわらず、スクリプトを使ってみたいと思います。
jQueryを使います。 jQueryの特徴は色々あるんですが、ノードの取得にCSSセレクタみたいな書き方ができるのがとても気に入っています。 普段CSSを書いている人にはとても使いやすいです。
今回のサンプルでは使ってないですけど、jQuery越しにCSS3のセレクタが使えたりするのも魅力です。 しかもIE5.5以上に対応。
今回もサンプルを用意しました。 対応ブラウザはIE5.5以上、Firefox2、Opera、Safariです。 MacIEはjQuery自体が対応していないみたいです。
例によってDL版も用意しましたので、こねくりまわしてみてください。
サンプルのJSソースはとてもシンプルです。
jQueryは、wrap()メソッドを使うとその要素をWrap(包むの意味。ちなみにサランラップのラップもこれ)してくれます。 例を挙げると、
$("div.entrytWrap").wrap('<div class="wrap1"></div>');
は、「<div class="entrytWrap">を<div class="wrap1">でwrapせよ(囲え)」という命令になります。 その結果、
<div class="wrap1">
<div class="entrytWrap">
</div>
</div>
こんな結果になります。 これでdivが一つ増えました。 あとはこの繰り返しでdivを増やして、その増やした要素に対してCSSで背景画像を指定するだけです。
サンプルでは少し工夫した書き方にしていて、量を減らしてあります(多分、工夫の余地はもっとあるんでしょうけど)。
ノードの取得はCSSのセレクタのように、カンマ区切りで複数指定が可能です(DL版に入っているkadomaru.jsのdiv.hogehogeって辺りがそれです)。
ちなみに、JavaScriptをオフにしている環境などを考えて、その場合はborderで囲われるようにしてあります。
「JSで要素を増やすんなら、HTMLに直接書いても同じじゃん」と思う人がいるかもしれません。 しかし、HTMLに直接記述するのとDOMを操作して要素を追加するのでは意味が違うと思います。
DOMを操作して追加した要素は、(例えばJavaScriptでもって行ったなら)JavaScriptがオフの場合は現れません。 HTML文書単体として見ればその要素は追加されていないと言うか、HTMLは(余計なdivによって)汚されない。
サンプルのclass名がわりと適当な感じなのも同様の理由です(見栄えを考えるとそれっぽい名前にした方がいいかもしれませんけど)。
DOMの仕様書にその辺りの説明(DOM操作によって追加されたノードの扱い、みたいな)があるかなと思って探したんですけど、見つけられませんでした(見落としてるのかな)。
とは言え、本来CSSが担当するべき「デザイン(表現)」をスクリプトで補っているのは確かで、そこはちょっとどうかなと思う所ではあります。 ただまあ、デザインを再現する際に文書上必要な要素のみで行うのが難しい(事がままある)現状では、手段の一つとして覚えておいてもよいのではないでしょうか。
JavaScript楽しい! これまでのHTML+CSSでは難しかった事が簡単にできたりします。
とは言ってもまだDOMごにょごにょぐらいしかできないから、「JSはDOMだけじゃ無いからね」って会社の人達にまた言われそう。
今回のサンプルもミスターjQueryのabuiさんに手伝ってもらって完成できたしなあ。
つまり何が言いたいかと言うと、hamashun.comはRoppongi.JSに超期待してるって事です!><
参考:UNIXに触り初めて一応7年・・・だけど・・・。 - devlog.holy-grail.jp
前回、前々回の記事同様、Webアクセシビリティ ~標準準拠でアクセシブルなサイトを構築/管理するための考え方と実践~の出版記念セミナーのまとめです。
10章の翻訳をされたのは中村精親さんですが、セミナーでは渡辺さんが話をしてくれました。 内容はアクセシブルなJavaScriptについてです。
なお、便宜上この記事では音声支援技術をスクリーンリーダーと呼んでいます。
資料へのリンク
JavaScriptは、アクセシビリティを妨げる使われ方が多かった。 例えば、右クリック禁止やポップアップ・ウィンドウなど。
また、アクセシブルでないスクリプトにより、JavaScriptをオフにすると利用できなくなってしまうコンテンツが(現在でも)ある。
原著を書いたのはChristian Heilmann。 ChristianはWaSPのDOMスクリプティング・タスク・フォースのメンバー。
Christianは、でしゃばらないJavaScriptがよいと言う。 JavaScriptが無い環境でも得られる情報は同じで、JavaScriptが利用できる環境では更にリッチな体験ができる、というように。
(この辺、Webデザインで言うところのMOSeを連想させますね。 アクセシビリティ関係ないですけど)
HTMLが構造、CSSが表現であるなら、JavaScriptは振る舞いであると言える。
これは、書籍から離れた内容。 GoogleのiGoogleとGoogleドキュメントのアクセシビリティについて。
なお、この調査は渡辺さんの生徒さんによるものだそうです。
渡辺研究室の2007年度卒業研究「JavaScriptを利用した動的なWebのアクセシビリティ」(松田理沙)から,GoogleのRIAのアクセシビリティ問題のケーススタディを紹介.
との事。(資料11ページより)
(セミナーでは悪い点ばかりが取り上げられていましたが、良い点もあったのでしょうか? 気になるところです)
ホームページリーダーを使用すると、キーボードで操作できない部分がある。 これらは内容を持たない要素と背景画像でコーディングされているので、HTML的には意味の無い存在という扱い。
他にも、Googleドキュメントにある「新規作成」というタブをクリックすると「リンクではありません」と読み上げられる(div要素やspan要素でマークアップしてあるため)。
Webアプリケーションのショートカットキーと、スクリーンリーダーのショートカットキーが競合してしまう事がある。 これは本質的な問題である。
Googleドキュメントでは、ドロップダウンメニューを開くとHTMLの最後にソースが追加される。 その為、スクリーンリーダーでは開いた時には読み上げられない。
例えば、nowaの管理画面では自動的に新着記事を表示しますが、スクリーンリーダーでは更新がなされた事を知る術がない。
WAI-ARIAのlive属性はこの問題を解決できるかもしれない。
(WAI-ARIAについては、梅垣さんの(今回のセミナーとは関係の無い)資料Ajaxアクセシビリティ~リッチ・インターネット・アプリケーションのゆくえ~が解りやすいかも)
アクセシビリティ業界(?)では、JavaScriptは悪役にされがちな気がします。
hamashun個人としては、「全てのWebサイトはアクセシブルなJavaScriptを採用すべき」という必要は無いと思います。
伝えたい情報が伝えたい相手に正しい形で伝わる事が大事なのであって、HTMLやCSSやJavaScriptなどの技術はその手段であるべきだと考えます(ここで言う情報とはテキストのみならず、デザインや操作感も含みます (いわゆるUser Experienceと言えるかも))。
JavaScriptの習得のために、とりあえず今期中は、週に一つはJavaScriptで何かを作る事にしました。 これは会社で設定した個人目標でもあります。
できた物はJavaScript1000本ノックで作った物を置いていく場所に追加していきます。
自分で定めたルールは以下です。
ちなみに1000本という数字は言葉のアヤです。
11月1週目のJavaScriptです。やりたかった事は以下。
jQueryを使用しています。
$(function () {
var searchInpt = $("#searchText");
var defaultVal = searchInpt.attr("value");
searchInpt.css("color","#999");
searchInpt.focus(function() {
if (searchInpt.attr("value") == defaultVal) {
$(this).css("color","#ddd").attr("value","");
}
}).blur(function() {
var nowVal = searchInpt.attr("value");
if ($(searchInpt).attr("value") == "") {
$(this).css("color","#999").attr("value",defaultVal);
}
});
});
変数に代入した結果は、その時点で保存されるという事。
例えば最初の方で var defaultVal = searchInpt.attr("value");
して、その変数に格納された値は、その後のブラウザ上の操作でvalueを変えても(その変数内では)替わらない。 処理を代入してるんじゃなくて処理の結果を代入していると言うか何と言うか。
なんかでも、条件によってはそうでもなかったような事があったような気がするのでその内また解るかも。
「スクリプトを適用する要素」を指定する方法(コード1行目)を、ある程度汎用的にしたい。
今はidを直接指定しているので、そこを「jsファイルを読み込ませたら全てよしなにやってくれる」的にしたい。
「inputのtypeがtextで、かつデフォルトでvalueの中身に何か入ってる場合」とかでif文かなー。 JS側でclassをキメて、それをHTMLに書くのはちょっともにょるしなあ。
11月2週目のJavaScriptです。やりたかった事は以下。
jQueryを使用しています。
$(function () {
var wrapper = $('div.wrapper');
var boxs = $('div.contents');
var tabBtn = $('h1.title');
$(wrapper).css({
height: '224px'
});
$(boxs).css({
position: 'absolute'
});
$(tabBtn).css({
position: 'absolute',
top: '-98px',
cursor: 'pointer'
});
function zIndexReset(){
$(boxs).css('z-index','1');
}
tabBtn.click(function(){
var tabBtnVal = $(this).attr('id');
var divId = tabBtnVal.replace('Title','');
zIndexReset();
$('#' + divId).css('z-index','2');
});
});
「いやそれ常識だしw」とか思われそうで恥ずかしいんですが、「処理を関数にして呼び出せるようにする」という感覚が、少しだけ自分になじんだと言うか。 これまでは「jQueryの仕組み上functionと書かないといけないから書く」みたいな使い方が多かった気がします。
実は以前、半年くらいかけてサイ本をある程度読んだんですけど、実際にJSのコードを書いているとふっと「あ、これサイ本に載ってた記憶がある」みたいな瞬間があって、あのツライ読書(1P読むのに数時間とか)は無駄じゃなかったのかなとか思ったり。 1000本ノックが終わったらまた再読したい。
書いたJSは「同じ機能なら複数の案件で使いまわせたほうがいい」と考えていたのですが、faultierの人が書いてくれた言及記事や、自分で実際にJSを書いている内に感じた事から、HTMLに使うJSなら、そのHTMLに合わせて(必要なら毎回)書いた方が良いんじゃないかと思えてきました。
あ、もちろん、使いまわせるライブラリを使った方が良いケースもあるんでしょうけど。
z-indexの操作が満足いってないです。 赤を最上段にしてから青をクリックすると重なり順がおかしくなってしまう。
これを解決するには、「クリックした時点で3つ全てのz-indexを取得して、その中の最大の値に+1して該当の要素に指定する」とか・・・かな・・・! 難しそうorz あと、若干重箱の隅ですけど、z-indexの最大値の件も問題としてはあると言えばある。
まあ、そもそも何故z-indexでやってるのかと言うと、少しづつズラして配置しているデザインのためなので、3枚とも完全に重なっているデザインなら、displayプロパティでタブ切り替えを行ってしまえば簡単だったりはします。
11月3週目のJavaScriptです。やりたかった事は以下。
結局jQueryを使用しました。
$(function () {
var ua = $.browser;
if(ua.msie) {
function inputFocus(inputId){
$('#' + inputId).focus().click();
}
$('label').click(function(){
var labelFor = $(this).attr('for');
inputFocus(labelFor);
});
}
});
input要素のtype属性がtextのみなら .focus(); で問題無かったのですが、checkboxやradioがあると .click(); も必要になりました。 で、そうなるとFirefoxでは逆にうまく動かなくなってしまいます。
それでは困るので、hokacchaさんのjQueryで簡単UserAgent判別 - Webtech Walkerを参考にUAで振り分けました。 ただし、この問題の解決方法は条件付コメントでも良いと思います。
今回は比較的、使い回しを考えたコードを書きやすいかもしれないと思ったので、jQuery無しで書いてみようと思いました。 無理でした。
document.getElementById で取得した要素は onclick(); で動くのに、document.getElementsByTagName('label') で取得した要素は onclick(); が動かなくて、それじゃあってんで散々こねくり回した末に、
var labels = document.getElementsByTagName('label');
for(var i=0; i<labels.length; i++){
var labelFor = labels[i].getAttribute('for');
alert(labelFor);
}
としたら、Firefoxではうまく取得できたけどIEだと nullnullnull... ってなってしまい、心が折れたと言うかヌルヌルすぎと言うか。
jQuery無しで同じ事ができるようになりたい。 もうちょっと色々分かってきたら、再挑戦したい。
ちょっと遅れましたが、11月4週目のJavaScriptです。やりたかった事は以下。
jQueryを使用しています。 IEは naturalWidth が効かないので、まだ対応できてません。
$(function () {
var thumbnail = $('#thumbnail li a'); // このセレクタを変えれば使いまわし可能
thumbnail.click(function(event){
event.preventDefault(); // リンクの遷移を止める
var clickHref = $(this).attr('href'); // 以下、クリックしたサムネのリンク先を取得して表示
$('<img>').attr('src', clickHref).bind('load', function(){ // 内部でDOM生成。続きは画像のロードが終わってから進む
var htmlElement = $('html'); // ブラウザの表示領域(高さ)を取得
var htmlHeight = htmlElement.height(); // ブラウザの表示領域(高さ)を取得
htmlElement.css('height', htmlHeight + 'px'); // 背景が見切れないようにheightを指定
var originalImageSize = this.naturalWidth; // リンク先の画像サイズ取得
$('body').append('<div id="hmsnBox"><div id="hmsnBoxOuter" style="height: ' + htmlHeight + 'px;"></div><p id="hmsnBoxInner" style="width: ' + originalImageSize + 'px"><img src="' + clickHref + '" alt="" /><span id="hmsnBoxClose">Close</span></p></div>');
$('#hmsnBoxClose').click(function(){ // 閉じる
$('#hmsnBox').remove();
});
});
});
});
$("body")で高さを取得したら、縦marginの影響でズレてしまったので、$("html")で取得したら思い通りになった。
なんか違うらしい。
こんな感じ。
これまで他の人が書いたコードを見て「なんでこんなにたくさん入れ子になりまくるんだろう」と思っていたのだけど、なんとなくわかったような気がしないでもない。
jQueryは、単に $('<img>').attr('src', 'hoge.jpg') などとすると、表示はせずに内部で生成してくれる。 で、その画像のサイズを取得する処理が画像自体のロード完了より先に動いてしまうので、上手くいかなかった。
会社の人に聞いて、ロード完了後に取得するようにして解決。 ありがとうございます><
12月2週目のJSです。 ごくごく簡単なTwitter APIを練習してみました。 やりたかった事は以下です。
jQueryを使用しています。
$(function () {
function twitterSearch(searchWord) {
$.ajax({
url: 'http://search.twitter.com/search.json',
data: {
'q': searchWord,
'rpp': 10,
'lang': 'ja'
},
type: 'get',
dataType: 'jsonp',
success: function(data){
$.each(data.results, function(i, itm) {
$('#twitterSearch').append('<li><a href="http://twitter.com/'+itm.from_user+'/" class="searchResultUser"><img src="' + itm.profile_image_url + '" alt="" width="48" /><span>'+itm.from_user+'</span></a><p class="searchResultText">'+itm.text+'<a href="http://twitter.com/'+itm.from_user+'/status/'+itm.id+'">Status page</a></p></li>');
});
}
});
}
$('#searchTwitter').click(function(){
$('#twitterSearch').empty();
var searchWord = $('#searchWord').val();
twitterSearch(searchWord);
});
});
jQueryを使うと、なんとか理解できるくらいにはなりました。
忘れないようにと復習も兼ねて今回のコードで解説すると、まず一行目の
$('#searchTwitterForm').after('<ul id="twitterSearch"></ul>');
は、検索結果を出力する場所を作っています。
$.ajax({
url: 'http://search.twitter.com/search.json',
data: {
'q': searchWord,
'rpp': 10,
'lang': 'ja'
},
type: 'get',
dataType: 'jsonp',
ここまでが前半で、Twitter に欲しい内容を伝えるための部分。 なんとなくCSSっぽい書式で親しみ深いです。
success: function(data){
$.each(data.results, function(i, itm) {
$('#twitterSearch').append('<li><a href="http://twitter.com/'+itm.from_user+'/" class="searchResultUser"><img src="' + itm.profile_image_url + '" alt="" width="48" /><span>'+itm.from_user+'</span></a><p class="searchResultText">'+itm.text+'<a href="http://twitter.com/'+itm.from_user+'/status/'+itm.id+'">Status page</a></p></li>');
});
これが、通信が成功した後に取ってきたデータをどう処理するのか、という部分。
ここまでの流れが、jQueryでAjax開発をする時の基本的な部分かなと。
$('#searchTwitter').click(function(){
$('#twitterSearch').empty();
var searchWord = $('#searchWord').val();
twitterSearch(searchWord);
});
ここは、フォームに入力したテキストを上記の処理に渡すための部分です。
セキュリティの関係上、JavaScriptではドメインの異なるファイルは取得できません。 それをバックエンドに頼らず簡単に解決してくれるのが今回も使ったjsonpなのです。 …が、ちょっとまだ理解しきれてないと言うか。 いや、ソースとして取得するっていうのは解ったんですが、言葉でなく心で理解するまでには至ってないと言うか。 まあ、なじんでないだけかも。
※IE8では動作が確認できたんですが、IE Testerだと6,7,8でダメでした。 時間と環境が取れたら純正IE6,7環境でも試してみます。
12月3週目のJavaScriptです。 適用したいセレクタを入力してclearfixのコードを吐き出す何かを作ってみました。 出力のセレクタ部分はカンマで改行することもできます。
単純に文字列を取得して定型文に組み込んでいるだけなんですが、組み込む場所がまちまちだったりして書いてる内に混乱してきました。 シンプルにできる事を複雑にしてしまってる気がする。。。
jQueryを使用しています。
$(function () {
$('#clearfixGeneration').click(function(){
$(this).empty();
var new_line_switch = $('#newLineOn').attr('checked');
var selecter_val = $('#selecterInput').val();
var comma_length = selecter_val.split(',').length;
var selecter_text = selecter_val.split('\n');
for(i=0; i<comma_length; i++) {
var selecter_ie6 = '* html ' + selecter_text[i];
var selecters_ie6 = selecter_ie6.replace('\n', '');
if (ie6) {
ie6 = ie6 + selecters_ie6;
if(new_line_switch) {ie6 = ie6.replace(',*', ',\n*');}
} else {
var ie6 = selecters_ie6;
if(new_line_switch) {ie6 = ie6.replace(',*', ',\n*');}
};
var selecter_ie7 = '*:first-child+html ' + selecter_text[i];
var selecters_ie7 = selecter_ie7.replace('\n', '');
if (ie7) {
ie7 = ie7 + selecters_ie7;
if(new_line_switch) ie7 = ie7.replace(',*', ',\n*');
} else {
var ie7 = selecters_ie7;
if(new_line_switch) ie7 = ie7.replace(',*', ',\n*');
};
var selecter_modernbrowser = selecter_text[i] + ':after';
var selecter_modernbrowser_substitution = selecter_modernbrowser.replace(',:after',':after,');
var selecters_modernbrowser = selecter_modernbrowser_substitution.replace('\n', '');
if (modernbrowser) {
if(new_line_switch) {
modernbrowser = modernbrowser + selecters_modernbrowser.replace(':after,', ':after,\n');
} else {
modernbrowser = modernbrowser + selecters_modernbrowser;
}
} else {
if(new_line_switch) {
var modernbrowser = selecters_modernbrowser.replace(':after,', ':after,\n');
} else {
var modernbrowser = selecters_modernbrowser;
}
};
$('#clearfixDone').val(''+ ie6 +' {\n\tzoom: 1;\n}\n\n'+ ie7 +' {\n\tzoom: 1;\n}\n\n'+ modernbrowser +' {\n\tcontent: ".";\n\tdisplay: block;\n\tclear: both;\n\theight: 0;\n\tvisibility: hidden;\n}');
}
});
});
12月4週目のJavaScriptです。 Twitter Search的な何かをもう少し発展させてみました。
jQueryを使用しています。
$(function () {
$('#friendTweetForm').after('<ul id="friendTweet" class="tweetList"></ul>');
function friendTweet() {
$.ajax({
url: 'http://twitter.com/statuses/home_timeline.json',
data: {
'callback': 'friendtweet',
'count': 100
},
type: 'get',
dataType: 'jsonp',
success: function(friend_data){
$.each(friend_data, function(i, friend_item) {
$('#friendTweet').append('<li class="tweet"><a href="http://twitter.com/'+ friend_item.user.screen_name +'/" class="icon"><img src="'+ friend_item.user.profile_image_url +'" alt="" width="48" height="48" /><span class="name">'+ friend_item.user.name +'</span></a><p class="text">'+ friend_item.text +'<a href="http://twitter.com/'+ friend_item.user.screen_name +'/status/'+ friend_item.id +'">Status page</a></p></li>');
});
}
});
}
$('#friendTweetBtn').click(function(){
$('#friendTweet').empty();
friendTweet();
});
$('#mentionsTweetForm').after('<ul id="mentionsTweet" class="tweetList"></ul>');
function mentionsTweet() {
$.ajax({
url: 'http://twitter.com/statuses/mentions.json',
data: {
'callback': 'mentionstweet',
'count': 20
},
type: 'get',
dataType: 'jsonp',
success: function(mentions_data){
$.each(mentions_data, function(i, mentions_item) {
$('#mentionsTweet').append('<li class="tweet"><a href="http://twitter.com/'+ mentions_item.user.screen_name +'/" class="icon"><img src="'+ mentions_item.user.profile_image_url +'" alt="" width="48" height="48" /><span class="name">'+ mentions_item.user.name +'</span></a><p class="text">'+ mentions_item.text +'<a href="http://twitter.com/'+ mentions_item.user.screen_name +'/status/'+ mentions_item.id +'">Status page</a></p></li>');
});
}
});
}
$('#mentionsBtn').click(function(){
$('#mentionsTweet').empty();
mentionsTweet();
});
$('#searchTweetForm').after('<ul id="searchTweet" class="tweetList"></ul>');
function twitterSearch(searchWord) {
$.ajax({
url: 'http://search.twitter.com/search.json',
data: {
'q': searchWord,
'rpp': 10,
'lang': 'ja'
},
type: 'get',
dataType: 'jsonp',
success: function(search_data){
$.each(search_data.results, function(i, search_item) {
$('#searchTweet').append('<li class="tweet"><a href="http://twitter.com/'+search_item.from_user+'/" class="icon searchResultUser"><img src="' + search_item.profile_image_url + '" alt="" width="48" /><span class="name">'+search_item.from_user+'</span></a><p class="text searchResultText">'+search_item.text+'<a href="http://twitter.com/'+search_item.from_user+'/status/'+search_item.id+'">Status page</a></p></li>');
});
}
});
}
$('#searchTwitter').click(function(){
$('#twitterSearch').empty();
var searchWord = $('#searchWord').val();
twitterSearch(searchWord);
});
});
jQueryを使用しています。
$(function () {
$('.wrap').hide();
$('#friendTweetWrap').show();
$('h3.twitterHeadline').css({
'position': 'absolute'
});
$('#twitter h3').click(function(){
$('h3.twitterHeadline').attr('class', 'twitterHeadline');
$(this).attr('class', 'now twitterHeadline');
var clickTabId = $(this).attr('id');
var showTargetForm = clickTabId.replace('Headline', 'Wrap');
var showTargetUl = clickTabId.replace('Headline', '');
$('div.wrap').hide();
$('ul.tweetList').hide();
$('#' + showTargetForm).show();
$('#' + showTargetUl).show();
});
});
12月5週目のJavaScriptです。 IEでもimg要素のlabelを効かせるのjQuery無しでも動く版です(hokacchaさんアドバイスありがとうございます!)。
IE以外では必要ないので、@cc_on ってなに? - Clouder::Bloggerを参考にして振り分けてみました。
/*@cc_on
var labels = document.getElementsByTagName('label');
for(var i=0; i<labels.length; i++) {
labels[i].labelFor = labels[i].getAttributeNode('for').nodeValue;
labels[i].onclick = function () {
var cursorTarget = document.getElementById(this.labelFor);
cursorTarget.focus();
cursorTarget.click();
}
}
@*/
ここの所忙しいのもあって、ちょっと遅れ気味だなあ。 まあ遅れるのを見越して目標設定しているのでギリセーフ。
2010-02-01:サンプルページのリンクが切れていたので直しました。
1月1週目のJavaScriptです。 type="image"なフォームボタンをマウスオンでロールオーバーします。 jQuery使用。
$(function () {
var preload_btn_num = $('div.submit input[type="image"]');
for(var i=0; i<preload_btn_num.length; i++) {
var preload_btn_src = $(preload_btn_num[i]).attr('src').replace('.png', '');
var preload_btn = preload_btn_src + '_on.png';
$('<img>').attr('src', preload_btn);
}
$('div.submit input[type="image"]').hover(function(){
var btn_src_full = $(this).attr('src');
var btn_src = btn_src_full.replace('.png', '');
var on_src = btn_src + '_on.png';
$(this).attr('src', on_src)
}, function(){
var btn_src_png = $(this).attr('src');
var btn_src = btn_src_png.replace('_on', '');
$(this).attr('src', btn_src)
});
});
処理を変数に代入→次の行でそれを使って処理をして変数に代入、みたいな部分は一行で書いた方がいいんだろうか。 個人的には別々にした方が読みやすいのだけど。
1月2週目のJavaScriptです。 フォームにテキストを入力してボタンを押すと、リストの中から該当した物だけを残して非表示にします。 jQuery使用。
$(function (){
var ranking_list = $('#designerList li');
function list_search() {
$(ranking_list).show('fast');
var search_word = $('#searchInput').val();
if(search_word){
$(ranking_list).not($(ranking_list + ':contains(' + search_word + ')').closest('li')).hide('fast');
} // end if
}
$('#searchButton').click(function(){
list_search();
});
/*@cc_on
var key_code = 0;
$('#searchInput').keydown(function(down){
if (down.keyCode == '13')
list_search();
});
@*/
});
IEは入力フォームでエンターを押しても動作してくれなかったので、キーコードを直接送る事で対応しました。
今回もIEにのみ読み込ませるようにしたのだけど、この手の部分はどうするのが良いのかなあ。 Firefoxなども適用してしまっていいんだろうか。
テキストノードを取得する部分と、非表示にするのは該当した物以外である所が大分苦労しました。 会社のプログラマーの人に聞いたりして。
1月3週目分のJavaScriptです。 canvasにさわってみようがテーマ。 塗りと直線で構成されたモンドリアンっぽい絵ならすぐに描けるんじゃね、って思いついて試してみました。
$(function(){
var canvas = document.getElementById('test');
if(!canvas.getContext) return;
var ctx = canvas.getContext("2d");
ctx.fillStyle = "rgb(200, 0, 0)";
ctx.fillRect(100, 0, 300, 300);
ctx.fillStyle = "rgb(0, 0, 0)";
ctx.fillRect(85, 0, 15, 400);
ctx.fillStyle = "rgb(0, 0, 0)";
ctx.fillRect(0, 150, 85, 25);
ctx.fillStyle = "rgb(0, 0, 0)";
ctx.fillRect(0, 300, 400, 15);
ctx.fillStyle = "rgb(0, 0, 0)";
ctx.fillRect(350, 310, 15, 90);
ctx.fillStyle = "rgb(0, 0, 0)";
ctx.fillRect(365, 350, 40, 15);
ctx.fillStyle = "rgb(0, 0, 200)";
ctx.fillRect(0, 315, 85, 85);
ctx.fillStyle = "rgb(250, 250, 0)";
ctx.fillRect(365, 365, 35, 35);
});
手動で描くと大分面倒くさい。
今回はRectしか使ってないので、もっと色々使ってみたい。
溜まってる分をある程度一気にやりました。
例によって手書きでグラフを書いてみたんですが、canvasの座標は左上からだけどグラフの座標は左下なのが面倒でした。 今度はカンマ区切りとかの値を渡して表示させたい。
ここ最近は、DateオブジェクトとかMathオブジェクトとかいう、いわゆる組み込みオブジェクトを使う機会がありました。 本で読んだ事はあったんですが、実際に使った事はあまりなかったので新鮮でした。 便利だなーと言うか。
タイマーとかランチとかは完全に自分用です。
簡単便利。 サンプルが超分かりやすいですね。 英語は読めないけどコードだけ読んだらどうにかなる感じ。
idやclassを自由に変えられるっていうのがマークアッパー好みですね。 すごいなーこれ。