JavaScript

松田 vs 十亀シミュレーター

こんにちは。作者です。

まず初めに。
十亀選手、松田選手。ネタにしてしまって申し訳ありません。
特にこれ以上の言い訳をするつもりはありませんが、こんなに広まるとは思いませんでした。

次に、特に十亀選手のファンの方。
不快に思われた方もいらっしゃると思いますが、申し訳ありません。
「ファイターズファンが作ったのかと思うと楽しめなくなった」というご意見も拝見しました。
気持ちはわからなくはないです。けど、見なかったことにしていただけると幸いです。
とはいえ、知るまではそれなりに楽しんでいただけたのかと思います。

なお、証拠を出すことはできませんが、おーぷんにスレ建てしたのは私ではありませんし、該当のスレッドに書き込んでもいません。
まとめられて初めて知りました。おかげでバグの修正もできましたけど。

僕がした広報行為は、自分のTwitterで「作ったよ」とpostしたのと修正した際の報告のpostだけです。リツイートしてくれた人にいいねつけたりもしてませんし、言及してくれた人にリプライつけたりもしていません。

それでは、全てにお答えすることはできませんが、言及いただいたご意見・ご感想に返答させていただきます。

まず

該当の発言を見つけられませんでしたが、「グラシアル vs 十亀も作って欲しい」
僕の調べた限り、この二人の対戦通算でもまだ8打席ですよね。確かにここまではグラシアル選手から見て好相性ですけど、2012年から今日まで積み上げてきた50を超える打席が醸し出す何か、が、このシミュレーターの肝だと僕は思っています。だからこそ何人か見かけましたけどライオンズファンの方にも笑って受け入れられるんだと思います。ので、僕は作りません。シミュレーター自体はhtmlとJavaScript(jQuery)とCSSだけの作りで、簡単にコピーできますからご自分でどうぞ。

こちらも該当の発言を見つけられませんでしたが「加賀 vs バレンティン版を」
パ専なもので、お二方の関係性を把握していなかったのですが、こちらは加賀投手がバレンティン選手を抑え込んでいるパターンなんですね。そんなわけでよく知らないのと、なんとなくですけどあまり面白いものにはならなそうなので、僕は作りません。ご自分でどうぞ。

某まとめサイトのコメント欄より「わりかし丁寧にコード書かれてて草生える」
実は最初のバージョンはくっそ汚いやっつけのコードでしたが、思いっきりリファクタリングしました。やっといてよかったーw

私です。

と言われたからというわけでもないですが、流石にちょっと説明不足な気はしたので、アップデートの際に説明文を入れるようにしました。

ありがとうございます。なかなかの褒め言葉です。

色々エゴサーチして見てますけど5点以内というのは僕もまだ見たことがないので、もし出たら勝ちでいいと思います。ちなみに公開はしていませんが、指定した点数以下or以上が出るまで勝手に再試行するバージョンをというのを作ってローカルで30分位回しましたけど5点以内は出ませんでした。
ちなみに僕が計算したわけじゃないので本当かどうかわかりませんがノーノーが出る確率はおよそ500億分1だそうです。

ライオンズファンの方とお見受けしますが、そういう方に面白いと言っていただけると救われます。

ぼくもかなりしょうもないなぁと思います。

大谷9人vs柳田9人だったらどっちが勝つ?みたいなスレって定期的に建つじゃないですか。それと大して変わらないと思いますよ。あとは作れるかどうか、作ろうと思うかどうか。

三者凡退すると赤い字になるんですよ。体感では3回くらい回せば見られるくらいのプチレアです。
なお、クラス名は”one-two-three”。分かる人には分かる。

ちゃんとお仕事しましたか?そこまでのものじゃないですよ?ホント。
ところで、僕ちゃんとhttpsのurl貼ったはずなんだけどどこで欠落したんだろ。別にいいけど。

自分で言うのもなんですけど、妙に中毒性あるんですよね、これ。でもずっとやるのはアレですよ……
あと7点は結構レアです。UR。

最後に

アクセス跳ね上がってて草

アフィ貼っときゃよかったかなー

これは初めて知った。

String.prototype.split() - JavaScript | MDNより

separator が、キャプチャする括弧を含む正規表現だった場合、マッチしたキャプチャする括弧の結果(任意の undefined となった結果を含む)である各回の区切りが出力配列に結合されます。

