#iphone

前回の記事:「iPhoneのPDF Viewer:GoodReader」ではざっと紹介しましたが、

GoodReaderは横スクロールを固定できる、

しかしダブルクリックではスクリーンが拡大され、

その時スクロールの固定は解除されてしまいます。

せっかく調整したスクロールが誤操作で崩れるのは厄介ですね。

そこで今回の記事でちょっと詳しくGoodReaderの設定について

説明したいと思います。

General Settings

  • Reopen last file
    • Onに設定すると常に前回開いたファイルを開く
    • 同じ設定がiPhone全体の設定にも変更できる
    • 無限クラッシュがあるらしいのでOFFに設定
  • Screen orientation
    • Allow autororations ONに設定すると自動に横、縦向き変更に対応。
    • Restore orientation on startup これは上記自動向き変更をOFFに設定する時のみ有効になる。ONにすると起動時に向き縦向きに回復

  • Disable device auto-lock 自動ロックを停止。ONにするのをおすすめ。突然ロックされ暗くなるのは嫌よね。
  • Ask for link action ONにすると閲覧中にリンクをタップするとどうするか毎回聞くので、OFFにするのをおすすめ。本を読む時はやはり集中するのが一番。

PDF Settings

次に「View PDF files」からPDF閲覧を設定しましょう。

  • PDF Link has priority これは上記と同じようにOFFにするのをおすすめ。
  • Double-tap for zooming これが今回記事のポイント!OFFに設定するのをおすすめ!PDFの資料を読む時は大体の場合はやはり自分でスクロールを調整し固定しますね。ダブルクリックによる拡大はスクロールも崩れるし、また拡大倍数が適切ではないの感じです。

Good Reader購入はこちら

#jquery

マインドマップでまとめました。ごらんください。

基本的な使い方はほかのサイトでもいっぱい書いてるため、

省略します。

大まかな仕組みだけをメモとして書きたいと思います。


最初に理解してほしいのはルールと検証メソッドです。

これはペアとして使います。

まずルールでは検証したい項目のname属性と適用するルール名を書きます。


例えばこんな感じです。

rules: {
  comment: {
    required: true,
    minlength: 5
  }
}

これはname属性がcommentの要素に対してrequiredとminlengthのルールを適用する意味です。

ルールの詳細はつまり検証メソッドに実装されています。

required,minlengthなどはプラグインのbuilt-inルールです。

ここでrequired(必須)は実際どう実装されたかをちらっと見てみましょう。

(私も実は初めてです。。。)

以下抜粋したコードです。

