Ajax. PeriodicalUpdaterクラス
1207: Ajax.PeriodicalUpdater = Class.create();
1208: Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
1209: initialize: function(container, url, options) {
1210: this.setOptions(options);
1211: this.onComplete = this.options.onComplete;
1212:
1213: this.frequency = (this.options.frequency || 2);
1214: this.decay = (this.options.decay || 1);
1215:
1216: this.updater = {};
1217: this.container = container;
1218: this.url = url;
1219:
1220: this.start();
1221: },
1222:
1207行目からはAjax.
例のごとくClass.
コンストラクタではsetOptions()を使ってthis.
最後に周期的なタイマーを開始するためにthis.
1223: start: function() {
1224: this.options.onComplete = this.updateComplete.bind(this);
1225: this.onTimerEvent();
1226: },
1227:
まず,
その設定が終わると,
1228: stop: function() {
1229: this.updater.options.onComplete = undefined;
1230: clearTimeout(this.timer);
1231: (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
1232: },
1233:
1228行目からはstop()メソッドです。定期的に行われている更新処理を中断します。
もしAjax.
最後に保存しておいたthis.
1234: updateComplete: function(request) {
1235: if (this.options.decay) {
1236: this.decay = (request.responseText == this.lastText ?
1237: this.decay * this.options.decay : 1);
1238:
1239: this.lastText = request.responseText;
1240: }
1241: this.timer = setTimeout(this.onTimerEvent.bind(this),
1242: this.decay * this.frequency * 1000);
1243: },
1244:
1234行目からはupdateComplete()メソッドです。これはstart()経由でonTimerEvent()でnew Ajax.
1235行目からはoptions.
そして1241行目で次のタイマーをセットしています。タイマー終了後に呼び出されるのはonTimerEventで,
1245: onTimerEvent: function() {
1246: this.updater = new Ajax.Updater(this.container, this.url, this.options);
1247: }
1248: });
最後はonTimerEvent()メソッドです。
初回,
1249: function $(element) {
1250: if (arguments.length > 1) {
1251: for (var i = 0, elements = [], length = arguments.length; i < length; i++)
1252: elements.push($(arguments[i]));
1253: return elements;
1254: }
1255: if (typeof element == 'string')
1256: element = document.getElementById(element);
1257: return Element.extend(element);
1258: }
1259:
1249行目からは,
まず,
1255行目では,
最後に,
1260: if (Prototype.BrowserFeatures.XPath) {
1261: document._getElementsByXPath = function(expression, parentElement) {
1262: var results = [];
1263: var query = document.evaluate(expression, $(parentElement) || document,
1264: null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
1265: for (var i = 0, length = query.snapshotLength; i < length; i++)
1266: results.push(query.snapshotItem(i));
1267: return results;
1268: };
1269:
1270: document.getElementsByClassName = function(className, parentElement) {
1271: var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
1272: return document._getElementsByXPath(q, parentElement);
1273: }
1274:
1275: } else document.getElementsByClassName = function(className, parentElement) {
1276: var children = ($(parentElement) || document.body).getElementsByTagName('*');
1277: var elements = [], child, pattern = new RegExp("(^|\\s)" + className + "(\\s|$)");
1278: for (var i = 0, length = children.length; i < length; i++) {
1279: child = children[i];
1280: var elementClassName = child.className;
1281: if (elementClassName.length == 0) continue;
1282: if (elementClassName == className || elementClassName.match(pattern))
1283: elements.push(Element.extend(child));
1284: }
1285: return elements;
1286: };
1287:
1288: /*--------------------------------------------------------------------------*/
1289:
1260行目からはdocument.
ブラウザ側でXPathが使えるかどうかによって実装が変わっています。
1261行目からはXPathが使える場合です。まずは,
evaluate()はXPathResult型を返します。snapshotLengthプロパティと,
1270行目からdocument.
ここで,
式 | 意味 |
---|---|
.//* | コンテキストノード |
[contains( foo, bar )] | ……のうちfooがbarを含んでいるもの |
concat(' ', @class, ' ') | 渡された文字列を連結して返す。@classはその要素のclass 属性 |
' ' + className + ' ' | 変数classNameの前後に空白を加えたもの |
という形になっています。これにより
1275行目からは,
まず,
返り値を入れておくためのelements変数と,
あとはchildren中の全ての要素をfor文でループし,
ここで,
この非XPath版のgetElementsByClassName()は,