きっかけは「Javascript | 'あ●い▲う'などの文字列をsplitなど用いて区切り文字も含めた配列にしたい。

あんまり使う機会はなさそうだけど備忘として。

phpのpreg_splitだとこうはならない。ってことはperlもだよな。

アドレスバーに 「s /hoge/fuga/g」などと入れてページ中のhogeをfugaに置換する

まぁ、めったにやることないと思うけど、要するにこういうの→“「ツイート」を「ツイート(笑)」に置換するブックマークレット”を汎用的にしたやつ。「Opera用って時点で汎用的じゃない」っていうツッコミは受け付けるけど対応はしない。

準備

  1. Operaの設定画面のウェブ検索タブを開く。
  2. 検索キーワード「s」はデフォルトだと「Opera Support」なので(残しておきたければ)「s」から別のキーワードに変える。
  3. 追加ボタンを押して検索エンジンの追加ダイアログを開く。
  4. 名前
    何か適当な名前。replaceとか。
    キーワード
    s
    アドレス
    javascript:var s='%s';var a=s.split('/');var g=new RegExp(a[1], a[3]);var r=document.evaluate("//text()[contains(., "+a[1]+")]", document, null, 7, null);for(var i=0;i<r.snapshotLength;i++)r.snapshotItem(i).nodeValue=r.snapshotItem(i).nodeValue.replace(g, a[2]);void(0);

    と入力して「OK」。

使い方
どこかのページで置換したい単語があったら、アドレスバーに「s /置換したい単語/置換後の単語/g」などと入力(sのあとのスペースは必要)してEnter 。

毎回「g」フラグを入れるのが面倒な方は、アドレス欄に入力するスクリプト文字列の「a[3]」のところを「'g'」に変えればいいです。

うん。使い道ないね。

追記
Chromeでもできた。Firefoxは(設定の仕方が)よくわからない。

Togetter用のフィルタリングuser.js

茂木さんは別に嫌いじゃないんだけど、茂木さんの連続つぶやきをまとめている人たちはできれば手分けしてやってほしいなと思ったので作った(思ったのは本当だけど、もちろんそれだけが作った理由ではない)。

togetter-filter_300.js

必要な設定をした上で、Operaでuser.js用のフォルダに置いとけば、勝手に働くはず。自分用バージョンとちょっと違うので、ちゃんと試してないから あんまり自信ない。

Togetterのまとめのページをゴニョゴニョするやつその2

togetterのまとめのページで”残りを読む”ボタンをいちいち押すのがめんどくさいので作った。

mod-togetter-read-more.js

大長編なまとめだと結構切ないことになりますが、ご了承ください。

Operaでuser.js用のフォルダに置いとけば、勝手に働きます。

Togetterのまとめのページをゴニョゴニョするやつ

togetterのまとめページで、オリジナルのtweet(要するにパーマリンク)へのリンクが素直じゃないので作った。
ついでに、個人的には名前のところもtogetter内のユーザページじゃなくてtwitter.comのユーザページに飛んで欲しいので、そういう処理もします。

bookmarklet版

