Home > 2008年05月

2008年05月

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
  • Comments (Close): -
  • TrackBack (Close): -

再帰関数のメモ

関数は自分自身を参照し、呼び出す事ができます。

Core JavaScript 1.5 Reference:Functions - MDC

引数で渡された数の階乗を計算

関数名で自分自身を呼び出す
function f(n){
    if (n <= 1){
        return 1;
    }
    return n * f(n - 1);
}
alert(f(5));    // 120
arguments.calleeで自分自身を呼び出す

無名関数の時は関数名が無いので arguments.calleeで自分自身を呼び出す。arguments.calleeは関数自体を参照する。

alert(
    (function (n){
        if (n <= 1){
            return 1;
        }
        return n * arguments.callee(n - 1);
    })(6)
);    // 720

ドキュメントツリーをたどり、ボーダーをセットする

setBorder(document.body, 'H3');

// (element:はじめの要素, target:ボーダーを付ける要素)
function setBorder(element, target){
    if (element.nodeName == target){
        element.style.border = 'solid 2px yellow';
    }
    for (element = element.firstChild; element; element = element.nextSibling){
            setBorder(element, target);
        }
    }
}

ドキュメントツリーをたどり、新しいウィンドウにノード名を書き出す

main();

function main(){
    var tree = Array();
    trace(document, tree, 0);
    write(tree);
}

function write(ary){
    var w = window.open('');
    w.document.write('<html><head><title>Recursive Function</title></head><body>');
    for (var i = 0; i < ary.length; i ++ ){
        w.document.write('<p>' + ary[i] + '<br /></p>');
    }
    w.document.write('</body><html>');
    w.document.close();
}

// DOMを解析 (node:対象のノード, ary:ノードを入れる配列, ノードの深さ)
function trace(node, ary, depth){
    ary.push(space(depth) + node.nodeName);
    if (node.childNodes.length){
        depth ++ ;
    }
    for (var i = 0; i < node.childNodes.length; i ++ ){
        trace(node.childNodes[i], ary, depth);
    }
}

// インデント
function space(number){
    for (var i = 0, string = ''; i < number * 4; i ++ ){
        string += '&nbsp;';
    }
    return string;
}

livedoor クリップでタグ補完した時のキャレットの位置を修正する User JavaScript

livedoor クリップでクリップを追加する時、今まで自分の付けたタグが候補に出てきて、候補の中から選択してタグの文字列を補完することが出来る。

便利で良いのだが、私の環境ではキャレット(カーソル)の位置は選んだタグの最後ではなく、入力した文字までの位置に止まってしまう。

例・「javas」まで入力して、「javascript」を選択した時(「|」はキャレット)
javas|
↓ 補完
javas|cript

タグを補完した後、いちいちEndを押すのが面倒なので、キャレットを補完した文字列の最後に移動する User JavaScriptを書いた。

livedoor Clip Move Caret

ちなみにタグ補完はクリップ(ブックマーク)する時だけでなく、ユーザのクリップのページでも使える。右側の「タグで探す」検索ボックスに文字列を入力すると該当するタグ補完候補が出てくる。ユーザは自分でなくてもいいので、他人のページで試せる。(まあ普通はタグを探す時インクリメンタルサーチを使うだろうから、必要ないけど。)


追記: 2008年7月1日 スクリプトの修正。

Opera 9.5でも動くようにした。

Database Searchとソート

Database Searchはファイルのデータベースである Media Library(database.fpl)から検索できる foobar2000のコンポーネント。

プレイリストを自動的に作成するPlaylist TreeColumns UIからしか利用できないので、この Database Searchとソートで何とかPlaylist Treeに近づけられないかと試している。

Database Search

  1. メニューの Library > Database Searchから Database Searchの検索ダイアログを開く。
  2. Search、Format、Filter、Patternに入力して検索する。
  3. 検索した結果を Ctrl+Enter(または右クリックから Send to Playlist...を選択)を押して、検索された曲を新しいプレイリストに送る。

ソート

TitleFormattingによるソート
プレイリストの曲を選択して、メニューの Edit > Sort > Sort by ...(あるいは右クリックメニューの Sort > Sort by ...)から Sort by ...のダイアログを開き、Title Formattingを入力して実行する。
無作為にソート
プレイリストの曲を選択して、メニューの Edit > Sort > Randomize(あるいは右クリックメニューの Sort > Randomize)を選ぶ。
逆順にソート
プレイリストの曲を選択して、メニューの Edit > Sort > Reverse(あるいは右クリックメニューの Sort > Reverse)を選ぶ。

