たった1行のJSコードでひたすらアイドル水着画像をあつめる
改行抜けば1行になるよ?
たった◯行のコードでひたすらアイドル水着画像をあつめる
なんかそういうタイトルのエントリが(超局所的に)バズっているようなので調べてみた。
- 【PHP】たった10行のコードでひたすらアイドル水着画像をあつめる - utgym’s diary
- 【Ruby】たった3行のコードでひたすらアイドル水着画像をあつめる(Rubyだよ) - maeharinの日記
- 【Goutte】たった数行のコードでひたすらアイドル水着画像をあつめるのをGoutteで書いてみた - iakioの日記
- 【Python】たった 4 行のコードでひたすらアイドル水着画像をあつめる(Python だよ) - Memo
- 【Haskell】たった6行のコードでひたすらアイドル水着画像をあつめる(Haskell)
- 【Perl】ゆーすけべー日記
- 【PHP】外部ライブラリ不要で、たった一つのツイートに納まる長さのコードでひたすらアイドル水着画像を集める - uzullaがブログ
ただ、どれも「指定したURLのページ内の特定画像を抽出して一つにまとめる」ということしかしてなくて、それって別にサーバーサイドスクリプトでやる意味あるのかなぁなんて思ったのですよ(モジュール化とかしらない)。だって、欲しい画像があるページのURLを取得するためにそのページをブラウザで開くんでしょ? だったらその場で抽出したいじゃん。そこでJavaScriptです。
最近のウェブサービスはどこもjQuery使ってて楽だね。
jQueryがないといちいちgetDocumentsByClassName()とかでゴニョゴニョしなきゃいけないけど、jQueryが標準で読み込まれているのでサックリ終わらせられるのいいね。
そんなわけで、JS版ひたすら水着はこちら。(82文字)
$( $(".MTMItemThumb").get().reverse() ).each( function(){ $("body").prepend($(this)); } );
最初にreverse()をしてるのは、ページの先頭に画像を集めるため、要素の追加を$("body").prepend()で行なっている関係で、表示順序が他の人のと逆になってしまうのですよ。それへの対策です。
ただ、このコードだと、画像一覧の下部に既存ページのデータが残ってしまうので、それもすっきりしたければ、下記のコードでいけます。(90文字)
var i = $(".MTMItemThumb"); var b = $("body"); b.empty(); i.each(function(){ b.append($(this)); });
今度はページをすっきりさせた上で、要素を追加できるので、prepend()じゃなくてappend()使ってます。だからreverse()してない。
ただ個人的にはクリックした先のページも見られるようにしたいよね。いや、クロールすると文字数おおくなるから、せめてanchorタグは引っ張っておきたい。
そこでこれ。(99文字)
var i = $(".MTMItemThumb").parent(); var b = $("body"); b.empty(); i.each(function(){ b.append($(this)); });
最初の画像のDOM取得時に、parent()を呼んで、その親要素(aタグ)を拾ってきている。
【追記】アドバイスもらった
jQueryのappendToを使えば、なんと改行を抜かなくても1行で表せるじゃないか! すごい! 上記で踏んできた段階の中でも一番短くて、もう上の項目不要なんじゃないかと。(56文字)
$(".MTMItemThumb").parent().appendTo($("body").empty());
JavaScriptの最大の利点
やっぱUserScriptを書く最大の利点と言ったら、ブックマークレットでしょう。そこでこれをブックマークレットにした。適当にブックマークを作成し、そのURL欄を下記に置き換えればよろしかろう。
javascript:(function(){$(".MTMItemThumb").parent().appendTo($("body").empty());})();
やっぱPureJSで書かなきゃね。
ライブラリが許されるのは小学生までだよねー。
んなわけねーだろ
var d = document; var b = d.getElementsByTagName("body")[0]; var d1 = d.createElement("div"); d1.innerHTML = b.innerHTML; b.innerHTML = ""; b.appendChild(d1); var i = d.getElementsByClassName("MTMItemThumb"); for(var j = 0; j < i.length; j++){ b.appendChild(i[j].parentNode.cloneNode(true)); } b.removeChild(d1);
なんかもう少し簡略化できそうだけどなー。特にbodyの中身を、後で一括削除するために新しくdivを作ってそこに入れなおしてるあたり。これをやらずにbodyタグの中身を空にすると、その時点でgetElementsByClassName()の中身が空配列になっちゃう(live nodeList objectのため)なので、どこかしらに残しておく必要があるんですよ。うーむ。
やっぱこれはこの企画の意味を考えると長すぎるなー。