ラベル jsFiddle の投稿を表示しています。 すべての投稿を表示
ラベル jsFiddle の投稿を表示しています。 すべての投稿を表示

2013年11月11日

よくある Back to Top ボタンの作成例


ブログとかでページ右下あたりによくある 「Back to Top」 ボタンを作ってみました。

DEMO


ページを開いてスクロールすると、右下に「Back to Top」ボタンが現れます。 ボタンをクリックしてページ上部までスクロールします。 今回は jQuery を使ってみたら、ごくありがちなボタンになってしまいました。 もしかしたら多少クリックしずらいかもしれません。

サンプルコード

※以下はDEMOを簡略化するため多少コード変更しています

HTML:
<div class="back-to-top">Back to Top</div>
JavaScript:
$(function() {
  var backToTop = $('.back-to-top');

  // クリックでページ上部までスクロール
  backToTop.hide().on('click', function() {
    $('html,body').animate({
      scrollTop: 0
    }, 800);
    return false;
  });

  // スクロール位置がページ上部じゃなかったら表示
  $(window).on('scroll', function() {
    if ($(this).scrollTop() < 10) {
      backToTop.hide();
    } else {
      backToTop.show();
    }
  });

});
CSS:
.back-to-top {
  display: none;
  position: fixed;
  bottom: 10px;
  right: 10px;
  width: 100px;
  height: 40px;
  background: rgba(255, 64, 64, 0.7);
  color: rgba(255, 255, 255, 0.9);
  line-height: 3;
  text-align: center;
  font-size: 13px;
  font-weight: bold;
  font-family: verdana, sans-serif;
  cursor: pointer;
  z-index: 9999;
}

.back-to-top:hover {
  background: rgba(255, 16, 16, 0.8);
  color: rgba(255, 255, 64, 0.8);
}
お好みで変更してください。

まとめ

真面目なページに突然こんなんがあったら嬉しくなりそう

/show/ じゃないほうの jsFiddle:

Contact


2012年9月4日

ランレングス法をJavaScriptの正規表現で書いてみた

ランレングス法は、BMP などに使われるデータ圧縮アルゴリズムです

連続したデータが多ければ圧縮率は上がりますが、
そうでない場合、逆にデータ量が増えることもあります
// ランレングス圧縮/解凍
var RunLength = {
  compress : function(s) {
    return s.replace(/([\s\S])\1{0,8}/g, function(a, c) {
      return c + a.length;
    });
  },
  decompress : function(s) {
    return s.replace(/([\s\S])(\d)/g, function(a, c, n) {
      return new Array(++n).join(c);
    });
  }
};



2012年4月22日

JavaScriptライブラリ Pot.js 関連リンクまとめ

Pot.js 関連のリンクまとめ

JavaScript ライブラリ Pot.js に関する記事やサンプルの紹介です。
Pot.js は CPU に負荷をかけることなく JavaScript の実行を可能とするユーティリティライブラリです。
MOONGIFT さんの記事 で紹介されたのもあって、せっかくなのでまとめてみました。



Pot.js / PotLite.js

Pot.js は CPU に負荷をかけることなく JavaScript の実行を可能とするユーティリティライブラリです。
PotLite.js は Pot.js の非同期な部分だけを抽出したライトバージョンです。

ダウンロード

マニュアル

その他の情報についてはマニュアル/マニュアルからのリンク から参照ください。

レポジトリ




その他、なにか問題・バグ・感想・指摘などあれば、
コメントやメールまたは @polygon_planet まで送っていただけるとうれしいです。



2012年4月5日

並列処理のWorkerぽいWorkeroid実装。JavaScriptライブラリPot.js 1.17 リリース




Pot.js 1.17 と PotLite.js 1.34 リリースしました。





Web Workers

バックグラウンド処理、並列処理ができる HTML5 API の Web Workers は、
主要なブラウザですでに実装されています。

