JavaScript

ホイール操作でスライドをめくるユーザースクリプト

以前作ったslideshare scrollというユーザースクリプトでQiitaのスライドにも対応しようと思ったものの、3年前のコードで無駄が多いので一から書き直した。 wheel-de-scroll.user.js - Gist createWheelHandlerで前後ボタンの取得を遅延させているのは、Qiit…

GitHub上のJSコードでモジュールをリンクで辿れるようにするユーザースクリプト

OctoLinkerという、より高機能な拡張機能が既に存在した。 を作った。GitHub上でのコードリーディングが少し楽になる(じっくり読むならgit clone)。 link-to-module.user.js ソースコード - Gist link-to-module.user.js RAW (インストール)

JavaScriptでgetterとsetterのどちらか一方のみをオーバーライドする

JavaScript でオブジェクトに accessor property を定義したとき、継承先でそのプロパティの getter, setter のどちらか一方のみを override するのは一筋縄にはいかない。例として、長方形を表す Rectangle と、正方形を表す Square を定義することを考える…

switch文によるコールバック地獄回避

url.txtに書かれているURLを取得し、そのURLのリソースの内容を取得し、1秒後にその内容をalertするという例(のための例)を考える。まずは普通に書いてみる。 var client = new XMLHttpRequest; client.open('GET', 'url.txt'); client.onload = function …

JavaScriptでカスラムエラーをどう作るか

