[ カテゴリー » 開発日誌 ]

Ajaxによる自動投稿スクリプト

category-icon

 フォーラムで,一旦投稿した後に,引き続き編集作業を継続できないかという問い合わせがありました。ppBlogでは,公開される通常の投稿であれ非公開のドラフト投稿であれ,ポストした後は一旦トップページを表示するような流れになっている訳ですが,確かに,そんなのもありだなぁと思った次第。編集画面から投稿後のトップページへの切り替えはJavaScriptを使っていて,とりあえずは,この行き先を変更すれば,投稿後に編集画面に戻ることが出来ます。これはnaoKさんLink が解決法をフォーラムの方に書いてくれてます。 →http://forum.p2b.jp/index.php?mode=box&UID=2870&display=allLink

 で,ppBlogはAJAXWの技術をコメント表示などに用いており,またログイン認証ではAJAXでポストということもしています。なので,記事の投稿もAJAX経由でいけば,編集画面から離れることなく,バックグラウンドでのドラフト投稿が出来そうだと思い,スクリプトを書いてみました。

 まずは,AJAX経由でポストするので,そのための準備をします。POST送信で送るパラメータは Array.push() メソッドを用いて,どんどん追加していって,最後に Array.join('&') で連結すればOKです。これをppBlogに組み込まれているAjax.post()メソッドを使ってPOST送信すれば良いです。これは以下のような感じになります(細かな条件振りなどは省略して書いています)。

function AjaxAutoPost(){
 var posts = [];

 posts.push('mode=update');
 posts.push('UID='+o('UID').value);
 posts.push('draft=1');
 posts.push('type=autopost');
 posts.push('category='+o('category').value);
 posts.push('title='+encodeURIComponent(o('_title').value));
 posts.push('author='+encodeURIComponent(o('author').value));
 posts.push('com='+encodeURIComponent(o('Page1').value));
 
 posts = posts.join('&'); // posts配列を&で連結

 Ajax.post("admin.php", posts, function(data){ // AJAXでPOST送信
  [data processing]
 });
}

 これをバックグラウンドで,自動的に一定時間ごとに行いたいので,setTimeoutを用いて,この関数を繰り返し呼び出せばOKです。

 次にサーバーサイドですが,こちらはPHPでの処理となります。日本語をJavaScriptでエンコードすると,もとの文字コードが何であれ,必ずUTF-8化して送出してくれます。なので,ppBlogで扱う文字コードがUTF-8以外の場合は(例えばデフォルトでのEUC-JP),その文字コードに変換してからログに記録するようにします。

autopost-shot1
新規作成画面での初期状態。

autopost-shot2
オートポスト起動中はアイコンが変わっています。

 このオートポスト機能を追加したppBlogでの記事作成画面のスクリーンショットを載せておきます。図にあるように,自動ポスト開始ボタンがあって,それをクリックすることによって,一定時間毎でのオートポストが開始されます。始動中は,ボタンが「一時停止」のボタンに変化していて,もう一度ボタンを押すと,オートポストを中断します。ボタンの隣のテキストボックスには,最後に自動ポストした時刻が表示されます。ボタンで自動投稿オンオフの切り替えが可能です。

 この機能を取り入れることの利点は,バックアップも兼ねる点でしょうか。記事をシコシコ書いて,いざ送信!って送信するとサーバーのレスポンスが悪かったりして,折角したためた記事がパーになってしまった経験が,自分は少なくとも3回あります。この自動ポストを使って,初めのうちからドラフト投稿しておけば,こういう痛い状況は極力減ると思います。

 当初は,記事をブラウザのクッキーに保存するオートセーブ機能みたいなやつも念頭にあったんですが,クッキーにはせいぜい4キロバイトぐらいが限度で(参照:クッキーの最大サイズ制限についてLink ),この容量ではとても長文には耐えられませんし,そもそもクッキーの用途とはずれている気もしますし,ここはppBlogで比較的簡単に実装できるAjaxを使うアプローチを取ってみました。

 まだ細かいところまでチェックしたわけではないんですが,試しに使ってみたいという方はどうぞ。簡単な説明文も一緒にZIPしておきます。ちなみに,editor.jsのお尻の方に今回のスクリプトを追記していますが,そこにでてくる60000という数字が,自動投稿の間隔を表しています。この場合は,60000ミリ秒すなはち1分おきにオートポストするということです。ここの数字を変えることでお好きな間隔に設定できます

 