var worker = new Worker('child.js');
worker.onmessage = function(event) {
    alert(event.data); // 'hogefuga' がアラートされる
};
worker.postMessage('hoge');
child.js
onmessage = function(event) {
    postMessage(event.data + 'fuga');
};
上のような感じで使うのですが、基本的に 'child.js' のようにファイル名を渡さないといけないんです。
なので JavaScript が 2 ファイルになります。

並列で 4 スレッドとか 6 スレッドとかしてたら どんどん増えてファイルの管理がめんどいです。

あと、ブラウザによって動作 (子Worker のスコープ) が若干異なっていて
せっかく並列処理がネイティブにできるのに、なかなか扱いにくいものになってしまってます。

そこで、ネイティブ Worker が利用できたら ネイティブで
なければ Worker エミュレータとして、
クロスブラウザに動作する Workeroid (Pot.Workeroid) を実装しました。

Pot.Workeroid

  • 基本的にネイティブ Worker と同じに並列処理ができる
  • ネイティブ Worker がなければエミュレートする
  • クロスブラウザ
  • 子 Worker スレッドで importScripts しなくても Pot.js が使える
  • エミュレート時でも terminate で中断/終了できる
  • ファイル名だけじゃなく関数オブジェクトを子 Workerとして渡せる

ネイティブの Worker は
子Worker プロセス内では 親 window のライブラリなどが使えません。
importScripts('hoge.js') で読み込まないと使えないのですが、
Pot.Workeroid はデフォルトで Pot.js が利用できます。
なので、Pot.Deferred.forEach などを利用して CPU 負荷を抑えた処理が可能です。

最大の特徴として、
コンストラクタに ファイル名のほか、関数を渡すことが可能なことです。

以下は function で Worker スレッドを生成する例です。

var worker = new Pot.Workeroid(function(data) {
    //                                          
    // このスコープの中が 子Worker スレッド     
    //                                          
    var add = 1;                                
    postMessage(data + add);                    
});

// メッセージを受信した時
worker.onmessage = function(data) {
    alert(data);
};

// エラー時の設定 (任意)
worker.onerror = function(err) {
    alert(err);
};

// 1 を 子 Worker に送信 => 2 が alert される
worker.postMessage(1);

をつけたスコープ内が 子 Worker として別スレッドになります。
子 Worker 空間内は、別ファイルに書いてる気持ちでコーディングするとわかりやすいかもです。
たくさんのスレッド作る場合でも、少しの短いコードでも 別ファイルにしなくて済みます。

これで楽に並列処理ができるとうれしい!


Pot.Workeroid の例を含む詳細は Pot.Workeroid リファレンス から参照できます。

あと、簡単な動作テストを jsFiddle に置いてあります。

更新したところ


Pot.js / PotLite.js

Pot.js は CPU に負荷をかけることなく JavaScript の実行を可能とするユーティリティライブラリです。

PotLite.js は Pot.js の非同期な部分だけを抽出したライトバージョンです。

ダウンロード

マニュアル

その他の情報についてはマニュアル/マニュアルからのリンク から参照ください。

レポジトリ




その他、なにか問題・バグ・感想・指摘などあれば、
コメントやメールまたは @polygon_planet まで送っていただけるとうれしいです。



2012年3月12日

jsFiddleだらけ-JavaScriptライブラリPot.js+PotLite.jsリリースノート



Pot.js 1.15 1.16PotLite.js 1.32 1.33 リリースしました。

2012-03-13 追記:
Pot.js 1.15 と PotLite.js 1.33 はバギーなためアップデートしました。詳細
2012-03-13 時点の最新は Pot.js 1.16PotLite.js 1.34 です。最新にアップデートお願いします。。


このバージョンでは、
  • 文字列処理の高速化
  • 重くなりそうな処理を非同期化
などを適応しました。

文字列処理の高速化

先日、ふと思って String.fromCharCode を呼ばずに
U+0000 - U+FFFF の配列をあらかじめ作成して インデックスに対応させたらどうなのかなって
ベンチマークとってみました。