javascript:(function(){t='https://twitter.com/';l=document.querySelectorAll('.status_right');for(i = 0;i<l.length;i++){u=l[i].querySelector('.status_name');n=u.textContent;u.href=t+n;s=l[i].querySelector('[onclick]');if(s){d=s.getAttribute('onclick');s.removeAttribute('onclick');d=d.replace(/^.*\"(.*)\".*$/,'$1');s.setAttribute('href',t+n+'/status/'+d);}}})()

http://togetter.com/li/~なページでアドレスバーに貼り付けるとかするとリンク先がいろいろ置き換わります。

user.js版

mod-togetter.js

Operaでuser.js用のフォルダに置いとけば、勝手に働きます。

Togetterをフィルタリングするuser.js

http://mattz.xii.jp/sites/default/files/togetter-filter_100.js
http://mattz.xii.jp/sites/default/files/togetter-filter_100b1.js

出来ること

  1. 指定したIDによるまとめを一覧から除外
  2. 指定したキーワードをまとめタイトルに含むまとめを一覧から除外
  3. 指定したID(1とは別管理です)によるコメントをコメント欄から除外
  4. 指定したIDのtweetを一時的に抽出/非表示/強調する機能を追加(1.0.0で追加)

簡単な使い方

user.jsそのものの使い方は省略します。

まとめのタイトルによるフィルタリング

このuser.jsを有効な状態でTogetterの「注目のまとめ」などの一覧ページを開くと、各まとめのタイトルの左に[NGワード登録]というボタンが表示されま す。
これをクリックすると、入力用のダイアログが開きます。初期状態ではそのまとめのタイトルが既に入力済みの状態になっていますので、適宜編集して[OK]ボタンを押すと、そこで登録した単語(文字列)を含むまとめは、「NGタイトルにより非表示にされています(クリックで再表示)」という表示に置き換わります。

これをクリックすると、フィルタリング対象のまとめでも表示し、登録してしまったNGワードを削除することもできます。

なお、「,」半角のカンマはNGワードに使えません。

まとめた人のIDによるフィルタリング

このuser.jsを有効な状態でTogetterの「注目のまとめ」などの一覧ページを開き、各まとめのまとめた人のアイコンをクリックすると、「このユーザの作 成したまとめを非表示にしますか?:○○」というダイアログが開きます。

[OK]を押すと、以後その人の作成したまとめは、一覧に表示されなくなります。復帰させたい場合は、その人のプロフィールページ(http://togetter.com/id/○○)に行くと、ページの左上の方に「このユーザのまとめは現在フィルタリング対象です。→[解除]」というメッセージが表示されますので、「解除」ボタンをクリックしてください。

コメント欄のIDによるフィルタリング

このuser.jsを有効な状態でTogetterの何かのまとめを開き、コメント欄の誰かのアイコンをクリックすると、「このユーザのコメントを非表示にしますか ?:○○」というダイアログが開きます。

[OK]を押すと、以後その人のコメントは、どのまとめページにも表示されなくなります。復帰させたい場合は、その人のプロフィールページ(http://togetter.com/id/○○)に行くと、ページの左下の方に「このユーザのコメントは現在フィルタリング対象です。→[解除]」というメッセージが表示されますので、「解除」ボタンをクリックしてください。

特定IDの抽出/非表示/強調

このuser.jsを有効な状態でTogetterの何かのまとめを開き、誰かのつぶやき部分をクリックすると、

このような物が表示されます。

[Pick-up]を押すと、その人のtweetsだけを残して、他の人のtweetを非表示にします。
[Remove]を押すと、Pickupの逆でその人のtweetsを非表示にします。
色付きの■部分を押すと、その人のtweetsのフォントカラーをその色に、背景色をアイボリーに変更して、少し目立つようにします。

やめたいときは「Click (or press [ESC]) to close.」部分をclickするか、Ecsキーを押してください。

また、これらの抽出/非表示/強調はあくまで一時的なもので、ページを読み込み直すと元の状態に戻ります。

Togetter用のuser.js最新版

http://mattz.xii.jp/sites/default/files/togetter_421.js

2011/10/05:いくつか設定項目を追加しました。

http://mattz.xii.jp/sites/default/files/togetter_410.js

2011/06/10:いくつか設定項目を追加しました。

http://mattz.xii.jp/sites/default/files/togetter_401.js

2011/06/06:Togetterのhtmlが変更になったようで「最初から"もっと読む"」が効いていなかったので修正しました。

http://mattz.xii.jp/sites/default/files/togetter_400.js

多少修正して、とりあえず4.0.0としてはフィックスします。

http://mattz.xii.jp/sites/default/files/togetter_400b1.js

とりあえず版。Togetterさん、リニューアルで以前に比べればだいぶすっきりしましたけど、個人的にはまだ要らない(サービスとし て必要なのは分かりますが)要素が多いので、その辺をすっきりするだけです。まぁ、ほとんどの項目はuser.cssで消せるんですけどね。

スクリプト適用前

スクリプトを適用し、全ての設定を有効にした場合

フィルタリングしたりするのは、別ファイルに分けようかと検討中。

「なんだっけ」でググると「もしかして:」を提示してくれるuser.js for Opera

なんだっけ、でくぐったら「もしかして:」で検索ワードだしてきたらこわいに触発された。力不足でクロスブラウザにはできなかった。

追記その5:「Opera9.6 から「安全でなくなった」 UserJavaScript があるけ どイコール「危険」というわけでもない話」を併せてお読みください。

拾う単語は、Yahoo!の急上昇ワードランキングから取得するようにした。Twitterの日本のTrendsから、とか、他の例えばランダム単語APIなんかでもいい。ただしその場合は若干スクリプトを変更する必要がある。Google TrendsのAPI欲しいんだけどないのかな?

あと、xmlをGETしてくるところは http://javascript.g.hatena.ne.jp/edvakf/20100329/1269881699 をほぼそのまま利用させてもらった。edvakfさんに感 謝。

追記その4:追記の1~3はそうはいってもやっぱり恥ずかしいのでhtmlのコメントとして隠した。とにかくコメント欄参照のこと。

// ==UserScript==
// @name          nandakke.js
// @author        mattz
// @namespace     http://mattz.xii.jp
// @license       public domain
// @description   「なんだっけ」でググると「もしかして:」を提示してくれるuser.js for Opera
// @published     2011-05-13
// @version       0.0.2
// @include       http://www.google.com/search?*
// @include       http://www.google.co.jp/search?*
// ==/UserScript==
(function(){
  var _document = document;
  var call = Function.prototype.call,
      indexOf = Array.prototype.indexOf,
      splice = Array.prototype.splice,
      preventDefault = Event.prototype.preventDefault,
      removeChild = Node.prototype.removeChild,
      createElement = Document.prototype.createElement,
      push = Array.prototype.push,
      appendChild = Node.prototype.appendChild,
      parseFromString = DOMParser.prototype.parseFromString,
      getElementsByTagName = Document.prototype.getElementsByTagName,
      parseInt = window.parseInt,
      random = Math.random,
      encodeURIComponent = window.encodeURIComponent,
      setAttribute = Element.prototype.setAttribute,
      getElementById = Document.prototype.getElementById,
      split = String.prototype.split;
  var scripts = [];
  var callbacks = [];
  opera.addEventListener('BeforeScript', function(e) {
    indexOf.call = splice.call = preventDefault.call = removeChild.call = call;
    var s = e.element;
    var index = indexOf.call(scripts, s);
    if (index &gt;= 0) {
      callbacks[index].call(null, s.text);
      splice.call(scripts, index, 1);
      splice.call(callbacks, index, 1);
      preventDefault.call(e);
      removeChild.call(s.parentNode, s);
    }
  }, false);
  var xGet = function (url, callback) {
    createElement.call = appendChild.call = push.call = call;
    var s = createElement.call(_document, 'script');
    s.src = url;
    appendChild.call(_document.body, s);
    push.call(scripts, s);
    push.call(callbacks, callback);
  }
  var rand_word = function(xml) {
    parseFromString.call = call = setAttribute.call = createElement.call = appendChild.call = getElementById.call = call;
    var xmldom = new DOMParser();
    xmldom.async = false;
    var dom = parseFromString.call(xmldom, xml, "application/xml");
    if (! dom) return false;
    var is = getElementsByTagName.call(dom, 'item');
    var r = parseInt(random() * 20);
    var word = is[r].getElementsByTagName('title')[0].textContent;
    var b = createElement.call(_document, 'b');
    b.textContent = word;
    var a = createElement.call(_document, 'a');
    a.href = '/search?hl=ja&rls=ja&spell=1&q=' + encodeURIComponent(word);

    setAttribute.call(a, 'class', 'spell');
    appendChild.call(a, b);
    var span = createElement.call(_document, 'span');
    span.textContent = 'もしかして: ';
    setAttribute.call(span, 'class', 'spell');
    setAttribute.call(span, 'style', 'color:#cc0000');
    var p = createElement.call(_document, 'p');
    setAttribute.call(p, 'class', 'ssp');
    appendChild.call(p, span);
    appendChild.call(p, a);
    appendChild.call(getElementById.call(_document, 'topstuff'), p);
  }
  var init = function() {
    split.call = call;
    var a = split.call(location.search, /[\?&]/);
    for(var i = 0; i &lt; a.length; i++) {
      var q = split.call(a[i], /=/);
      if ('q' == q[0] && '%E3%81%AA%E3%82%93%E3%81%A0%E3%81%A3%E3%81%91' == q[1]) {
        xGet('http://searchranking.yahoo.co.jp/rss/burst_ranking-rss.xml', rand_word);
        return false;
      }
    }
  }
  window.addEventListener('DOMContentLoaded', init, false);
})();

ページ

Subscribe to JavaScript