— posted by martin at 09:35 pm   commentComment [15]  pingTrackBack [0]

タグ機能を使ったテクノラティへの検索リンク

category-icon

 ppBlogの最新版には、タグ機能が付いています。「タグ」と「カテゴリー」は使い方が同じように感じるかもしれませんが、やっぱり違いますね。タグは「キーワード」とほぼ同等と個人的には思っています。ある記事があって、その内容と繋がりを持ったキーワードというものがある。そして、そのキーワードは記事を分類するカテゴリーとは別の要素です。だぶっても良いと思いますが。

 てなわけで、ppBlogにシンプルなタグ機能を付けてみました。このタグ機能は、ppBlogの中で完結するものですが、折角なので、Technorati JAPANLink にリンクするタグも出力できるようにしてます。テクノラティジャパンのタグ検索機能は、2005年12月29日にベータ版のサービスが提供されていて、未だにベータ版ですが、まぁこれはグーグルのGmailがそうであるようにずっとβ版ということかもしれません。ちょっとサイトが重いんじゃないかと感じますが、これからの改善に期待してます。

 テクノラティでは、記事の更新PINGも受け付けており、ppBlogの管理画面で、テクノラティの更新PINGを登録すれば、より効果的にタグを活用できるのではないでしょうか。

 ppBlog自体のタグ機能について、簡単に述べておくと、タグは、記事の新規作成時や編集時に自由に追加や削除が可能になっています。そして、大体、どのブログでもそうであるように、エントリー数の多いタグほど文字サイズが大きいです。カテゴリー毎のソートが出来るように、タグによるソートも可能です。

 とりあえず、これぐらいの機能でよいかなぁと。

 


— posted by martin at 09:27 pm   commentComment [41]  pingTrackBack [0]

モブログのテスト

category-icon

[PCから追記@2006/6/6 23:5:33]

 なんとか自動モブログ・複数ファイル添付もOKのようで。ちなみに、ケータイの機種はSO902iG。ネット情報では写真の質はお世辞にも良いとは言えない感じであったが、これぐらいの大きさであればまずまずではなかろうか。日曜の朝、チェックアウトを済ませてテニスに向かう前に、記念に一枚。大谷山荘は、すごく山奥にあるという感じの、非常に奇麗な巨大ホテルでした。山荘っていうから何となく浅間山荘みたいなイメージがあったのだけれど、全然違った。「山荘」というネーミングはどうなのかなぁ。(666って獣の数字Gじゃないか、くわばらくわばら)
320(W)×240(H) 20.24

95(W)×72(H) 2.57

大谷山荘とケータイに始めからあるアニメーション添付(自動エントリー)

— posted by martin at 02:56 pm   commentComment [0]  pingTrackBack [0]

Firefoxでテキストエリア内のマウスカーソルが最初に戻ってしまう件

category-icon

 こんばんは。何だか、地球特捜隊ダイバスターGみたいなタイトルになってしまいました。近頃は、もっぱらFirefoxで記事を書いていますが、この際に、ひとつ「何じゃ」と思っていたことがあります。記事作成画面で記事をしこしこ書いていて、時々、文字を強調したり文の整形のために、ppBlogツールバーから選んでタグを反映させますが、その際にFirefoxだと、テキストエリアにフォーカスを合わせると、マウスカーソルがテキストエリアの先頭に移動しちゃうんですよね。なので、その都度、また修正を加えた場所までスクロールさせないといけません。文章が長くなってくると、スクロール量も増えて大変。で、ブロッグは書いてなんぼ、こういう所でストレスを感じさせるようではイケナイ。というわけで、webを検索したらちゃんと便利な属性がありました。ちなみにIEエンジンならマウスカーソルは、修正を加えた箇所にとどまってくれるので問題ないです。

 テキストエリア内で垂直方向にスクロールした距離は、次のプロパティーで読み書き可能です。

object.scrollTop

なので、予め、この値を取得しておき、内容に修正を加えた後で、再度この値に設定すれば良いです。具体的には、ppBlogのlib.jsで言えば、