結果として、String.fromCharCode(c) のような
apply で配列を使わない場合、かなり高速化できました。
メモリ消費も文字列などは気にするほどじゃなかった。
String.fromCharCode.apply(null, [...]); のような場合は逆に遅くなるので
従来通り String.fromCharCode を使用しています。

(この件はあほなミスをしてて@gochoさんにつっこまれて助かりました)

重くなりそうな処理を非同期化

重くなりそうな処理とは、巨大な文字列が渡される可能性のある関数や、
ループ回数が未知の処理などです。

途中で「応答のないスクリプト」警告なんぞ でてしまったらめんどうです。
そういった対処や負荷軽減も含めて 関数オブジェクトに deferred というメソッドを持たせました。

例えば Pot.md5(string); が同期実行に対して
Pot.md5.deferred(string); は、非同期で実行します。


圧縮・解凍

文字列を LZ77 アルゴリズムをベースに圧縮・解凍する
Pot.Archive.AlphamericString も同様に非同期化しています。

その他のサンプル

他にもいくつかテスト用にサンプルがあったので紹介します。



Pot.js / PotLite.js

Pot.js は CPU に負荷をかけることなく JavaScript の実行を可能とするユーティリティライブラリです。

PotLite.js は Pot.js の非同期な部分だけを抽出したライトバージョンです。

ダウンロード

マニュアル

その他の情報についてはマニュアル/マニュアルからのリンク から参照ください。

レポジトリ




その他、なにか問題・バグ・感想・指摘などあれば、
コメントやメールまたは @polygon_planet まで送っていただけるとうれしいです。


2012年2月25日

JavaScriptコードをトークンに分解する正規表現

/(\/\*[\s\S]*?\*\/|\/{2,}[^\r\n]*(?:\r\n|\r|\n|)|"(?:\\[\s\S]|[^"\r\n\\])*"|'(?:\\[\s\S]|[^'\r\n\\])*'|(?:(?:\/(?!\*)(?:\\.|[^\/\r\n\\])+\/)(?:[gimy]{0,4}|\b)(?=\s*(?:(?!\s*[\/\\<>*+%`^"'\w$-])[^\/\\<>*+%`^'"@({[\w$-]|===?|!==?|\|\||[&][&]|\/[*\/]|[,.;:!?)}\]\r\n]|$)))|<([^\s>]*)[^>]*>[\s\S]*?<\/\2>|>>>=?|<<=|===|!==|>>=|\+\+(?=\+)|\-\-(?=\-)|[=!<>*+\/&|^-]=|[&][&]|\|\||\+\+|\-\-|<<|>>|0(?:[xX][0-9a-fA-F]+|[0-7]+)|\d+(?:\.\d+)?(?:[eE][+-]?\d+)?|[1-9]\d*|[-+\/%*=&|^~<>!?:,;@()\\[\].{}]|(?![\r\n])\s+|(?:\r\n|\r|\n)|[^\s+\/%*=&|^~<>!?:,;@()\\[\].{}'"-]+)/g
これがパターンです。