設定例

ランダムに曲を選ぶ

すべての曲を選び、無作為にソートする。

Database Search
Search:
Media Library
Format:
 
(Filter:)
All items
Pattern:
 
Sort
Randomize
再生回数の多い曲

すべての曲を選び、再生回数でソートする。

Database Search
Search:
Media Library
Format:
 
(Filter:)
All items
Pattern:
 
Sort
Sort by ... %play_counter%
Reverse

曲数を減らすなら、再生回数が10回以上(任意)の曲を選び、再生回数でソートする。

Database Search
Search:
Media Library
Format:
 
(Filter:)
Query
Pattern:
%play_counter% GREATER 9
Sort
Sort by ... %play_counter%
Reverse
レートが高い曲

ratingフィールドが 4以上の曲を選び、レートでソートする。

Database Search
Search:
Media Library
Format:
 
(Filter:)
Query
Pattern:
%rating% GREATER 3
Sort
Sort by ... %rating%
Reverse
Hip-Hop

ジャンルが 'Hip-Hop'か 'Rap'の曲を選び、無作為にソートする。

Database Search
Search:
Media Library
Format:
Genre ([%genre%])
(Filter:)
Find any word
Pattern:
hip-hop rap
Sort
Randomize
Kanye Westの絡んだ曲

フィールド(アーティスト、タイトル、その他)のどれかに 'Kanye West'が含まれている曲を選び、無作為にソートする。

Database Search
Search:
Media Library
Format:
 
(Filter:)
query
Pattern:
* HAS "kanye west"
Sort
Randomize

問題点

  • 曲の数が選べない。foobar2000はある程度曲数が多くてもフリーズしないが。
  • すべての条件を覚えられない。パターンにいちいち入力するのが面倒。AutoHotkeyUWSCなどのスクリプトを使えば何とかなるかも。

参考にしたページ

livedoor Readerのスペースキーのカスタマイズ

livedoor Reader のホットキーをカスタマイズするブックマークレット - (new Hatena).blog()のスペースキーの機能が便利だ。

スクロールするのはデフォルトのままだが、フィードの一番下までいくと、次のフィードに移るようになる。そのため、スペースキーから次のフィードに移るキーに変える手間が減る。

「livedoor Reader のホットキーをカスタマイズするブックマークレット」から取り出したスペースキーのところをOpera User JavaScriptにしてみた。

ついでにシフト+スペースキーにも同じような機能を付けてみた。上にスクロールして、フィードの一番上までいくと、前のフィードに移るようにした。

// ==UserScript==
// @include     http://reader.livedoor.com/reader/*
// ==/UserScript==


window.opera.addEventListener('AfterEventListener.load', function (e){

    // init()関数でなければ抜ける
    if (e.listener.toString().indexOf('function init()') == -1) return;

    Keybind.add("space", function (){
        var pos = $("right_container").scrollTop;
        Control.scroll_next_page();
        if (pos > $("right_container").scrollTop - 20 && writing_complete()){
            message('next');
            Control.read_next_subs();
        }
    });

    Keybind.add("shift+space", function (){
        var pos = $("right_container").scrollTop;
        Control.scroll_prev_page();
        if (pos == $("right_container").scrollTop && writing_complete()){
            message('previous');
            Control.read_prev_subs();
        }
    });

    // イベントリスナーを削除
    this.removeEventListener( 'AfterEventListener.load', arguments.callee, false)
}, false);

スクロールして一番下まで行くのになぜか上に戻ってしまい、次のフィードに移れないことがあるので、判定を甘くした。(スペースキーを押して、スクロールが 20pxより少ない時、次のフィードに移す。)

判定を甘くしたせいで、livedoor Readerの設定>詳細設定>スクロール量の調整を「任意」に設定してあり、スクロール量が「20px」より少ないと、すぐに次のフィードに移ってしまう。なので、スクロール量の調整を「20px」以上にするか、「1画面分」または「画面の半分」に設定するようにして下さい。


追記: 2008年7月2日 スクリプトの修正。

Karafuto Blog livedoor Readerのショートカットキーを変更する User JavaScriptKarafuto Blog livedoor Readerのショートカットキーを削除するの追記と同じ Opera 9.5対策。livedoor Readerのスクリプトの「window.onload = init;」を「'document.addEventListener("DOMContentLoaded", init, false);」に書き換える処理を User JavaScriptに追加した。

