コンソールに出力する文字列を読みやすくする
以下のコードで元の文字列の各文字の位置を分かりやすくするための、補助的な文字列を生成できる
文字幅(=文字数)は元の文字列と同じとなる
var s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890'; console.log(s); var t = s.replace(/[\s\S]{1,4}/g, function(m) { return '^'+new Array(m.length).join(' ') }); console.log(t);
出力結果
ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
関数化して、'^'が現れる位置を調整可能にしてみる
var s = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890'; console.log(s); console.log(f(s, 4)); console.log(f(s, 8)); function f(s, width){ return s.replace( new RegExp('[\\s\\S]{1,'+(width || 4)+'}', 'g'), function(m){ return '^' + new Array(m.length).join(' '); }); }
出力結果
ABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^
Unicode 空白文字等調査
Unicode 'Other, Format'カテゴリ (Cf)
コード | 意味 | バージョン | コメント |
---|---|---|---|
U+200B | ZERO WIDTH SPACE | Unicode 1.1.0 | 幅の無い空白 |
U+200C | ZERO WIDTH NON-JOINER | Unicode 1.1.0 | |
U+200D | ZERO WIDTH JOINER | Unicode 1.1.0 | |
U+FEFF | ZERO WIDTH NO-BREAK SPACE | Unicode 1.1.0 | 幅の無い改行しない空白 |
Unicode 'Separator, Line'カテゴリ (Zl)
コード | 意味 | バージョン | コメント |
---|---|---|---|
U+2028 | Line Separator | Unicode 1.1.0 | LS |
Unicode 'Separator, Paragraph'カテゴリ (Zp)
コード | 意味 | バージョン | コメント |
---|---|---|---|
U+2029 | Paragraph Separator | Unicode 1.1.0 | PS |
Unicode 'Other, Control'カテゴリ (Cc)
コード | 意味 | バージョン | コメント |
---|---|---|---|
U+0009 | Horizontal Tabulation | Unicode 1.1.0 | HT, 水平タブ, \t |
U+000A | Line Feed | Unicode 1.1.0 | LF, ラインフィード, \n |
U+000B | Vertical Tabulation | Unicode 1.1.0 | VT, 垂直タブ, \v |
U+000C | Form Feed | Unicode 1.1.0 | FF, 改ページ, \f |
U+000D | Carriage Return | Unicode 1.1.0 | CR, キャリッジリターン, \r |
U+0085 | Next Line | Unicode 1.1.0 | NEL |
Unicode 'Separator, Space'カテゴリ (Zs)
コード | 意味 | バージョン | コメント |
---|---|---|---|
U+0020 | SPACE | Unicode 1.1.0 | 半角スペース |
U+00A0 | NO-BREAK SPACE | Unicode 1.1.0 | 改行しない空白 |
U+1680 | OGHAM SPACE MARK | Unicode 3.0.0 | |
U+180E | MONGOLIAN VOWEL SEPARATOR | Unicode 3.0.0 | |
U+2000 | EN QUAD | Unicode 1.1.0 | 'n'幅の四角形 |
U+2001 | EM QUAD | Unicode 1.1.0 | 'm'幅の四角形 |
U+2002 | EN SPACE | Unicode 1.1.0 | 'n'幅の空白 |
U+2003 | EM SPACE | Unicode 1.1.0 | 'm'幅の空白 |
U+2004 | THREE-PER-EM SPACE | Unicode 1.1.0 | 1/3'm'幅の空白 |
U+2005 | FOUR-PER-EM SPACE | Unicode 1.1.0 | 1/4'm'幅の空白 |
U+2006 | SIX-PER-EM SPACE | Unicode 1.1.0 | 1/6'm'幅の空白 |
U+2007 | FIGURE SPACE | Unicode 1.1.0 | フィギュアスペース, 等幅フォントの半分の幅, 数字用空白 |
U+2008 | PUNCTUATION SPACE | Unicode 1.1.0 | 約物スペース, 句読点用, 約物と同幅で横幅が狭い |
U+2009 | THIN SPACE | Unicode 1.1.0 | 1/5'm'幅の空白, 細い空白 |
U+200A | HAIR SPACE | Unicode 1.1.0 | ヘアスペース, 非常に細い空白 |
U+202F | NARROW NO-BREAK SPACE | Unicode 3.0.0 | 幅の狭い改行しない空白 |
U+205F | MEDIUM MATHEMATICAL SPACE | Unicode 3.0.0 | 中程度の幅の数学用空白 |
U+3000 | IDEOGRAPHIC SPACE | Unicode 1.1.0 | 和字間隔, 全角スペース |
どこかの英語のサイトを参考にしました
タグを生成
追記:Bookmarkletとして実行するとm%60の部分がURLデコードされて構文エラーとなってしまうのを修正(とりあえず%の直後に空白を追加)
(function(){ /* タイムスタンプを取得 */ javascript: var d = new Date(), o = d.getTimezoneOffset(), m = Math.abs(o), s = d.getFullYear() + '-' + ('0' + (d.getMonth()+1)).slice(-2) + '-' + ('0' + d.getDate()).slice(-2) + 'T' + ('0' + d.getHours()).slice(-2) + ':' + ('0' + d.getMinutes()).slice(-2) + ':' + ('0' + d.getSeconds()).slice(-2) + (o < 0 ? '-' : '+') + ('0' + Math.floor(m / 60)).slice(-2) + ':' + ('0' + (m % 60)).slice(-2); prompt('TimeStamp(ISO 8601)', s); // 1行にまとめたもの javascript: var d=new Date,o=d.getTimezoneOffset(),m=Math.abs(o),s=d.getFullYear()+'-'+('0'+(d.getMonth()+1)).slice(-2)+'-'+('0'+d.getDate()).slice(-2)+'T'+('0'+d.getHours()).slice(-2)+':'+('0'+d.getMinutes()).slice(-2)+':'+('0'+d.getSeconds()).slice(-2)+(o<0?'-':'+')+('0'+Math.floor(m/60)).slice(-2)+':'+('0'+(m% 60)).slice(-2);prompt('TimeStamp(ISO 8601)',s) /* 短縮化 */ javascript: var d = new Date, o = d.getTimezoneOffset(), m = Math.abs(o), s = d.getFullYear(); with(d){['-','-','T',':',':',o<0?'-':'+',':'].forEach(function(e,i){ s+=e+('0'+[getMonth()+1,getDate(),getHours(),getMinutes(),getSeconds(),Math.floor(m/60),m% 60][i]).slice(-2) })} prompt('TimeStamp(ISO 8601)', s); // 1行にまとめたもの javascript:var d=new Date,o=d.getTimezoneOffset(),m=Math.abs(o),s=d.getFullYear();with(d){['-','-','T',':',':',o<0?'-':'+',':'].forEach(function(e,i){s+=e+('0'+[getMonth()+1,getDate(),getHours(),getMinutes(),getSeconds(),Math.floor(m/60),m% 60][i]).slice(-2)})}prompt('TimeStamp(ISO 8601)',s);void(0) /* <ins>タグを生成 */ javascript: var i = prompt('タグの内容', ''), d = new Date, o = d.getTimezoneOffset(), m = Math.abs(o), s = d.getFullYear(); with(d){['-','-','T',':',':',o<0?'-':'+',':'].forEach(function(e,i){ s+=e+('0'+[getMonth()+1,getDate(),getHours(),getMinutes(),getSeconds(),Math.floor(m/60),m% 60][i]).slice(-2) })} if(i)prompt('TimeStamp(ISO 8601)', '<ins datetime="' + s + '">' + i + '</ins>'); // 1行にまとめたもの javascript:var i=prompt('タグの内容',''),d=new Date,o=d.getTimezoneOffset(),m=Math.abs(o),s=d.getFullYear();with(d){['-','-','T',':',':',o<0?'-':'+',':'].forEach(function(e,i){s+=e+('0'+[getMonth()+1,getDate(),getHours(),getMinutes(),getSeconds(),Math.floor(m/60),m% 60][i]).slice(-2)})}if(i)prompt('TimeStamp(ISO 8601)','<ins datetime="'+s+'">'+i+'</ins>');void(0) })();
メソッド内からメソッド名を取得
var o = { f : function(){ for( var i in this ){ if( this[i] == arguments.callee ){ console.log(i); } } } }; o.f(); // f
Bookmarkletで画像ビューア
Bookmarklet用の簡単なビューアVersion0.1(といっても1066文字もある・・・)
機能:
- 実行すると、ページ内の<img>要素を順番に表示。
- <img>要素が<a>要素に囲まれている場合は、<a>要素ごと表示。
- Right, Leftで画像切り替え、Escでビューア終了。ビューア終了後、vで再度実行。
- Rightで最初の画像より前に戻るか、Leftで最後の画像より先に進むとビューア終了。
テスト環境:Windows Vista SP2, Chrome 7.0.517.44
javascript:(function(a){function $(a,b,c){c=_.createElement(a);c.a=function(a){this.style.cssText=a};if(b)c.a(b);return c}var _=document,b=_.images,c=arguments.callee,d=_.body.appendChild($('div','position:fixed;left:0px;top:0px;width:100%;height:100%;background-color:rgba(0,0,0,.6);z-index:65535')),e=d.appendChild($('div','position:absolute;left:50%;top:50%;z-index:65535')),z='keydown',w=window,g=function(a){w.addEventListener(z,a,!1)},h=function(a){w.removeEventListener(z,a,!1)},j='U+001B';if(b.length==0)return;e.appendChild($('span'));function f(a,c){c=b.item(a);e.style.marginLeft=-c.width/2+'px';e.style.marginTop=-c.height/2+'px';e.replaceChild((/^a$/i.test(c.parentNode.tagName)?c.parentNode:c).cloneNode(true),e.firstElementChild)}f(a);g(function(e,k){k=e.keyIdentifier;if(k=='Left'?--a-a:k=='Right'?++a-a:k==j?0:1)return;e.preventDefault();if(a<0||b.length<=a||k==j){h(arguments.callee);_.body.removeChild(d);g(function(b){if(b.keyIdentifier=='U+0056'){b.preventDefault();h(arguments.callee);setTimeout(function(){c(k==j?a:0)},0)}});return}f(a)})})(0)
変数名・関数名・プロパティ名の短縮化をしてくれるJavaScriptコード圧縮機ってないかな。。。
DOMContentLoadedイベントのイベントターゲットを調べる
document.addEventListener('DOMContentLoaded', ...)という記述と
window.addEventListener('DOMContentLoaded', ...)という記述を見たので、どっちが正しいのだろうと思い、チェック用のHTML+jsを作成。
結果は、(IEを除く)どのブラウザでもdocumentがイベントターゲットとなっていた。IEはそもそもW3C DOMイベントモデルじゃないのでDOMContentLoadedをサポートしておらず問題外。
テスト環境
OS : Windows Vista SP2
Web Browser : Chrome 7.0.517.44 / Opera 10.63 / Firefox 3.6.12 / IE 8.0.6001.18975IC
テスト用コード (HTML+js)
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html lang="ja"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>DOMContentLoaded タイミングチェック</title> <script type="text/javascript"> <!-- var params = [ { name : 'window', target : window, type : 'load' }, { name : 'window', target : window, type : 'DOMContentLoaded' }, { name : 'document', target : document, type : 'load' }, { name : 'document', target : document, type : 'DOMContentLoaded' } ]; var eventPhaseStr = { 1 : 'CAPTURING_PHASE', 2 : 'AT_TARGET', 3 : 'BUBBLING_PHASE' } /** console.log, console.warnがない場合は適当なログ出力処理で代用 */ if( !window.console ){ window.console = {}; if( window.opera ){ console.log = function(msg){ window.opera.postError(msg); }; console.warn = function(msg){ console.log('WARNING: ' + msg); }; }else{ console.log = function(msg){ alert(msg); }; console.warn = function(msg){ console.log('WARNING: ' + msg); }; } } function makeListener(name) { return function(e){ console.log(name + ', ' + e.type + ', ' + eventPhaseStr[e.eventPhase]); }; } function AddEventListener(element, type, listener, useCapture) { if( element.addEventListener ){ element.addEventListener(type, listener, useCapture); }else if( element.attachEvent ){ console.warn('attachEvent used'); element.attachEvent('on' + type, listener); }else{ console.warn('event-handler used'); element['on' + type] = listener; } } console.log('TARGET, TYPE, EVENT_PHASE'); for( var i=0, l=params.length; i < l; i++ ) { var e = params[i]; AddEventListener(e.target, e.type, makeListener(e.name), false); AddEventListener(e.target, e.type, makeListener(e.name), true); } //--> </script> </head> <body> <h1 style="text-align : center">DOMContentLoaded タイミングチェック</h1> </body> </html>
テストした全ブラウザでconsole.log, console.warnの両方が使えた。いつからIEとOperaには用意されているんだろう・・・
function文とfunction式の違い
console.log(typeof fn1); // undefined console.log(typeof fn2); // function var fn1 = function(){}; function fn2(){}
varによる変数宣言は、スコープに入ったとき変数の追加だけ行われ、宣言のある行で値の代入が行われる。それに対してfunction式で定義した関数は、スコープに入ったときから使用可能。なので
function Hoge(){}
と
var Hoge = function(){};
は完全に同じではない。