javascriptとjQueryでBookmarkletを作ろうの第四回
はじめに
前回 はブラウザに表示した画面(HTML)から要素を指定して値を抜き出すBookmarkletのサンプルを作ったので、今回はもう一歩進んで外部のAPIを叩いてみるBookmarlketに仕上げます。
#使うもの
- javascript
- jQuery3
- Page speed api
jQueryでajax叩く方法は、こちらのページを参考にさせていただきました。
https://gist.github.com/kawa-/33d72748ce9b120c785f6f13b5b525b3
#作るもの
googleの検索結果ページの各ページの表示スピードをgoogle page speed apiで調べ、HTML内に結果を挿入するものです。
分かりにくいですが、73とか31がリアルタイムで計測したページスピードです。
##コード
全体
void((function(f){
var script = document.createElement('script');
script.src = '//code.jquery.com/jquery-3.2.1.min.js';
script.onload = function(){
var $ = jQuery.noConflict(true);
f($);
};
document.body.appendChild(script);
})(
function($, undefined){
count=0;
$('div.srg>div.g').each(function(i,e){
href=$(e).find('a[href]').first().attr('href');
score = $(e).find('div._score_');
if( score.length ){
console.log(score.text());
}else{
count++;
if( count>5 ){
console.log('break function');
return false;
}
console.log(count + '(' + i + ')' + href);
$.ajax({
type: "get",
url: "https://www.googleapis.com/pagespeedonline/v4/runPagespeed",
timeout: 20000,
cache: false,
data: {'url':href, 'strategy':'desktop'},
dataType: 'json'
})
.done(function (response, textStatus, jqXHR) {
console.log(response);
if (response.status === "err") {
console.error("err: " + response.msg);
} else {
score = response['ruleGroups']['SPEED']['score'];
console.log(href+'=>' + score);
$(e).prepend('<div class="_score_">'+score+'</div>');
}
})
.fail(function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR);
alert("失敗: サーバー内でエラーがあったか、サーバーから応答がありませんでした。");
})
.always(function (data_or_jqXHR, textStatus, jqXHR_or_errorThrown) {
// done,failを問わず、常に実行される処理
});
}
});
console.log('end function');
}
)
);
圧縮版
javascript:void function(b){var a=document.createElement("script");a.src="//code.jquery.com/jquery-3.2.1.min.js";a.onload=function(){var a=jQuery.noConflict(!0);b(a)};document.body.appendChild(a)}(function(b,a){count=0;b("div.srg>div.g").each(function(a,c){href=b(c).find("a[href]").first().attr("href");score=b(c).find("div._score_");if(score.length)console.log(score.text());else{count++;if(5<count)return console.log("break function"),!1;console.log(count+"("+a+")"+href);b.ajax({type:"get",url:"https://www.googleapis.com/pagespeedonline/v4/runPagespeed",
timeout:2E4,cache:!1,data:{url:href,strategy:"desktop"},dataType:"json"}).done(function(a,d,e){console.log(a);"err"===a.status?console.error("err: "+a.msg):(score=a.ruleGroups.SPEED.score,console.log(href+"=>"+score),b(c).prepend('<div class="_score_">'+score+"</div>"))}).fail(function(a,b,c){console.log(a);alert("\u5931\u6557: \u30b5\u30fc\u30d0\u30fc\u5185\u3067\u30a8\u30e9\u30fc\u304c\u3042\u3063\u305f\u304b\u3001\u30b5\u30fc\u30d0\u30fc\u304b\u3089\u5fdc\u7b54\u304c\u3042\u308a\u307e\u305b\u3093\u3067\u3057\u305f\u3002")}).always(function(a,
b,c){})}});console.log("end function")});
##解説1
HTML内から対象を探す部分
$('div.srg>div.g').each(function(i,e){
href=$(e).find('a[href]').first().attr('href');
- googleの検索結果ページから、
<div class="srg">
の下の<div class="g">
を探してきます。 - 上のパターンで複数見つかった要素にたいし、eachメソッドを実行し
- hrefを持つAタグの最初をやつのhrefの値を捕えます
##解説2
Bookmarkletの起動制御部分
Bookmarkletを何度も実行しても大丈夫なように、保険をかけておきます。
score = $(e).find('div._score_');
if( score.length ){
console.log(score.text());
}else{
count++;
if( count>5 ){
console.log('break function');
return false;
}
//(省略)
- 検索結果のかたまりから、
<div class="_score_">
を探す。これはgoogleの検索結果には含まれないタグなので基本的にはelseの処理をする。URLに対して2回目の実行の場合は、trueの処理に入る。 - 検索結果で出てくるURLの全部に対して同時にAPIを投げると怒られるケースがあるので、1回のBookmarkletで実行するのは5個までにしておきます。
##解説3
google のAPIを実行する部分
$.ajax({
type: "get",
url: "https://www.googleapis.com/pagespeedonline/v4/runPagespeed",
timeout: 20000,
cache: false,
data: {'url':href, 'strategy':'desktop'},
dataType: 'json'
})
APIを実行するコードはこれだけです。今回は、検索結果から取り出したURLとstrategy(PCのスピードを取るためのパラメータ)だけを渡しています。
Googleのpage speed apiのパラメータと戻り値は、こちらの資料にて調べられます。
https://developers.google.com/speed/docs/insights/v4/reference/pagespeedapi/runpagespeed
##解説4
APIの戻り値を使う部分
今回は、APIの戻り値からspeed scoreだけ取り出して、<div>
タグを埋め込んでいます。この結果を埋め込むことで、一度調べたURLに対してAPIを実行しないようにします。
.done(function (response, textStatus, jqXHR) {
console.log(response);
if (response.status === "err") {
console.error("err: " + response.msg);
} else {
score = response['ruleGroups']['SPEED']['score'];
console.log(href+'=>' + score);
$(e).prepend('<div class="_score_">'+score+'</div>');
}
})
コードは以上です。
#まとめ
こんな感じでブックマークレットを作ると、画面に表示されたHTMLを使ってAPIを投げて値を取ることができます。ページスピードを1つ1つ調べるようなお仕事が存在するとすれば、ブラウザにボタンを設定して押すだけで良くなります。
ブックマークレットは、スタート地点のHTMLの構造が変わるとうまく動かなくなりますが、社内のwikiページを起点とするような形にすれば、対象のURLを増やすのも簡単ですし、不意に形が変わって動かなくなることも少なくできるとは思います。
覚える技術要素はそんなに多くないですし、テスト的に試してみる環境を整えるハードルも低いので、いろいろ試してみるとよいです。