var s = ed.selectionStart;
var scrollTop = ed.scrollTop;
ed.value = ed.value.slice(0,s)+ed.value.slice(s).replace(caretSelection, string);
ed.setSelectionRange(eval(s+string.length), eval(s+string.length));
ed.scrollTop = scrollTop;
ed.focus();

とすれば良い。ホットピンクの部分が変更した箇所です。これで、Firefoxでもストレスなく記事が書けます。

 余談ですが、Firefoxの最新版は、1.5.0.4で6月2日にバージョンアップしています。最近のFirefoxは、アップデートもほぼ全自動ですし、良い感じですね。最近、見つけたTipsは、「スムーズスクロールを使用する」です。自分がIEエンジンから、なかなかFirefoxに乗り換えることが出来なかった最大要因が、何か皮を一枚被ったような「もっさり」感でした。どことなくスムーズでない。で、よくよく注意してみると、どうもスクロール時のぎこちなさが原因じゃないかと思いました。そういえば、設定項目にスクロールの項目があったような、と、「ツール」→「オプション」→「詳細」→「一般」の「ブラウズ」という項目にありました。デフォルトではオフになってるんですね(自分が以前に弄ったのかも知れないけど)。で、これをオンにすると、マウスホイールでのスクローリングのスムーズなこと!おぉー、これこれ、って感じでした:) 皆さんも一度、試されては■


— posted by martin at 04:21 am   commentComment [1]  pingTrackBack [0]

Firefoxでの擬似window.event

category-icon

Follow-Up 2006-7-6

 Firefoxでもwindow.eventを有効にするやり方のエントリーはこちらLink  

 Gecko系のブラウザでは、これはNetscape4.x時代からずっとそうなんだけど、イベントは、イベントハンドラーにargumentとして渡されるので、この手の記述には必ず引数(ひきすう)を書く必要がある。一方、IEでは(Operaもか?)、イベントモデルには、最後に生じたイベントをキャプチャーするwindow.eventという属性があり、これはどこからでも自由にアクセスすることが出来る。以上のことをまとめると、イベントに関してクロスブラウザーな記述をしようと思えば、例えば以下のような感じになる。

function getEventType(e){
 var e = e || window.event;
 alert("Event Type is:" + e.type);
}

 で、ここで引数に使用している"e" であるが、これはGecko系のためだけに必須である。window.event であれば、この引数は不要だ。で、自分は常々、この"e"を追放できないかなと思っていた。何しろ、イベントを絡ませるような関数に必ずついて回るからだ。スクリプトの記述はシンプルなのが良いのに、この"e" のために余計に引数が増えてしまう。

 ppBlogでは数箇所に、この"e" が出てくるので、こいつを追放してやろうと決心した。そして色々弄った結果、これならOKかなというのを見つけたのでメモしておく。もちろん、ppBlogにも反映される。

 まず、最初にやったことは、ppBlogのjs/lib.jsに記述してある、ページ内でのマウスイベントX座標をゲットする以下の関数において、Firefoxでイベントがどんな風に呼び出されるのかだ。

function getEventPageX(e){
 var e = e ||window.event;
 if(e.pageX){
  return e.pageX;
 } else if(e.clientX){
  if(d.documentElement && typeof d.documentElement.scrollLeft != "undefined"){
   return d.documentElement.scrollLeft + e.clientX;
  } else if(d.body && typeof d.body.scrollLeft != "undefined"){
   return d.body.scrollLeft + e.clientX;
  }
 }
 return 0;
}

 実行している関数自身は、arguments.calleeで参照出来る。そして、この関数が何によって呼び出されているかは、callerプロパティーを参照すればいい。これらを使って、上の関数に、

 alert(arguments.callee.caller);

を付け足してみると、Firefoxでは、

function onclick(event){
  getEventPageX(event);
}

というのが返ってくる。→デモ1。Link ほほう。ちなみにIEでは

function anonymous()
{
  getEventPageX(event);
}

という匿名関数が返ってくる。Firefoxでは、引数のeventonclick関数によってキャプチャーされていることが分かる。じゃ、このonclick関数のeventって何だろう。これは次のようにして調べることが出来る。

 alert(arguments.callee.caller.arguments[0]);

