Archive for the ‘javascript’ Category

jQueryの$.css(‘width’)や$.css(‘height’)取得はcssを設定していなくても実際の値が返ってくる

jQueryので幅や高さを取得する場合はwidth()メソッドやheight()メソッドが便利だが、
css()メソッドを使用して$.css(‘width’)や$.css(‘height’)でも取得できる。
でも単純にcssで設定されている値を取得したい場合には邪魔になる機能だったりする。
css()メソッドはCSSとして設定していないのに数値pxが返ってくるらしい。(jquery1.7.1で検証)

この場合はget()メソッドを使用して一度DOMを取得してからDOM.style.widthやDOM.style.heightを参照するとよい。

<div id="test">TEST</div>
<script>
console.log($('#test').css('width'));//出力:'1345px' (実際の大きさ)
console.log($('#test').get(0).style.width);//出力:'' (空)
</script>

Flasherの衰退と今後の人材と教育について

以前勤めていた会社ではFlasher(Flashコンテンツを作成する人)として働いていました。
当時はFlashがリッチコンテンツを作るうえでとても手軽なことがあり、
ブラウザ上だけでなく、SONYのVAIOに標準搭載されるアプリケーションのUI部分の作成など、
Flashを作成する技術が世の中で重要なスキルだったとおもいます。

「Flashが今後なくなることはないけれども、モバイル機器用のは開発しない」というアドビの発表。

さて、それに代わるのがHTML5だというのですが、これは話を少々単純にしすぎです。
「一部ではそう」ですが、ほんの一部です。もっというとHTML5で新しくできることって厳密に言うとそんなにないのではないかと思います。

ビデオが見れる。絵が描ける。などの実現はFlashではなくてもQuickTimeやJavaアプレットなどでできました。HTML5の厳密な見方はこのような「プラグインに任せていた部分をブラウザがやりますということになった」ということだと思います。
実際HTML5として紹介されている多くの部分をAjaxが担っています。
Ajaxが登場したときも同じでした。Ajaxは通信する方法の名前でしかなく、開発はほぼjavascriptです。

カートにドラッグできるショッピングサイトなんかをFlashで作るようなことは
ずいぶん前からなくなっていて、Ajaxで作ります。
その時点でFlashの役割のかなりの部分はAjaxに取って代わっていました。

CSS3もそうですね。

このように、Flashは急に役割を取られたのではなく、徐々にそうなっていったのです。

それなのに突然な印象を与えたのは、Apple社のモバイル製品がフラッシュを非対応にしたときです。
正直「えぇ?」と思いました。それは二つの理由からです。
ひとつはまだまだFlashで作られたサイトやサービスがたくさんある状況でお客さんがどのように反応するだろうという不安。
二つ目はFlashが(Flasherという職が)なくなってしまうのではないかという危惧。

一つ目の理由については、本当に驚きました。一流の先導者の凄み、出てました。
二つ目の理由についてはそれほど意外なことではなかったです。

さて、HTML5の時代にこれから入ります。
今後Flasherは普通にやっていたら食べれないと思います。

進路のパターンとしては、
1:他の技術も習得してポリバレントな技術者になる。
2:さらに進化していくだろうFlashの最先端をひたすら追い続け、職人として生きる。

どちらかというと私は1のパターンです。デザインやアニメーションが強い人は2のパターンになるのかな。

媒体で言うと、1のほうが圧倒的に舞台が多い。

そういうわけで就職も1の人材のほうが就職しやすいでしょうね。
2は会社を選びます。故に狭き門。職人の淘汰がされるでしょうね。

HTMLコーダーと呼ばれている職業の人がHTML5という名前だけを理由に、それをやらされているとも聞きます。
FlashでActionScript書いてた人のほうが簡単に習得できる技術だと思うので、
HTML5の表面の部分(マークアップとCSS)と動作部分(Javascript)で職種名を分けて、
Javascript側をやる人として再就職とかお勧めです。Javascripterとか、Ajaxianとか。

現在の教育の現場でもいまだにHTMLとかFlashとか分けて教えられていますが、
それらの境目を作るのは早くやめてほしいと思います。
まずウェブサービスが動いている全体を感じられる指導をしてほしい。

1:ネットワークを組む。(プラモデル方式に)
2:サーバーを立ち上げる。(ざっと)
3:データベースを作成(いわれたとおりに)
4:サーバー側の簡単なプログラム(一応内容を把握)
5:クライアント側の簡単なプログラム(アレンジしてみる)
6:それらを動かす。

これを一度体験しておくことで、その後どんな専門を持ったとしても、
技術革新が早いこの業界においても自分を変えながら生きていける絶滅しない人材になれると思います。

DeAGOSTINIさんあたりで出ないかな。ニッチすぎるか。。

javascript php ajaxでphpからjavascriptへのリスポンス(jquery使用)

1:javascriptからPHPは$.ajaxを使用

$.ajax(ajaxOption);

2:PHPからjavascriptはjson形式で返す

$json = json_encode($result);
echo $json;

3:受け取り側javascriptでjsonにパース

json = null;
try{json = $.parseJSON(msg);}catch(e){}
if(json){
//処理
}