例えば、
/* comment */
var regex = /[\/\\"']*/g;
var str = "hoge\"fuga'\
piyo";
// 'comment'
var arr = [
    0x0FFF, 1e8, 0, 12345,
    3.524603890386048e+24,
    0.0006215, 0666 // (classic mode)
];
var i = 0;
var e4x = <>{{///*E4X*///}}</>;
var xml = <root><hoge fuga="piyo" /></root>;
var ほげ = '/*"ほ//げ"*/';
var $var = re.test(str) && arr[2] || (i+++i) === 1;
このコードを文字列として code.match(pattern) すると、以下の要素を持った配列が得られます。
0: /* comment */
1: 

2: var
3:  
4: regex
5:  
6: =
7:  
8: /[\/\\"']*/g
9: ;
10: 

11: var
12:  
13: str
14:  
15: =
16:  
17: "hoge\"fuga'\
piyo"
18: ;
19: 

20: // 'comment'

21: var
22:  
23: arr
24:  
25: =
26:  
27: [
28: 

29:   
30: 0x0FFF
31: ,
32:  
33: 1e8
34: ,
35:  
36: 0
37: ,
38:  
39: 12345
40: ,
41: 

42:   
43: 3.524603890386048e+24
44: ,
45: 

46:   
47: 0.0006215
48: ,
49:  
50: 0666
51: 

52: ]
53: ;
54: 

55: var
56:  
57: i
58:  
59: =
60:  
61: 0
62: ;
63: 

64: var
65:  
66: e4x
67:  
68: =
69:  
70: <>{{///*E4X*///}}</>
71: ;
72: 

73: var
74:  
75: xml
76:  
77: =
78:  
79: <root><hoge fuga="piyo" /></root>
80: ;
81: 

82: var
83:  
84: ほげ
85:  
86: =
87:  
88: '/*"ほ//げ"*/'
89: ;
90: 

91: var
92:  
93: $var
94:  
95: =
96:  
97: re
98: .
99: test
100: (
101: str
102: )
103:  
104: &&
105:  
106: arr
107: [
108: 2
109: ]
110:  
111: ||
112:  
113: (
114: i
115: ++
116: +
117: i
118: )
119:  
120: ===
121:  
122: 1
123: ;
そもそもシンタックスハイライトのほうが崩れてる…。

jsFiddle でテストできます。

文字列は、改行の前にバックスラッシュ (\) がある場合も対応してみました。
セミコロン挿入もあって、スペースと改行は区別されます。

E4X はシンプルなのだけ対応してます。
var x = <root<div id={(function() {
return '</root>' ? 'hoge' : 'fuga';
}())}></root>
こういうのは無理っぽい。あとネストとか。


match() に g つけて match(/(...)/g) がこんな便利だなんて…。


2012年2月11日

JavaScript whileループとPot.Deferred.forEverイテレータでCPU使用率を比較-Pot.js+PotLite.jsリリースノート

Pot.js 1.13PotLite.js 1.30 リリースしました。

Pot.js 1.13 と PotLite.js 1.30 では、主に内部ループ処理を大幅に高速化しました。
(そろそろ ChangeLog 作らないとまずいかも…)

あとは、変数宣言とか 例の (function(){}()) とか (結局直してる)
細かい修正などです。

先日、Hacker NewsEcho JS で Pot.js が紹介されました (ありがとうございます)。
でもアクセスが今までの 1000 倍くらいになって、すごいことになってちょっとビビった。
(API サーバのほうは適当に調節しておいたので大丈夫だった。よかった。。)


それで Pot.js の本来の存在意義ですが、

実行環境の CPU に負荷をかけることなく JavaScript が実行できる。

といったことが本来の目的であり、常に追求している目標でもあります。
Deferred が重点にとらわれがちですが、Pot.Deferred はそれの足がかりであり、
Pot.Deferred だけがライブラリの中核ではないので、いろいろ使ってみてください。

新しいデザインのリファレンス

現在、新しいデザインでリファレンスを書き直しています。


前は 全部で 1 ファイルになっちゃってて、どんどん重くなるし更新もやり難くて
どうしようもなかったのですが、今回は 各ページを非同期読み込みにして
英語版と日本語版で見れるようにして、戻るボタンとかも再現したり、がんばってます。

でもまだ作成途中です (2012-02-11 現在)。

ある程度完成したら 本来の /index.html に移動させようと思ってるんですが、
先ほどの Echo JS などが /test-for-new-design/ にリンクしちゃってるもんだから
どうしようかと考え中。(たぶん リダイレクトか、もうこのままでいいか…)。

CPU 比較を実行

jsFiddle のほうで
JavaScript の while ループと、Pot.js の非同期イテレータとで CPU 使用率の比較を書いてみました。
前に書いた Pot.js イテレータと jQuery.each と for ループの CPU 使用率をグラフで比較
と同じ事ですが、実際に実行できます (ただし負荷テストなのでブラウザクラッシュに気をつけてください)。
もっとも最近のブラウザはループでクラッシュしないと思いますが。。

CPU 使用率は、Web ブラウザからの JavaScript では取得できないと思うので、
CPU モニタリングするアプリとか、
なければ Win ならタスクマネージャから「パフォーマンス」→ 「CPU 使用率」
を見ながら実行してみるとわかりやすいと思います。


今回は while 文と Pot.Deferred.forEver の比較ですが、
Pot.js 非同期イテレータは CPU 負荷が一定量に抑えられたループが可能になっていると思います。
ただし、この例のような処理だと実行時間はある程度伸びてしまいます。

実行時間に関しては 速度調整 が可能なので、処理に応じたスピードを選ぶこともできます。
(このへんは今後改善したいです)。

サンプルのソースコード

jsFiddle でも確認できますが、今回使用したサンプルのソースコードです。
ループ処理の部分だけ抽出しています。

JavaScript while ループを使ったソースコード:
// while で同期ループして圧縮
compressSync : function(s) {
    var a = 53300, b, c, d, e, f, g = -1,
        h, i, r = [], x = String.fromCharCode;

    s = new Array(a--).join(' ') + s;
    while ((b = s.substr(a, 256))) {
        for (c = 2, i = b.length; c <= i; ++c) {
            d = s.substring(
                a - 52275,
                a + c - 1
            ).lastIndexOf(b.substring(0, c));
            if (!~d) {
                break;
            }
            e = d;
        }
        if (c === 2 || c === 3 && f === g) {
            f = g;
            h = s.charCodeAt(a++);
            r.push(
                x(h >> 8 & 255),
                x(h & 255)
            );
        } else {
            r.push(
                x((e >> 8 & 255) | 65280),
                x(e & 255),
                x(c - 3)
            );
            a += c - 1;
        }
    }
    return r.join('');
}

Pot.js 非同期イテレータ (今回は Pot.Deferred.forEver) を使ったソースコード:
// Pot.js 非同期イテレータで圧縮
compressAsync : function(s) {
    var a = 53300, b, c, d, e, f, g = -1,
        h, i, r = [], x = String.fromCharCode;

    var deferred = new Pot.Deferred();

    s = new Array(a--).join(' ') + s;

    // whileループを forEver に置き換え
    Pot.Deferred.forEver[SPEED](function() {

        b = s.substr(a, 256);
        if (!b) {
            throw Pot.StopIteration;
        }

        for (c = 2, i = b.length; c <= i; ++c) {
            d = s.substring(
                a - 52275,
                a + c - 1
            ).lastIndexOf(b.substring(0, c));
            if (!~d) {
                break;
            }
            e = d;
        }
        if (c === 2 || c === 3 && f === g) {
            f = g;
            h = s.charCodeAt(a++);
            r.push(
                x(h >> 8 & 255),
                x(h & 255)
            );
        } else {
            r.push(
                x((e >> 8 & 255) | 65280),
                x(e & 255),
                x(c - 3)
            );
            a += c - 1;
        }
    }).then(function() {
        deferred.begin(r.join(''));
    }, function(err) {
        deferred.raise(err);
    });
    return deferred;
}

同期か非同期かの違いがありますが、
単に、メインの while 文を Pot.Deferred.forEver に変えてるだけです。
forEver は、StopIteration が throw されるまで、永久にループする関数です。

あと、この関数は LZ77アルゴリズムによる圧縮関数をJavaScript最短コードで | 圧縮電子精神音楽浮遊構造体 (見れないかも)
で作ったソースコードをちょっとだけ手直ししたものです。
文字列を圧縮解凍します。

Pot.js / PotLite.js

Pot.js は CPU に負荷をかけることなく JavaScript の実行を可能とするユーティリティライブラリです。

PotLite.js は Pot.js の非同期な部分だけを抽出したライトバージョンです。

ダウンロード

マニュアル

マニュアルは上に書いたように 2012-02-11 現在、まだすべてのオブジェクトの解説ができてません。。

その他の情報についてはマニュアル/マニュアルからのリンク から参照ください。

レポジトリ




その他、なにか問題・バグ・感想・指摘などあれば、
コメントやメールまたは @polygon_planet まで送っていただけるとうれしいです。