Edited at

Bookmarkletを作ろう(ajax編)

More than 1 year has passed since last update.

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');


  1. googleの検索結果ページから、<div class="srg">の下の<div class="g">を探してきます。

  2. 上のパターンで複数見つかった要素にたいし、eachメソッドを実行し

  3. 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;
}
//(省略)


  1. 検索結果のかたまりから、<div class="_score_">を探す。これはgoogleの検索結果には含まれないタグなので基本的にはelseの処理をする。URLに対して2回目の実行の場合は、trueの処理に入る。

  2. 検索結果で出てくる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を増やすのも簡単ですし、不意に形が変わって動かなくなることも少なくできるとは思います。

覚える技術要素はそんなに多くないですし、テスト的に試してみる環境を整えるハードルも低いので、いろいろ試してみるとよいです。