Smarty:html_optionsで出力される改行を出力しないようにする。

いったん定義してからエスケープする。

{capture assign="opt"}{html_options ...}{/capture}
{$opt|escape:javascript}

Javascript: あるオブジェクトのメソッドをほかのオブジェクトに呼んでもらうとthisはwindowになる

A = function(){
this.myName = "A";
}
A.prototype = {
trace:function(){
alert(this.myName);
}
}
B = function(){
this.myName = "B";
}
B.prototype = {
callme:function(callme){
callme();
}
}
$a = new A();
$b = new B();
$b.callme($a.trace);

AとBにはそれぞれmyNameを設定

BのインスタンスにAのインスタンスのメソッドtraceを渡し、Bのインスタンスに呼んでもらう。

結果はAでもBでもなく、undefined.

traceメソッド内のthisはwindowになる。traceが匿名関数になる。

なんどもなんどもつまずくところ。

JQuery Balloonプラグイン: balloonの消し方

ツールチップを表示するこちらのJQueryプラグイン「jquery.balloon.js」について動的に消したいのになかなか消せなかったのでメモ。

経緯:

削除ボタンがあって、そのボタンにマウスをあわせると「削除する」とツールチップを表示するために上記のプラグインを用いていたのですが、クリック時にボタン自体を消したら、ツールチップだけ画面に残ってしまった。

解決:

Balloonにはballoonを設定したオブジェクトに対し、data(“balloon”)で取得できる模様。

deleteBtn.click(function(){
$(this).data("balloon").remove();
});
deleteBtn.balloon();

 

追記2011/11/11

 

上記の方法では不十分。消した後、ブラウザの画面サイズを変更するjavascriptエラーがでる。
理由はツールチップを表示したときに$.balloon.instancesに配列を追加していて、window.resizeイベントでそれらの配列の要素にアクセスしているため。

本当は拡張したかったのだが、面倒だったので直接プラグインに変更を加えた。

1:$.balloonにメソッドを二つ追加。

2:配列に常に突っ込むのをやめて、重複していないかのチェックをするように変更。

 

追記2 2011/11/11

と思ったが、adjustBalloonで位置が設定できない現象が。理由はこのメソッドが呼ばれたときに要素が表示されていないこと。表示する瞬間に位置情報を計算したほうがよいのではないかと思い、再び改造。

showメソッドの中で計算した。それによって$.balloon.instances関連のものが必要なくなった。

誰の助けになるかわかりませんが一応ソースを張っておきます。

 

EC-CUBE2.11(session_set_save_handler)+Ajaxでセッションがうまくいかない件。

2日悩んでまだうまくいっていないことですが、とりあえずこれまでわかったことをメモします。
※この情報は間違っている可能性が高いです。

EC-CUBEでは2.11ではセッション情報をデータベースに保存している。
通常、商品をカートに入れる際にはカートのページにリダイレクトされ、セッション情報にカートの内容が保存される。

カートの追加をAjaxで実装したところ、連続して複数の商品をカートに追加すると、タイミングによってカートに追加されない商品があるという現象が起きた。EC-CUBE2.11ではSC_Helper_Sessionクラスにてsession_set_save_handlerが呼ばれ、セッションに対して起こるイベント用のようなものが定義されて、オリジナルの処理(データベースへセッション情報を書く処理)がかかれている。

こうすることによって単純に$_SESSIONにプロパティをセットするだけでデータベースにセッション情報を残すことができる。

原因を探っていくと、どうやら$_SESSIONを操作した際に、その都度登録した処理(データベースへ書き込む処理)が呼ばれるわけではないことで、たとえばその処理の中で一度$_SESSIONを読み込み、それに対して何かを付けたし、そして再度$_SESSIONに書き込むというような処理を入れることが原因のようだ。

EC-CUBEではカートにある商品をID(連番の)で処理しているようなのだが、次の商品がカートに追加されるたびに一番最後のID(数字)に1を足して処理している。そのためカートに追加する際に一度カートの内容を読み込み、追加し、書き込むという処理をする。

Ajaxを使うことで「読み込み」「読み込み」「書き込み」という処理がありえるので、商品が0のときは「次はID:1」「次もID:1」「IDが二つかぶるので2つめのみ追加」となる。

通常は「読み込み」から「書き込み」まで同じ行に対する処理をロックできるので問題は起こらないのだが、読み込みは読み込み、書き込みは書き込みとデータベースへのアクセスが別々になっていることでこのようなことになってしまっている模様。

その辺のトランザクションを何とかするか。セッションを連番で処理するのを何とかするか。

どうすれば最善か。まだ考察中です。

追記(2011/11/10)

Ajaxを使うことで「読み込み」「読み込み」「書き込み」という処理がありえるので、商品が0のときは「次はID:1」「次もID:1」「IDが二つかぶるので2つめのみ追加」となる。

さらに調査した結果、こういうことではないようだ。