required: function (value, element, param) {
    // check if dependency is met
    if (!this.depend(param, element)) return "dependency-mismatch";
    switch (element.nodeName.toLowerCase()) {
    case 'select':
        var options = $("option:selected", element);
        return options.length > 0 && (element.type == "select-multiple" || ($.browser.msie && !(options[0].attributes['value'].specified) ? options[0].text : options[0].value).length > 0);
    case 'input':
        if (this.checkable(element)) return this.getLength(value, element) > 0;
    default:
        return $.trim(value).length > 0;
    }

一番デフォルトな行為はこれですね。

return $.trim(value).length > 0;

単純にその項目のvauleをtrim(スペースを取り除く)して長さを確認してます。

その前に要素がselectの場合や、inputの場合の判断がそれぞれ違います。

最初にdependがあるのですが、これは簡単に言うとこの要素が必須項目となるのはある前提がある意味です。


これが一番基本の仕組みとなってます。

これ以外もメッセージの内容や位置、

どのタイミングで検証するか、

エラーがある場合のコールバックなどを各自でカスタマイズできるようになってます。


参考となったサイト:

#html

目的

見たの通りform前後の余白を消しました。

これはフォームがテーブルなどを跨がる場合に

レイアウトを調整するのに非常に役に立ちます。

方法

formのmarginを0pxに設定します。

<form style="margin: 0px;">

またmargin-topやmargin-bottomでなどで詳しく指定できます。

マイナス値も入力でき、さらに間隔を縮むめることができます。

参考となったサイト:http://www.1uphp.com/con1/form/form1style.html

#diary

私服よりスーツ

最初のうちはまだ本社で私服で出勤する同僚がうらやましかったのです。

私はお客さんに常駐し毎日スーツでした。

ある日、先輩の一言で突然目覚めた感じです。

「私服じゃ仕事する気がなくなっちゃう」ってね。

それに、スーツでもかっこいいスーツがあるし、

ファッションもできますよね。

ブラックコーヒー

これも甘いものが好きだっだのですが、

いつの間にか、気づいたらもう毎日ブラックじゃないとだめになっちゃいました。

仕事する上で、やはりブラックが一押し!

酒(特に生ビール)

がんばった一日の最後に生ビール一杯で、

本当に「うわぁ~~」って感じ

#jquery

jQueryの$.extendはとても便利な機能です。

jQueryのプラグインを作成する場合は以下の二つを利用します。


$.extend(object) //jQueryそのものを拡張する
$.fn.extend(object) //jQueryエレメントに新しいメソッドを追加する。
//(典型的なjQueryプラグインの作成方法)


今回検討するのは第三の使い方です。

$.extend(target,option,...);

これは第一のパラメータのオブジェクトをどんどん拡張する意味です。

実際のプログラミングではこんな使い方が両方あります。

$.extend(target, option);
$.extend({}, target, option);


違いは何でしょうか?


$.extend(target, option);

これはtargetそのものを拡張する意味です。

実行後targetオブジェクトは変更(拡張)されます。


実例として、例えばプロジェクトにトップレベルの空のConstansクラスがあります。

その下で各モジュール要のconstantsが定義されていて、

それをトップのConstantsに拡張します。

$.extend(constants,subConstants1,subConstants2...);

落とし穴:

var defaults = {};
var option = {};
var opts = $.extend(defaults,option);

上記ではdefaultsが変更され、わざわざ変数optsに代入する意味もなくなります。


$.extend({}, target, option);

これは空のオブジェクトを拡張する意味です。

実行後、targetもoptionもかわらりません。

最も多く使われている実例は、jQueryのプラグインの開発です。

あるデフォルトのoptionを定義し、

ユーザが自分のニーズにあったoptionがあればそれを適用する感じです。

ここで大事なのは定義したデフォルトのoptionはかわりたくないのです。

なので、最初に空のオブジェクトを拡張しそれを何かの変数に

リファレンスをアサインします。


var defaults = {};
var option = {};
var opts = $.extend({},defaults,option);

これで変数optsは求めているデフォルトoptionとユーザが定義したoptionをマージ、拡張したものとなります。

#jquery

前記:

この記事では多数のAJAX通信が発生した際、 「非同期」の処理順番を保障する方法を検討します。 すべては私個人の経験なので、もしこれよりもっどいい方法があれば ぜひ教えてください。 実際この問題にぶつかった際の考えの流れで書いています。 使えない案や、懸念がある案も全部述べたので、文章が長くなってしまいました。 開発する当時はまだインターネットにつながらないので、 何の情報も取得できず、考えたんです。 後でネットで調べたらAjax Queueのプラグインが 同じことをしてくれます。 このプラグインを使った後に所感を書く予定です。

本題

AJAXはご存知だと思います。非同期通信でページをリフレッシュせずに動的に通信ができる、 リッチなウェブアプリケーションを構築する上で不欠けんな存在であります。

一方、この「非同期」というのは特徴であり、たまには厄介なことになります。 例えばajaxの処理と普通の処理の実行順序を気にするとき、 コードの書いた順番とおり実行する保障はありません。

jQueryでコードを書くと、こんな感じです。

$.ajax(option);
alert('ajax done');

ここでajax通信が終わってからalertが出るように見えますがそうとは言い切れないです。 ajax通信が終わってない段階でalertが出るかもです。 ならばどうしたらいいんですか?

一番簡単なのはjQueryが用意したコールバック関数です。

$.load(url, [data], [callback])
$.get(url, [data], [callback], [returnType])
$.getJSON(url, [data], [callback])

などがあります。 [data]がなければ、コールバックの関数を二番目のパラメータで書いてもOKです。 jQueryは内部的に判断してくれます。dataなのか、コールバックかを。

そして$.ajaxにはoptionでsuccessやcompleteにコールバックを設定できます。 これらを用いて上記のコードを以下のように改善できます。

$.ajax(option)の場合

.load(url,[data],[callback])
$.get(url,[data],[callback],[returnType])
$.getJSON(url,[data],[callback])

ここで問題2に入ります。

もし必要なajax通信が一つ以上で、すべてのajax通信が完了した後に何かの処理が実行したい場合は どうすればいいでしょうか。

コードで書くと、こんな感じです。

$.ajax(option1);
$.ajax(option2);
$.ajax(option3);
function(){
	alert('all ajax done');
}

案1:ajaxのグローバル関数

jQueryではajaxのグローバル関数と呼ばれるいくつかの関数を提供してくれました。 それらは以下のようなものです。

.ajaxComplete(handler)
.ajaxSuccess(handler)

これらはDOM上のどの要素にも設定でき、AJAX通信が行われる際に呼び出されます。

例えば以下のようなコードがあります。

$(document).ajaxComplete(function(){
	alert('ajax complete');
});

これはdocument要素において、何かのajax通信が完了したらパラメータのコールバックを実行する意味です。 selectorにはもっと範囲を縮むことができます。 例えばこんなHTMLがあるとします。

<div id='content'></div>

$('#content').ajaxComplete(function(){
	alert('content ajax complete');
});

これならidがcontentのdivにajax通信が完了する際のコールバックを示しています。

しかしこれだけではまだ問題2を解決できません。

$.ajax(option1);
$.ajax(option2);
$.ajax(option3);
$(document).ajaxComplete(function(){
	alert('ajax complete');
});

こう書くと、任意の通信が完了したらこのajaxCompleteが呼ばれ、 ほかの二つの処理がどうなってるかはまったくわからないです。

ここで$.ajax(option)のoptionに注目しましょう。 optionにはglobalというフラグがあり、デフォルトはtrueになってます。 その役割はグローバル関数の監視対象にするかしないかです。 このフラグをfalseに設定すれば、該当のajax通信がどうなってもグローバル関数はトリガーしません。 なので、通信処理1と2のglobalフラグをfalseに設定し、最後の処理3をtrueに設定すれば、 処理3が実行完了した際、グローバルのajaxCompleteが実行されます。

改善したコードは以下になります。一部省略しました。

var option1 = {
	global: false
	// ほかのurlなどの設定
}

var option2 = {
	global: false
	// ほかのurlなどの設定
}

var option3 = {
	global: true
	// ほかのurlなどの設定
}

$.ajax(option1);
$.ajax(option2);
$.ajax(option3);
$(document).ajaxComplete(function(){
	alert('ajax complete');
});

しかし、ここで懸念事項があります。 ajax処理の間の順番はどうなるか断言できません。 つまりこういった順番で実行されたかもです。

処理1実行 処理1完了 処理2実行 処理3実行 処理3完了 グローバルの関すを呼び出す 処理2完了

軽く動作確認ではちゃんと思ったとおり1,2,3で動いていますが、 やはりその辺が気になって、やめました。

案2:ajaxをラッパーした関数を作る

$.ajax(option)のoptionにはcompleteというのがあります。 successと使い方は同じで、successは通信が成功した際実行するコールバックで、 completeは完了した際のコールバックです。

なので今回思い出したのアイディアはこのcompleteに次のajax処理を指定して、 さらにその次のajaxのcomplete optionにも後のajax処理を指定したらどうでしょうか。 尻尾をどんどん噛んでいく蛇のイメージです。

(抜粋)

var option1 = {
	complete: $.ajax(option2)
}

var option2 = {
	complete: $.ajax(option3)
}

var option3 = {
	complete: function() {
		alert('ajax all complete');
	}
}

$.ajax(option1);

動作確認でOKでした。 completeオプションで前のajax通信が必ず完了した後に次のajax通信を始まることを保障しています。 これでajaxのチェインができました。

これをちょっと綺麗にラッパーした関数を作りました。 ご覧ください。

function doOrderGuaranteedAjax(ajaxOptionArray, allCompleteHandler){
  var defaults = {
    type : "GET",
    dataType : "text",
    complete : function() {
      // 最初の要素を削除
      ajaxOptionArray.shift();
      // すべての通信が完了した場合
      if (ajaxOptionArray.length == 0 ) {
        // コールバックが設定された場合
        if (allCompleteHandler) {
          allCompleteHandler();
        }
      } else {
        // 通信配列にまだ通信が残っている場合
        option = ajaxOptionArray[0];
        // ajaxのオプションを次の通信に切り替え
        opts = $.extend({}, defaults, option);
        // 通信を開始
        $.ajax(opts);
      };
    }
  };

  // 初期指定
  var option = ajaxOptionArray[0];
  var opts = $.extend({}, defaults, option);
  // 一回のみ実行
  $.ajax(opts);
};

まず$.ajax(option)のoptionを順番でpushした配列が第一パラメータで渡されます。 2~23行まではデフォルトのoptionを構築し、一回目の処理は29行から走ります。 そしてデフォルトのoptionではcompleteで実行完了した処理を配列から削除(7行)します。 配列にまだ待ち状態の処理があるならオプションを次の通信に切り替えます(14~20行)。 もし配列にある処理が全部実行完了したら、コールバックを呼びます(9~13行)。

使い方はまずオプションを一つの配列にpushし、その配列を一番目のパラメータで、 コールバックを二番目のコールバックで渡します。

var optionArray = [];
optionArray.push(option1);
optionArray.push(option2);
optionArray.push(option3);
doOrderGuaranteedAjax(optionArray, function(){
	alert('all complete');
});

arrayのpushとshiftを利用し、スタック構造を真似してます。 push() は array の最後に配列要素を加えます。 shift() は array の最初の要素を削除します。

これでファーストイン、ファーストアウトFIFOが実現し、 処理の順番が保ちます。

#diary

仕事でいろいろとお世話になった先輩がいます。

技術でどのような難題があっても絶対解決できる、ものすごい技術者です。

そんな先輩はなぜか英語がぜんぜん読めないですよ。

たまたま一緒にソースコードを見て「require」の単語が何の意味って聞かれて、

「え?」って思ったら先輩が話したのです、英語がまったくできないって。

何か勉強するのも日本語の本やサイトにしか頼れないって。

私はもったいない気持ちでいっぱいでした。


きっと、英語ができたらさらに高まるって思ったわけですから。

でも考え直したら、本当にそうなのかとの疑問が出ました。

英語ができる技術者とできない技術者の差はどこ、どれくらいでしょうか。


流行ってる技術に対しては日本語のリソースも十分あるし、

何か困ったときはこれだけに頼ってもほとんどは解決できるとも思います。


翻訳による多少のロスや誤りはありえるけど、

その分ネイティブの言葉でよりよく意味がわかるでしょう。


もちろん、最新の技術はほとんど英語の資料からあって、

その後有志の人たちが自分の国の言語に翻訳するから時間的のロスはあります。

が、「最新=ベスト」とは限らないでしょう。

その技術が成熟かつ、エンタープライズ開発に応用できるまでは

すごく時間が必要と思います。

個人的にはもちろん新しい技術に興味があり、

それを仕事上の開発にも使いたいのですが、なかなか実現できないです。

お客様から何を使うかの指示、あるいはそういった影響もあるし、

その技術が彼らがわかった時は既に最新じゃなくなりますと

私は思っています。

単純な仕事でのごく普通の開発ミッションを満たすだけならば、

その差は特にないとの結論になりました。


とはいっても基本的な英語は覚えといて損はないでしょう。

少なくともメソッド名を見て大体の役割が想像できるくらいは。。。