htsign's blog

ノンジャンルで書くつもりだけど技術系が多いんじゃないかと思います

iOS端末でデバッグするためのブックマークレット

iOSに限らず、モバイルOSのWebブラウザってものすごくデバッグに不向きですよね。
一応iOSのMobile Safariには「デバッグコンソール」というモノがありますが、
アレは主にJavascriptのエラーを検出するのが目的のもので、デザインがうんたらには役に立ちません。

ですので、少しはデザイン寄りのデバッグができるものを作ろうと思い立って作ったのが以下のブックマークレットです。

javascript:(function(){var a="touchstart";document.documentElement.addEventListener(a,function(n){this.removeEventListener(a,arguments.callee,false);var g=n.target||event.srcElement,o=window.open("about:blank",""),h=o.document,l=h.body,m,c=function(b){return h.createElement(b)},i=function(d,b){return h.defaultView.getComputedStyle(d,null)[b]},e=function(d){for(var b in d){o.HTMLElement.prototype[b]=d[b]}};(function(){if(g.nodeType!==1){g=g.parentNode;arguments.callee()}})();e({ele:function(){for(var d=0,b=arguments.length;d<b;d++){this.appendChild(arguments[d])}return this},ID:function(b){this.id=b;return this},cl:function(b){this.className=b;return this},txt:function(b){this.ele(h.createTextNode(b));return this}});o.onunload=function(){j(true)};function j(b){var d=g.style;if(b){d.outline=m}else{m=i(g,"outline");d.outline="2px solid red"}}j();(function(){var t=h.createElement("meta"),r="margin:0;",u="padding:0;",p="width",q="box-sizing:border-box;",s="background-color",d="border";t.name="viewport";t.content="width=device-width,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no";h.getElementsByTagName("head")[0].ele(t,c("style").txt("*{font-size:14px;}:root,body{"+r+u+p+":100%}div{"+r+u+q+"-webkit-"+q+"}#tree,#table{margin-left:auto;margin-right:auto;"+p+":300px}#tree{display:block;margin:8px auto;height:24px}#table{color:#333;"+d+":4px ridge silver;overflow:hidden}.row{float:none;clear:both}.colhead,.coldata{padding:1px;outline:1px solid silver;"+s+":#eee;"+p+":50%;height:20px;float:left}.colhead{font-weight:bold;text-align:center;"+s+":#ccc;"+d+":1px solid silver}"))})();function k(){var d=c("select").ID("tree"),r=c("optgroup"),q=c("optgroup"),p=[],s=[],b=function(u){var v=u.id,t=u.className;return u.tagName.toLowerCase()+(v?"#"+v:"")+(t?"."+t.split(" ").join("."):"")};d.onchange=function(){var t=this.selectedIndex;if(t<1){return}l.innerHTML="";j(true);g=p[t-1];j();k();f()};d.ele(c("option").txt(b(g)));s.unshift(b(g));r.label="親要素";q.label="子要素";(function(){var t=[],u=g;while(!!u.parentElement){t.push(u.parentElement);u=u.parentElement;s.unshift(b(u))}p=p.concat(t.reverse());t.forEach(function(v){r.ele(c("option").txt(b(v)))});d.ele(r)})();Array.prototype.slice.call(g.childNodes).filter(function(t){return t.tagName}).forEach(function(t){q.ele(c("option").txt(b(t)));p.push(t)});d.ele(q);l.ele(d);h.title=s.join(" > ").slice(-40)}k();function f(){var b=c("div").ID("table").ele(c("div").cl("row").ele(c("div").cl("colhead").txt("プロパティ"),c("div").cl("colhead").txt("値")));"width,height,position,display,left,top,right,bottom,z-index".split(",").forEach(function(d){b.ele(c("div").cl("row").ele(c("div").cl("coldata").txt(d),c("div").cl("coldata").txt(i(g,d)||"(none)")))});l.ele(b)}f()},false)})()

はい、長いですね。
当初は「とりあえずブロックレベル要素の幅・高さが分かりゃいいや」と思っていたんですが、
まぁ作ってるうちに欲が出てきましてね…いろいろ実装してしまいました。
とはいえそんなに凝った機能はないので、使い方は使ってみればたぶん分かります。

上のスクリプトと同じものをtextarea内に記述したHTMLファイルを用意したので、ブックマークレット登録の際におひとつどうぞ。

一応説明させていただくと…
上のブックマークレットを呼び出すことでdocument.documentElementに対してtouchstartイベントを登録します。
その状態で現在表示しているページ上で任意の箇所をタップすると、
タップした要素の width, height, position, display, left, top, right, bottom, z-index の各スタイル適用状況を確認することができるウィンドウを生成します。

主な機能として以下があります。

  • 要素のスタイル適用状況を表示
  • 親要素、子要素(1階層のみ)の一覧を表示
  • 親要素、子要素のスタイル適用状況を追跡する
  • 元ウィンドウの現在確認している要素に枠をつける


スクリプトの前の方にある

var a="touchstart";

var a="click";

に書き換えることでPC版ブラウザ(Chromeで動作確認)でも一応使えます。
でもPC版ブラウザはこんなもの使わずとも、より高機能でより広範に使える開発者コンソールが標準で備わっているので、
そこで使うことはあまり想定していません。

また、後ろの方にある

var n="width,height,position,display,left,top,right,bottom,z-index".split(",");

にカンマ区切りでいろいろ書き足していくと、いろいろなスタイル適応状況が分かります。
この辺はお好きにどうぞということで。

どうでもいいけど、こういうのデバッグとは言わないかもしれない。




あと、IE9でも対応してる box-sizing: border-box; にベンダープリフィクス付けないと認識しない iOS 4.3.x はクソ


追記: 2012/04/14
JS内容を若干更新し、いちいち「Go!」ボタンを押さなくてもいいようにしました。
また、いくつかデフォルトで確認できるプロパティを増やしています。

追記: 2012/04/26
全体的にリファクタリングしました。
それとスタイルに若干の修正を。