JavaScriptでは、連鎖メソッド呼び出しが非常に人気があり、 jQuery を使用する友人はこれについて深く理解している必要があります。このメソッドについては、「JavaScript デザイン パターン」で詳しく説明されています。メソッドのチェーン呼び出しを実装するには、プロトタイプで定義されたメソッドに、これらのメソッドを呼び出すインスタンス オブジェクトへの参照を返させるだけです。この本を参照してください。コード:
(関数() {
関数 _$(els) {
this.elements = [];
for (var i = 0, len = els.length; i < len; ++i) {
var 要素 = els[i];
if (要素の種類 == '文字列') {
要素 = document.getElementById(要素);
}
this.elements.push(要素);
}
};
_$.プロトタイプ = {
それぞれ: function(fn) {
for ( var i = 0, len = this.elements.length; i < len; ++i ) {
fn.call(this, this.elements[i]);
}
これを返します。
}、
setStyle: function(prop, val) {
this.each(関数(エル) {
el.style[prop] = val;
});
これを返します。
}、
表示: function() {
var that = this;
this.each(関数(エル) {
that.setStyle('表示', 'ブロック');
});
これを返します。
}、
addEvent: function(type, fn) {
var add = function(el) {
if (window.addEventListener) {
el.addEventListener(type, fn, false);
}
else if (window.attachEvent) {
el.attachEvent('on'+type, fn);
}
};
this.each(関数(エル) {
追加(エル);
});
これを返します。
}
};
window.$ = function() {
新しい _$(引数) を返します。
};
})();
ご覧のとおり、各メソッドは「return this」で終了し、呼び出し元メソッドのオブジェクトをチェーン内の次のメソッドに渡します。しかし、操作したいデータが非同期リクエストを通じて取得された場合、メソッド呼び出しのチェーンをどのように維持すればよいでしょうか? Dustin Diaz は、メソッド呼び出しを確実に連鎖させる方法を提供しています。彼は、『JavaScript Design Patterns』という本の著者の 1 人でもあります。
彼はまず、次のような Queue オブジェクトを構築しました。
次に、それをツールとして使用して、非同期メソッド キュー チェーンを構築します。このツールを使用すると、サーバーからコンテンツを取得してセレクターに追加する jQuery プラグインを簡単に構築できます。
このようにして、コンテンツを非同期に取得し、一連の呼び出しを継続できます。
$("<div/>")
.fetch('/server/navigation.html')
.addClass('列')
.appendTo('#side');
デモページで効果を確認してください。
キュー内にサーバー側の応答での処理を待機しているアイテムが多数ある場合はどうすればよいでしょうか?著者はそのようなメソッドを構築しました。これは参照する価値があります。
このようにすると、次のように呼び出すことができます。
fetchTweet(url).linkify().filterBadWords().appendTo('#status');
この時点で、非同期メソッド チェーンの実装方法はすでにわかっていますが、「 JavaScript での非同期メソッド キュー チェーン」の下部にあるコメントによって提起されたいくつかの疑問については、検討する価値があります。プラグイン $.fn.fetch は、返されたコンテンツを要素に追加するだけで済みます。キューは必要ですか?さらに、jQuery の $.fn.load は、Queue で使用されるコールバック関数が 1 つだけであれば、次のように記述できます。
(関数($) {
$.fn.fetch = 関数(url) {
var queue = 新しいキュー;
this.each(function() {
var el = これ;
$.ajax({
URL: URL、
タイプ: 'get'、
データ型: 'json'、
成功: function(resp) {
$(el).html(resp['text1']);
}
});
});
これを返します。
};
})(jQuery);
どう思いますか?
関数 fetchTweet(url) {
this.queue = 新しいキュー;
this.ツイート = "";
var self = これ;
ajax(url, function(resp) {
self.tweet = resp;
self.queue.flush(this);
});
}
fetchTweet.prototype = {
linkify: function() {
this.queue.add(function(self) {
self.tweet = self.tweet.replace(/b@(w{1,20}b/g, '$1');
});
これを返します。
}、
フィルター悪い言葉: function() {
this.queue.add(function(self) {
self.tweet = self.tweet.replace(/b(fuck|shit|piss)b/g, "");
});
これを返します。
}、
appendTo: 関数(セレクター) {
this.queue.add(function(self) {
$(self.tweet).appendTo(selector);
});
これを返します。
}
};
(関数($) {
$.fn.fetch = 関数(url) {
var queue = 新しいキュー;
this.each(function() {
var el = これ;
queue.add(関数(それぞれ) {
$(el).html(resp);
});
});
$.ajax({
URL: URL、
データタイプ: 'html'、
成功: function(html) {
キュー.フラッシュ(html);
}
});
これを返します。
};
})(jQuery);
関数キュー() {
// コールバックを保存します
this._methods = [];
// 応答への参照を保持します
this._response = null;
// すべてのキューはフラッシュされずに開始されます
this._flushed = false;
}
キュー.プロトタイプ = {
// コールバックをキューに追加します
追加: function(fn) {
// キューがフラッシュされていた場合は、すぐに戻ります
if (this._flushed) {
fn(this._response);
// それ以外の場合はキューにプッシュします
} それ以外 {
this._methods.push(fn);
}
}、
フラッシュ: 関数(それぞれ) {
// 注: フラッシュは 1 回だけ発生します
if (this._flushed) {
戻る;
}
// flash() 後の後続の呼び出しのために応答を保存します
this._response = 応答;
// フラッシュされたことをマークします
this._flushed = true;
// 彼らをシフトアウトし、彼らを呼び戻す
while (this._methods[0]) {
this._methods.shift()(resp);
}
}
};