jQuery使ってたらネイティブDOMが浦島太郎になってた話

先日仕事でEC-CUBEの2系のカスタマイズしてたんです。

内容的にはformにinput type=hiddenな項目追加するというもの。

既存のソースにあんまり手を入れたくないし、
複数サイトに横展開していかなきゃいけないのでモジュール(アドオン)化したくって
JSから要素追加しちゃえ!ってこんな感じの操作をさせたんですね。

$("#form").append('<input type="hidden" name="hogehoge" value="">');

ところがこれがなぜか動かない!!

首をひねりながら色々調べる事30分
$がprototypeになってたっていうね(笑

一般的な対処は

jQuery("#form").append('<input type="hidden" name="hogehoge" value="">');

ってすればいいんでしょうけど。。。

jQueryに依存してったのってこの部分だけなので、この際全部ネイティブで書いちゃおうかと思ったんですね。

私の知ってるネイティブなDOM(level3)ってappend([DomNode])しかなくて。。。
これがとってもメンドクサイ( ˘•ω•˘ )

querySelector()が知らぬ間に出来てたのを思い出して、もしかしてなんか出来てるかも?
で、ちょいと調べたら素敵なメソッド出来てるじゃん!!

var form = document.querySelecter("#form");
form.insertAdjacentHTML('beforeend','<input type="hidden" name="hogehoge" value="">');

なんでもコア技術が好きな私としてはめちゃくちゃ感動してたんです!!

で、今日になってquerySelector()とかも追加されてるしもしかしてDOM Level4出てる?
なんて思って調べてみた。

DOM4 REC-dom-20151119
あるじゃーん!
DOM Level4じゃなくてDOM 4 !?
Levelとこ行ったの!!!Σ( ̄□ ̄;

って突っ込みつつ長らく浦島太郎だったことを思い知ったのでした。。。

jQuery::mouseleave マウスアウト(mouseout)を上手にとる

mouseoutの代わりにmouseleaveを使うと楽できます。

DOMLevel3で追加になったイベントのようで、マウスオーバー/マウスアウトは内包した要素(li)のイベントもバブリングで親要素(ul)に伝搬されていて処理が煩雑になっていたものをスマートに採取できるようになります。

<ul>
 <li><a href="">aaaa</a></li>
 <li><a href="">bbb</a></li>
</ul>

こんな構造のメニューをアコーディオンするときに、ulタグのマウスオーバー/マウスアウトで制御しようとするとバブリング制御に苦労するので、マウスエンター/マウスリーヴを使うと幸せになれます。

Photoshop+Javascriptでデバッグ

PhotoshopにもJavascriptのデバッガがあるんだそうです!
それがコレ!

ExtendScript Toolkit という名前みたい。

まだ開いただけなのでそのパフォーマンスは未知数だけど、これでデバッグが楽になる~♪
いままでalertとか、documentにテキストレイヤーを追加してそこに出力したりして調査してたから(^^;

開き方はというと
ファイル>スクリプト>参照でファイル選択ダイアログを出して、実行するスクリプトを選択。ALTキーを押しながら「読み込み」をすると上の画面を開くことができました。

ExtendScript Toolkitのヘルプ>オブジェクトモデルビューアで次のような画面が表示できました。

これがあればリファレンス調べるのが楽になって幸せになれそうですね!

Javascriptでオブジェクト解析

ブラウザ向けのJavascriptの開発環境はだいぶ充実してきた感がある今日この頃ですけど、PhotoShopとか、こうしたキワモノを扱う時にはweb上の情報も不足していてなかなか欲しい情報が得られません・・・

こうした時はオブジェクト自身に聞くのが一番!っとリバースエンジニアリングとかそうした機能がほしぃですよね。
オブジェクト毎のメソッド一覧とか引数、戻り値のリファレンス、クラス変数(プロパティ/フィールド)の一覧があると色々助かるんだけど。。。

っとうわけで、なんちゃって解析をしたのがPhotoshop+Javascriptでサムネールに載せた資料でした。

これはどうやって捕ったかというと


itemList = new Array();
for(hoge in object){
  itemList[itemList.length] = hoge;
}

っとして、itemListをテキストに吐き出して拾い上げてつくりました。
最初は


analystObj = {methods: new Array(),
              property:new Array(),
              perce:function(obj){
                  for(hoge in obj){
                      if(typeof eval("obj."+hoge) == 'function'){
                         this.methods[this.methods.length] = hoge;
                      }else{
                         this.property[this.property.length] = hoge;
                      }
                  }
              },
              };

こんな感じで解析用オブジェクトを作って。。。っと思もったんですけど、evalが毒でPhotoshopに怒られてしまって上手くいかなかったんですよね(^^;
try/catchで回避できないかとやってみたんですけど、ほとんど取れなくて実質意味がなかったのであきらめちゃいました。。。

しばらくNativeなJavascriptからも離れてしまっていたので思い出す良い切っ掛けになりました。

こうしたらいいんじゃないの?みたいな突っ込みありましたら是非是非お願いします!

PhotoShop+JavaScriptでサムネール

PhotoshopやillastratorなどAdobe製品でJavascriptを使ったマクロが組めるって話を以前から聞いていましたが、なかなか触る機会が無かったので弄ってみました。

で、できたものがこちらのサムネイル

[処理内容]
・フォルダ内のjpg画像の一覧を取得
・ファイルを開いて440pxにリサイズ
・画像をサムネール画像にコピペ
・画像の位置調整(4段6コマの24コマ構成)
・テキストでナンバリング
・ファイルに保存して次のファイルを作成

わざわざPhotoshopでしかもJavascriptでやるような内容じゃないんですけどね(^^;

Javascriptでファイル操作ってあんまりしないし、FileSystemベースとは違うAdobeオリジナルオブジェクトってこともあって色々と苦労しました。。。

特に癖があるな~って思ったことがいくつかありました。。。
 ・テキストレイアは一般レイヤーのkind(種類)フラグを変更すると内容(オブジェクト)が変わる。キモイよ~。。。
 ・テキストレイヤー位置を指定して書けない。。。
 ・絶対位置への移動機能が無い。。。何故に!?
 ・画像を選択範囲でしかコピーできなさげなところ
   レイヤーのコピー機能が無い。。。どういうこと!?
 ・コピペする場所を指定できない。
   キャンバスの中心に画像の中心を合わせて配置されるみたい。
   規則性があってくれたところが救いでしたけど。。。左上原点を計算して、そこから再配置みたいな考え方でソースが複雑になっちゃいました。。。

っとまぁ、色々苦労したわけですけど何とか形になったかな?

ついでにオブジェクトを調べたりした結果を添付します~
以下の内容はオブジェクトのプロパティ(フィールド)とメソッドがごちゃ混ぜです。


[layer]
kind,
fillOpacity,
layerMaskDensity,
layerMaskFeather,
vectorMaskDensity,
vectorMaskFeather,
filterMaskDensity,
filterMaskFeather,
grouped,
isBackgroundLayer,
pixelsLocked,
positionLocked,
transparentPixelsLocked,
textItem,
typename,
name,
allLocked,
blendMode,
linkedLayers,
opacity,
visible,
bounds,
xmpMetadata,
parent

[layer[kind=ART].textItem]
contents,
size,
font,
justify,
antiAliasMethod,
autoKerning,
color,
useAutoLeading,
tracking,
verticalScale,
horizontalScale,
baselineShift,
leading,
ligatures,
alternateLigatures,
oldStyle,
position,
direction,
fauxBold,
fauxItalic,
capitalization,
strikeThru,
underline,
language,
noBreak,
kind,
justification,
leftIndent,
firstLineIndent,
rightIndent,
spaceBefore,
spaceAfter,
hangingPuntuation,
textComposer,
hyphenation,
minimumGlyphScaling,
desiredGlyphScaling,
maximumGlyphScaling,
minimumLetterScaling,
desiredLetterScaling,
maximumLetterScaling,
minimumWordScaling,
desiredWordScaling,
maximumWordScaling,
autoLeadingAmount,
hyphenateWordsLongerThan,
hyphenateAfterFirst,
hyphenateBeforeLast,
hyphenLimit,
hyphenationZone,
hyphenateCapitalWords,
width,
height,
warpStyle,
warpDirection,
warpBend,
warpHorizontalDistortion,
warpVerticalDistortion,
typename,
parent




[layer[kind=TEXT].textItem]
antiAliasMethod,
autoKerning,
color,
useAutoLeading,
tracking,
verticalScale,
horizontalScale,
baselineShift,
contents,
font,
leading,
ligatures,
alternateLigatures,
oldStyle,
position,
direction,
size,
fauxBold,
fauxItalic,
capitalization,
strikeThru,
underline,
language,
noBreak,
kind,
justification,
leftIndent,
firstLineIndent,
rightIndent,
spaceBefore,
spaceAfter,
hangingPuntuation,
textComposer,
hyphenation,
minimumGlyphScaling,
desiredGlyphScaling,
maximumGlyphScaling,
minimumLetterScaling,
desiredLetterScaling,
maximumLetterScaling,
minimumWordScaling,
desiredWordScaling,
maximumWordScaling,
autoLeadingAmount,
hyphenateWordsLongerThan,
hyphenateAfterFirst,
hyphenateBeforeLast,
hyphenLimit,
hyphenationZone,
hyphenateCapitalWords,
width,
height,
warpStyle,
warpDirection,
warpBend,
warpHorizontalDistortion,
warpVerticalDistortion,
typename,
parent