すると次の答えが返ってくる。→デモ2Link

[object MouseEvent]

ほうほう。イベントは、マウスイベントオブジェクトとしてonclick関数に組み込まれているらしい。ならば、これを呼び出して、"e" に渡してやれば、"e" の束縛から逃れられるのではと推察する。なので次のようにして、"e" なしのやつを走らせてみる。→デモ3Link

function getEventPageX(){
 var e = arguments.callee.caller.arguments[0] || window.event;
 if(e.pageX){
  return e.pageX;
 } else if(e.clientX){
  if(d.documentElement && typeof d.documentElement.scrollLeft != "undefined"){
   return d.documentElement.scrollLeft + e.clientX;
  } else if(d.body && typeof d.body.scrollLeft != "undefined"){
   return d.body.scrollLeft + e.clientX;
  }
 }
 return 0;
}

 おおぉー、上手く行った:) 3つ目のデモでは、もはや引数のeは必要なく、getEventPageX()だけで座標を取得していることに着目。

 こりゃいいやと、js/lib.jsjs/editor.jsに出てくる引数"e"をとりあえず、全部なしにしてブロッグを見てみると、意図したように動かない。何でかなと、デバッグダイアログを見てみると、これまでのデモでは、マウスクリックによって直接getEventPageX()を呼び出していたのに対して、実際のスクリプトでは、getEventPageX()などは、別の関数の中で呼び出されている。なので、

arguments.callee.caller.arguments[0]

だと、getEventPageX()を含んだ関数の第一引数を返してしまうのである。初歩的ミス。。それならば、

arguments.callee.caller

を次々に呼び出していけば、そのうち、マウスイベントオブジェクトに到達するはずである。イメージ的には、sourceに向かって遡っていくイベントバブリングですね。これは次のような記述でいい。

var caller = arguments.callee.caller;
while(caller){
 var ob = caller.arguments[0];
 if(ob == '[object MouseEvent]') return ob;
 caller = caller.caller; // 次の呼び出し元にセット
}

ただ、ob == "[object MouseEvent]" というのは何となく「カッコ悪い」。この部分はコンストラクタを用いて次のようにも書ける。

ob.constructor == MouseEvent

 以上をまとめて、IEでも使えるようなクロスな記述にすると以下のような感じ。

function windowEvent(){
 if(window.event) return window.event;
 var caller = arguments.callee.caller;
 while(caller){
  var ob = caller.arguments[0];
  if(ob && ob.constructor == MouseEvent) return ob;
  caller = caller.caller;
 }
 return null;
}

 windowEvent()がそのままIEのwindow.eventに相当する。これを用いればイベント関連の記述に必須であったeからめでたく解放される訳である。最初に出てきたgetEventPageX()関数は、最終的には次のように記述できる。

function getEventPageX(){
 var e = windowEvent();
 if(e.pageX){
  return e.pageX;
 } else if(e.clientX){
  if(d.documentElement && typeof d.documentElement.scrollLeft != "undefined"){
   return d.documentElement.scrollLeft + e.clientX;
  } else if(d.body && typeof d.body.scrollLeft != "undefined"){
   return d.body.scrollLeft + e.clientX;
  }
 }
 return 0;
}

 もはやイベントのキャプチャーのためだけに引数は必要ない。最終的なデモをあげておきます。 →http://p2b.jp/demos/windowEvent.htmlLink  なお、イベント座標取得関数とは別に、イベントが起こった要素の座標を返す、getElementPosition()という関数も新たに定義しています。これは、JavaScriptマスターであるppk氏Link のサイトにある"Find PositionLink " という記事に紹介されている関数をmodifyしたやつです。こんなやつ。

function getElementPosition(){
 var _x = _y = 0;
 var ob = windowEvent().target || windowEvent().srcElement;
 if(ob.offsetParent){
  while (ob.offsetParent){
   _x += ob.offsetLeft; _y += ob.offsetTop;
   ob = ob.offsetParent;
  }
 }
 return [_x, _y];
}

 とりあえず


— posted by martin at 06:10 pm   commentComment [1]  pingTrackBack [0]

T: Y: ALL: Online:
Created in 0.0062 sec.
prev
2024.4
next
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30