追記: 2008年7月8日 スクリプトの修正。

スクリプトの「window.onload」を「document.addEventListener」に書き換える上の方法では確実ではないから、検出したイベントハンドラが init()関数か確かめてから実行するようにした。

loadイベントのテスト

loadイベントはページのデータが全て読み込まれた後発生する。

DOMContentLoadedイベントはページの HTMLが解析された後発生する。

しかし、window.opera.addEventListenerメソッドなら AfterEvent.loadイベントで全てのデータ(?)の読み込みを検出できる。

User JavaScriptでテストしてみた。

loadイベントと DOMContentLoadedイベント、AfterEvent.loadイベントを検出したらエラーコンソールに書き込む。AfterEvent.loadイベントの時には、イベントが起きた要素とその要素に scr属性か href属性があればその値を書き込む。時間も付けているが、あくまで目安ということで。

画像、エラーが多いサイトでは見づらい。一度に複数のサイト、フレームのあるサイトを開くと、ごっちゃになり訳が分からなくなる、などの欠点がある。

// ==UserScript==
// @include    http://www.opera.com/*
// ==/UserScript==

(function(){
    var start = new Date().getTime();
    var num = 1;
    opera.postError( ' --------------  start  -------------- \n' + location.href);

    document.addEventListener('DOMContentLoaded', function() {
        postEvent('DOMContentLoaded');
    }, false);

    document.addEventListener('load', function() {
        postEvent('load');
    }, false);

    window.opera.addEventListener('AfterEvent.load', function(e) {
        var file = e.event.target.src ? ' : ' + e.event.target.src : e.event.target.href ? ' : ' + e.event.target.href : '';
        postEvent( 'AfterEvent.load' + '\n' + e.event.target.nodeName + file);
    }, false);

    function postEvent( str) {
        var time = new Date().getTime();
        opera.postError( num + '.  ' + ( time - start ) / 1000 + '\n'  + str );
        num ++ ;
    }
})();

Operaのページを開いてスクリプトを試してみた一例。

 --------------  start  -------------- 
http://www.opera.com/
1.  1.844
AfterEvent.load
SCRIPT : http://www.opera.com/js/menu.js
2.  2.203
AfterEvent.load
LINK : http://www.opera.com/css/templates.css
3.  2.281
AfterEvent.load
LINK : http://www.opera.com/css/media.css
4.  2.5
AfterEvent.load
SCRIPT : http://www.opera.com/js/newsticker.js
5.  2.844
AfterEvent.load
LINK : http://www.opera.com/css/handheld.css

(エラー。コンテンツのブロック)JavaScript - http://counter.hitslink.com/track.js
リンク先のスクリプトを読み込むことができません

6.  2.969
AfterEvent.load
SCRIPT : http://www.opera.com/js/hitslink.js
7.  2.969
AfterEvent.load
IMG : http://counter.hitslink.com/statistics.asp?v=1&s=100&acct=opera&an=Opera&sr=&ck=1162&rf=&sl=undefined&av=9.27%20%28Windows%20NT%205.1%3B%20U%3B%20ja%29&l=ja&pf=Win32&pg=/&cd=32&rs=1024%20x%20768&tz=-540&je=false&tks=1208096266320
8.  3.141
AfterEvent.load
LINK : http://www.opera.com/css/screen.css
9.  4.031
AfterEvent.load
IMG : http://www.opera.com/img/lang/jp/flag.gif
10.  4.031
AfterEvent.load
IMG : http://www.opera.com/img/operalogo.gif
11.  4.203
AfterEvent.load
IMG : http://www.opera.com/img/download/new/dl-mini.png
12.  4.219
AfterEvent.load
SCRIPT : http://cetrk.com/pages/scripts/0006/9056.js
13.  4.313
DOMContentLoaded
14.  5.359
AfterEvent.load
IMG : http://www.opera.com/img/front/minicampaign/europe.jpg
15.  5.516
AfterEvent.load
BODY
16.  5.516
load
17.  5.719
AfterEvent.load
#document

実際のエラーコンソールには「JavaScript,Unknown thread」が出るが、見づらくなるので削除した。

参考にした記事

Home > 2008年05月

おまかせリンク(R)
全記事表示リンク
Search
Meta
Feeds

Page Top

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。