IDがかぶるから上書きされるのではなく、セッションが書き込まれるときには
「すべてを読み込み」→「変更(追加)」→「すべてを書き込み」となるので、
たとえばAが入っているセッションにB,Cを書き込みたい場合
「A」を読み込んでそれに「B」を足して「A,B」となり、それを書き込む前に「A」を読み込み「C」を足して「A,C」となり、最終的に「A,C」となってしまうということらしい。

これはsession_set_save_handlerでデータベースを使う際にまれにある現象らしい。

http://xoops.ec-cube.net/modules/newbb/viewtopic.php?viewmode=thread&topic_id=8247&forum=2&post_id=39923#forumpost39923

http://svn.ec-cube.net/open_trac/ticket/571

追記2(2011/11/11)

結局、非同期通信を行う場合、session_set_save_handlerを使うと読み込みと書き込みが入れ子になり、上記のような現象になることは避けられなかった。

また、Ajax側で通信を順番に行うようにすることでこれを回避することができた。
具体的には商品をaddしたときにqueueに追加し、順番に処理していく。

また処理が終わったらカートをリフレッシュしていたのだが、コレもまずかった。

カートのリフレッシュ時には当然最新のカートの情報を取得するのだが、それもこの現象の原因になった。
つまり読み込むだけであっても通信が入れ子になることでセッションの同期が取れず、セッション関連がある通信は常に順番に確実に行う必要がある。

session_set_save_handlerを使用しないような実装も考えたが、EC-CUBEの保守がややこしいことになりそうなのでやめた。

通信をすべて順番に行うことで、問題を解決することにした。

  1. 商品を追加ボタンを押す
  2. queueに追加
  3. queueがひとつだけならqueueを開始
  4. ajaxでpost
  5. javascriptでカートに追加中の表示(追加ボタンをロード中にし、カートに商品を半透明で追加表示)
  6. 応答があったら本当にカートに入っているかを一度チェックする
  7. 成功ならカートに追加済みの表示:失敗ならすべてを元に戻す。
  8. queueがまだあるなら次のqueueを開始し、4へ戻る。

追記3(2011/11/11)

resize_image.phpを動かすと、セッションが上書きされるようだ。なんで、画像をリサイズするためにセッションを操作しているのか不明。。
なんだか動作ももたつくので使用するのをやめた。

Javascript 自身がフレーム内かどうかを判定する

フレーム内でないとwindowもwindow.parentも同じくwindowを参照しているようなので、

function isFrame($window){
return $window != $window.parent;
}

とした。

Colorbox iframe内からのリンクで親のフレームにColorboxを表示する

$("a.test").click(function(){
var href = $(this).attr("href");
parent.$.fn.colorbox({
width: "560px",
height: "700px",
href:href,
iframe: true ,
scrolling: "auto"
});
});

joomlaでpreタグ内の改行がbrタグに自動的にに変換されてしまう件について

joomlaでeditorにJCEを使用し、記事にコードをのせるためにsyntax highlighterを使ったときに、せっかくコードをきれいに保存してくれるのにタイトルのような余計な機能のせいで、見苦しくなってしまう。こういった「余計な機能」はセキュリティーやユーザビリティの観点から「妥当な機能」なのだろうが、やっぱり柔軟性にかける。このような記事に対するユーザーへの制限はjoomlaに限らないが、javascriptがかけなかったり、tableがかけなかったりするのはつらい。。

今回はjoomlaのpreタグ内の改行がbrタグに変換されてしまうのを回避すべく、まさぐってみた。
ただし。コードを把握しているわけでなく、適当にいじったら出来たというメモ程度のものなので、まねしないほうがいいかもしれません。

/plugins/editors/jce/tiny_mce/tini_mce.jsを編集
1:「j=j.replace(/\r?\n|\r/g,” “);」の一文を削除(これをやるとpreタグに限らず全部のタグに改行が可能になる。)
2:「{pattern:/(<pre[^>]*>)(.*?)(<\/pre>)/g,encode:1},」の一文を削除(これをやるとpreタグ内の改行がbrタグに変換されなくなる。)

上記の方法では結局保存したときに元に戻ってしまう模様。コードと数時間格闘したが、結局わからずじまい。。。

途方にくれていたとき、ハッと発想の転換が。

「そうだ。Syntax Highlighter側でbrタグを改行であると認識させちゃえばいいんじゃね?」

というわけで、またまた力技だが
plugins/content/syntaxhighlighter/core/shCore.js を編集するのですが、
plugins/content/syntaxhighlighter/src/shCore.jsが元のファイルのようなので
予め、plugins/content/syntaxhighlighter/core/shCore.jsをそのファイルで上書きます。
そして、plugins/content/syntaxhighlighter/core/shCore.js を編集。

1081行目あたりにある for(var i = 0; i < elements.length; i++) というループの中で、
elements[i]がtargetという変数に代入される前に下記の2行を加えてelements[i]の内容を書き換えます。

elements[i].innerHTML = elements[i].innerHTML.replace(/\<br*\>/g,”\n”);
elements[i].innerHTML = elements[i].innerHTML.replace(/\<*code*\>/g,”");

2行目はjoomlaで編集してるとpreタグの中に入ってくるcodeタグもついでに消しています。

これでとりあえず解決(?)です。