はじめに:IE 11、Firefox 28、Chrome 34で試しているJavaScriptのErrorオブジェクトにはstackプロパティにコールスタックを表す文字列がセットされる。これは現行のECMAScript仕様では規定されておらず、実装によって違いがある。 function foo() { bar(); …

プロトタイプ=見本となるオブジェクト

JavaScriptを始めたころはprototypeオブジェクトが何なのかよく分からなかったけど、その名の通り「見本」あるいは「原型」なんだと分かれば、コンストラクタ関数とprototypeオブジェクトの関係は単純だと思える。 例として、人を表すオブジェクトを考えてみ…

IEで関数名を取得する

IE以外のブラウザであれば、関数.nameで関数名を取得することができる。 var func = function hoge() { } func.name; // => "hoge" 事実上標準でES6にも取り入れられそう。しかしIEではバージョン11においても関数.nameは定義されていない。そこで、Function…

文字列SetとしてのDOMTokenList

DOMTokenListを文字列専用のSetとして使えそうと思ったけど、空白を含む文字列を追加できないので使いづらかった(DOMTokenListを得られるのはclassListかrelListで、どちらもセパレータが空白)。 var set = document.createElement('div').classList; set.…

似非Set

Setを似非実装してみた。sizeではなくlengthならArray.prototypeのメソッドを転用できるのに。 似非Setdeleteは予約語なので、関数名に同名を付けられない。Setを既に実装しているFirefoxでは、Set.prototype.delete.name === 'delete'となる。Function#name…

JavaScriptの ++i は i += 1 ではない

JSLintでは ++ を使うとエラーになる。++i の代わりに i += 1 と書くようにということのようだ。でも、+= 1 は ++ の正確な代替ではなかった。加法演算子は被演算子の少なくとも一方が文字列なら、文字列連結処理になる。一方、前置増分演算子 (++) は初めに…

FirefoxにおけるArray#concatは strict mode function 相当

Array.prototypeの大半のメソッドは、配列以外のオブジェクト(NodeListなどの擬似配列など)にも転用できるように汎用的に定義されている。Array.prototype.concatもその一つだけど、他のメソッドとは異なりthis値に配列っぽさは求められておらず、どんなオ…

CSSセレクタ4の字句解析器を書いた

CSS4 セレクタエンジンの事始めとして。字句解析の範囲では、CSS3 とそれほど変わらない。違いは Reference combinator で使う「/」と、セレクタの subject を指定する「!」くらい。 yonQuery/lexer.js at master · rikuba/yonQuery · GitHub デモ用のページ…

NodeListを配列に変換するのにArray.applyを使うのはどうか

NodeListやHTMLCollectionを配列(Array)に変換する方法の一つに、Array.prototype.sliceを使う方法がある。 var array = Array.prototype.slice.call(document.getElementsByTagName('A')); でも、最近の実装であればArray.applyもその用途に使える。 var ar…

Array/Stringの汎用メソッドをこだわって定義する

FirefoxではArray.prototypeやString.prototypeにあるメソッドを簡単に転用できるように、コンストラクタ(Array, String)自身に汎用メソッド(generic method)が定義されています。 これにより、 Array.prototype.forEach.call(nodeList, body.appendChil…

breakできるforEach ―throwを使って―

JavaScriptのforEach的なものでbreakしたい話 - 車輪を再発明 / koba04の日記 思いつき。break文のように入れ子になった内側のループの中から外側のループも抜けられるように。 function Break(target) { this.target = target; } function forEach(array, c…

文字コードを使ってソート

JS Bin Array.apply(null, Array(100)) .map(function () { return Math.random() * 1000 | 0; }) .map(String.fromCharCode) .sort() .map(function (c) { return c.charCodeAt(0); }); 140文字に収まらなかった。

IEではフォーム内の要素にIDを付けてもグローバル変数として定義されない

サンプルコード <title>TEST</title> <body> <input id="input1"> <form> <input id="input2"> </form> <pre><script> function w(text) { document.writeln(text); } try { w('input1: ' + input1); } catch (e) { w('input1 is undefined'); } try { w('input2: ' + input2); } catch (e) { w('input2 is undefi…</pre></body>

slideshareのスライドをスクロールでめくるユーザースクリプト

wheel de slideというユーザースクリプトとして作り直した。以下の内容はもう古い。 version 1.2: speakerdeck, docs.google.comにも対応。 version 1.3: slideshareでめくり終えたときに表示されるスクリーンを考慮するように修正。 https://gist.github.co…

DOM Traversal の出番

多分javascriptについての質問です。h1,h2,h3と見出しが入ってい… - 人力検索はてな ({ observe: function (doc) { this.iterator = doc.createNodeIterator(doc, NodeFilter.SHOW_ELEMENT, this, true); doc.addEventListener('keydown', this, false); }, …

常にマッチする正規表現を使えばJavaScriptでも固定位置でのパターンマッチができる

パターンの末尾に「|」を付け加えると、その正規表現は常にマッチする。 /aaa/.exec("xyz"); // => null /aaa|/.exec("xyz"); // => [""] これを使えば、ある位置でのみパターンマッチを行うということ(Perl の正規表現で「\G」のメタ文字を使うようなこと…

正規表現のキャプチャの応用

キャプチャした部分文字列を、文字クラスや先読みに転用できることに気づいた。 順不同の組み合わせ 例えば、ショートカットキーを表す文字列(ここでは ctrl+shift+alt+x とする)にマッチする正規表現において、ctrl と shift と alt の順番に関わらずマッ…

Firefoxはdocumentにclickイベントリスナーを登録すれば中・右クリックも捕捉できる

Firefoxのclickイベントは、イベントリスナーの登録先がdocumentか要素かによって、中・右クリックも捕捉するかどうかが変わる。 /* Firefox 3.6.13 */ document.addEventListener('click', function (e) { alert(e.button); /* 左クリック、中クリック、右…

querySelector(All)のレシーバは、セレクタのコンテキストには影響を与えない

<ul id="list"> <li>階層1</li> <li>階層1 <ul> <li>階層2</li> <li>階層2</li> </ul> </li> </ul> <script> var list = document.getElementById('list'); var lis = list.querySelectorAll('ul li'); </script> 変数lisには階層2のli要素だけが含まれると思っていたが、実際には階層1のli要素も含まれてしまう。querySelector、querySelectorA…

HTMLFormElement#elementsにはtype="image"のinput要素は含まれない

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>HTMLFormElement#elements Test</title> <form action="#" id="testForm"> <ul> <li><input type="text"></li> <li><input type="password"></li> <li></li></ul></form></meta>

A要素は文字列コンテキストではhrefプロパティ値で評価される

window.openの第一引数にA要素(HTMLAnchorElement)をそのまま渡しているコードを見て、動かないんじゃないかと思って試してみると問題なく動いて驚いた。どうやらHTMLAnchorElementは文字列コンテキストではhrefプロパティの値として評価される、つまりtoS…

要素ノードにデータを紐付ける関数

HTML5で、紐付けたいデータが文字列なら、data-で始まる属性(custom data attribute)を付けることができる(詳細はコメント欄を参照)。 DOM3のNode#setUserData・Node#getUserDataのように、間接的に要素とデータを紐付けられる関数を作った。jQuery.data()…

jQueryを使わずに画像の先読み(プリロード)

function preLoadImages() { for (var i = 0, I = arguments.length; i < I; ++i) { new Image().src = arguments[i]; } } preLoadImages("image1.gif", "/path/to/image2.png"); Preloading Images with jQuery and JavaScript | Code Engineered [JS]jQuer…

Firefoxでのみ動くイベントリスナー

Firefoxでは、グローバルスコープに「on+イベントハンドラ名」の名前の関数を宣言すると、その関数をwindowのイベントハンドラとして設定してしまうので気をつける。 // グローバルスコープで function onclick(evt) { alert('click'); } // Firefoxのみ、こ…

使い捨て関数と使い捨てコンストラクタ

使い捨て関数 無名関数と呼ばれているけど、ここでは使い捨て関数と呼ぶ。 (function () { // 即実行される })(); 使い捨てコンストラクタ 無名コンストラクタ? new function () { // 即実行される // ただし、コンストラクタとして }; コンストラクタとし…

ページ内のタブ文字をスペースに置き換えるブックマークレット

タブ文字(\t)を半角空白2文字に置き換えるブックマークレットを作った。IEでは動かない。インストールはリンク先から。 tabToSpace - Hatena::Let document.body.innerHTML = document.body.innerHTML.replace(/\t/g, ' ');と単純に書くこともできる(IEでも…