■
http://www.hawk.34sp.com/stdpls/xml/xmlhttprequest.html
XMLHttpRequestって同期の呼び出しができるんだ(どしろうと)
前書いたの*1を同期させてみるか。
mixiはajax周りにPrototype.js*2を使っている、俺もそのまま使っているのだけれど、これはパラメーターに
asynchronous: false
と渡してあげれば同期で動く様になってラクチンポン。
筈なんだけどなあ…(;´Д`)
このパラメータをセットすると動かないんだよな、もしかしてFirefoxだと動かない?
JSコンソールにエラーも出ないのでコードを見ると
request: function(url) { (略 } catch (e) { } },
アレッ?!(;´Д`)にぎりつぶされてRUUUUU!!!!
Prototype.jsは自前で色々処理しているらしいので、多分Prototype.jsのバグだ(いいかげん)
でも、Prototype.jsの使い方はなんとなくわかったので、onLoadingで適当にステート管理させた。
非力なノートでもブラウザが固まらなくなった、しかし何回も何回もリクエストを投げるので表示までは遅い。
残りロード数を表示する様にしたので、固まっているかどうか位は見分けられるけど*3
// ==UserScript== // @name new friend diary mod // @namespace http://d.hatena.ne.jp/zim/ // @description new friend diary mod // @include http://mixi.jp/new_friend_diary.pl // ==/UserScript== // // mixi の新着マイミク日記を前のものに近い具合に再現します、時刻がとれません、HTMLが汚すぎます // 野地 尚弘 http://d.hatena.ne.jp/zim/ (function() { function reload_List(){ //DIV箱にidListとHtmlListを元に描画 idList.sort().reverse(); html = ""; for(i=0; idList.length>i; i++) html = html + listHtml[idList[i]]; document.getElementById("out").innerHTML = html; } function toDiaryList(request, user_name) { //ajaxレスポンスを整形&配列に投入、配列更新 > if(他の非同期Requestが無い)HTML再描画 var data = request.responseText; _dataList = data.match(/<div.*?<\/div>/g); dbg("_dataList.length="+_dataList.length); for(i=1; _dataList.length>i; i++){ //※i=1 1行目はゴミ _id = _dataList[i].replace(/<div.*?id=/, '').replace(/&owner_id=[0-9]+">.*?<\/a><\/div>/,'') ; listHtml[_id] = _dataList[i].replace(/<div.*?>/,'').replace(/<\/div>/,'').replace(/<img.*?>/,'') + user_name + "<br>"; idList[idList.length] = _id; } if(requestCounter == 0) reload_List(); } function requestNewDiary(user_id,user_name) { // ajaxインスタンス生成(this) > 配列更新 toDiaryList() > HTML再描画 reload_List() var url = '/ajax_new_diary.pl'; var myAjax = new Ajax.Request( url, { method: 'get' , asynchronous: true ,//falseの挙動が謎過ぎる parameters: 'friend_id=' + user_id , onLoading: function (request) { requestCounter++; document.getElementById("out").innerHTML = "now loading... 残りロード数:"+requestCounter;}, onComplete: function (request) { requestCounter--; document.getElementById("out").innerHTML = "now loading... 残りロード数:"+requestCounter; toDiaryList(request,user_name);} } ); } uidList = document.body.innerHTML.match(/owner_id=[0-9]+/g); for(i=0;uidList.length > i;i++) uidList[i] = uidList[i].replace(/owner_id=/,''); nameList = escape( document.body.innerHTML ).match(/view_diary\.pl.*?%0A/g); for(i=0;nameList.length > i;i++) nameList[i] = unescape( nameList[i].replace(/.*%3C\/a%3E%20/,'') ); document.body.innerHTML = document.body.innerHTML.replace(/<!-- end: page link -->[\s\S]*<!-- start: page link -->/g, '<div id="out" align="left"></div>'); var requestCounter = 0; var idList = new Array(); var listHtml = new Object(); for(i=0;uidList.length > i;i++) requestNewDiary(uidList[i],nameList[i]); // リクエスト実行 })();
多分動く。
でも調べている最中で onLoading の前に onComplete が呼ばれる事があるとか*4で、非常にうさんくさすぎる。
追記:上のGreaseMonkeyスクリプトはマイミクが少ない人は残りロードが0で止まってしまうらしい、これがonLoadingとonCompleteのバグだと思う。
それでも自前で書くよりも数段楽だよなー、こういう制限を仕様だと割り切っちゃえば。
*1:http://d.hatena.ne.jp/zim/20051028#p2
*2:http://prototype.conio.net/
*3:同時に何十個ものリクエストがスロットされるわけで、そりゃ重いわ
*4:http://labs.cybozu.co.jp/blog/kazuho/archives/2005/09/prototypejs.php