「 Ajax」とは

いまいち良く判ってないので、Webで調べると以下の説明がありました。

 

Ajaxは何に使うのか?

JavaScriptでHTMLやXMLで記述された要素を参照・操作する際に使用される 

 

この機能は、とにかく素早くページ構成のデータを取り寄せる事に長けている様で、「集まったメンツだけで直ぐにゲームを始める」といった感じで、ウェブページを要領よく展開・運営するのにとても有効な通信機能と言えそうです。

 

ブログページは、ページャーでページを移動しますが、移動時に書き換わるのは本文等のページの一部分で、この差し換え操作も Ajaxで効率よく行っている様です。

 

 

 

「ツール一覧表」について

私のブログでは、スクリプトツールの最新版がすぐ見つけられる様に、最新版のページがすぐに判る一覧表を作っています。 下がそのページです。

 

 

この一覧表は、各ツールの行ごとに「最新版のページへのリンク」と「纏めページへのリンク」の2個のリンク(a要素)を並べています。

 

 

 

「纏めページ」は、機能の種類でスクリプトツールを分類して、説明も少しを加えているので、全てのツールを纏めるのに8ページ位になり、さっと一覧と言う事が出来ません。 そのために、この一覧表のページを作ったのです。

 

従って、現在はこの一覧表のページが、全ツールの交通案内の中軸になっています。

 

また、既に「一覧表のページ」は文字数限界になっていて、余り一般的でないツールは、次の追補ページに表を分けています。

 

 

 

 

「ツール一覧表」の更新日付データの取得  

この一覧表で、各ツールの最終更新日付があれば、ツール陳旧化を読みとる助けになり、アップデート漏れのチェックも使えそうです。 現在の一覧表は迂闊に書換えができないので、一覧表の複製を作って改装してみることにしました。

 

ただ、表に列を追加すると、確実に文字数オーバーになるので、「纏めページへのリンク」の列を、最終更新日付に変更することにしました。

 

さて、各行にはツールの最新ページのリンクがありますが、そのページの投稿日付は、リンク先のページを開いて、調べないと判りません。

 

ここで、最初の書いた「Ajax」が必要になりました。 Webページの部分的な差換えとは使用目的が違いますが、この一覧表のブログページ上で動作する JavaScriptで、各ツールの最新ページのデータを収集する事に使うわけです。

 

 

データ調査のエンジン 

下は、調査する「url」と、そこで得たデータを収める配列のインデックス「n」を指定して、動作する関数です。

 

function ajaxInspect(n, url){ // XMLHttpRequestを使ってデータを取得
    url=url+'?ver='+new Date().getTime(); // キャッシュを抑止して取得
    let ajax=new XMLHttpRequest;
    ajax.open('GET', url, true);

    ajax.onload=function(){ // データ取得時の操作
        let tmp_='<div id="tmp_div" style="display: none"></div>';
        if(!document.querySelector('#tmp_div')){
            document.body.insertAdjacentHTML('beforeend', tmp_); }

        let tmp=document.querySelector('#tmp_div');
        if(tmp){
            tmp.innerHTML=ajax.responseText; // 取得データをtmpに展開
            let elem=tmp.querySelector('script[type="application/ld+json"]');
            if(elem){
                let elem_data=elem.textContent;
                let data=elem_data.split(',');
                let pub_data=data.filter(function(data_text){
                    return data_text.includes('datePublished'); });

                if(pub_data){
                    let pub_date=pub_data.toString().replace(/[^0-9]/g, '').substr(0, 8);
                    pub_date=
                        pub_date.substr(0, 4) +'-'+ pub_date.substr(4, 2) +'-'+ pub_date.substr(6, 2);
                    date_all[n]=pub_date; }}}

        tmp.innerHTML=''; } // 取得データを削除
    ajax.send(null); }

 

最初に、「ajax」を使って「url」先を開く指定をしています。 次に「#tmp_div」という非表示の「div要素」を作っておき、「url」先のデータをそっくりそこへ展開しています。

 

この時に展開されるデータは、実際にページ表示に必要なデータより、色々と間引かれている様です。 画像などは、ページを表示する際に画像サーバーから読み出すので、このデータには乗っていないと思います。

 

目的ページのデータを展開し、そこでブログページの「投稿日付」を取得したかったのですが、これは予想外な問題がありました。 本文等はちゃんとあるのに、日付の表示枠だけで、実際の日付データは無いのです。 どうやら、これはページ表示時に、後からインポーズされるデータらしい。

 

 

 

そこで、「head要素」を探すと「type="application/ld+json"」属性の「script」に、記事データ等が収められている事が判りました。 下は実際の例です。

 

<script type="application/ld+json" data-react-helmet="true">{
"@context":"http://schema.org",
"@type":"BlogPosting",
"mainEntityOfPage":{"@type":"WebPage","@id":"https://ameblo.jp/personwritep/entry-12832760747.html"},
"headline":"「Abema TV」専用の閲覧ツール「AmbTV Comfy」(23)/ JavaScript",
"datePublished":"2023-12-18T07:20:00.000+09:00",
"dateModified":"2023-12-18T07:20:00.000+09:00",
"author":{"@type":"Person","name":"personwritep"},
"publisher":{"@type":"Organization","name":"Ameba","logo":{"@type":"ImageObject","url":"https://stat100.ameba.jp/ameblo/pc/img/amebloJp/abema_logo.png","width":600,"height":32}},
"image":{"@type":"ImageObject","url":"https://stat.ameba.jp/user_images/20231216/16/personwritep/27/c0/p/o1135091515377665420.png","width":1135,"height":915}}
</script>

 

この「script」は全ての記事にあるらしく、上の赤字のデータを取り出せば、投稿日付を取得できます。

 

調査エンジンのコードのブルーのコードは、取得したデータの「script」要素をとり出し、その中の「datePublished":"2023-12-18T07:~」のデータを抜き出して、そこから「2023-12-18」の文字列を得ています。

 

最後に、それを配列「date_all」に入れて、1件の調査が終了です。

 

これを一覧表に表示した約80件のスクリプトごとに行いますが、実際は1secもかからない様です。( Ajaxは早さが命です)

 

80件のツールのページの投稿日付は、配列「date_all」に納めたので、これをファイルに出力するコードを追加しました。

 

出来たツール名は「JSTools Updatelog」で、自分のためのツールなので、シンプルなインターフェイスです。

 

このツールを「ON」にして「ツール一覧表」のあるページを開くと、自動的に投稿日付のデータ収集を実行します。 余裕を持たせて 4sec後に、結果をファイル出力するかをダイアログで問い、「OK」ならダウンロードファイルとして、日付データの配列を出力します。

 

ダウンロードファイルはメモ帳で開く事ができ、下の様な日付けの配列になります。

 

["2023-12-18","2023-12-14","2023-07-03","2022-03-03", ……]

 

 

 

一覧表に投稿日付データ書き込む 

「JSTools Updatelog」で得られるのは、最新の更新日付の配列です。 これを表に書き写すのは手間です。 そこで、配列を自動的に一覧表の書き込むツールを作りました。 ツール名は「JSTools Date Writer」としました。

 

こちらは編集画面で動作しますが、特別に複雑な点はありません。 一覧表の各行で、右端の列を、配列の日付に置換えるだけです。 コードのインターフェイスを簡単にするために、配列を読込むコードは省略し、コードに直接配列のデータを書き込んでから、編集画面を開いて処理を実行します。

 

編集画面に一覧表のページを開いたら、「Ctrl+Shift+F10」のショートカットを押すと、配列のデータが書込まれます。 結果がよければ、一覧表を保存します。

 

 

書込んだ様子 

「JSTools Updatelog」と「JSTools Date Writer」を使って、一覧表に更新日付の表示列を追加しました。

 

 

 

 

 

「JSTools Updatelog / JSTools Date Writer」について

以下のツールは Chrome / Edge版の拡張機能「Tampermonkey」上で動作します。

 

これらのツールは「ツール一覧表」を配したページでの動作を前提としているので、一般のページで起動させると正常な動作は期待できません。 あくまで、参考のためにコードを掲載しています。

 

 

〔 JSTools Updatelog 〕 ver. 0.1

 

// ==UserScript==
// @name         JSTools Updatelog
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description   「スクリプトツール一覧表」の各ツールの最終アップデート日付を取得
// @author       AmebaBlogUser
// @match        https://ameblo.jp/*
// @noframes
// @icon         https://www.google.com/s2/favicons?sz=64&domain=ameba.jp
// @grant        none
// ==/UserScript==

let date_all=[];

let links=document.querySelectorAll('#entryBody #ambt0 td:first-child a');

for(let k=0; k<links.length; k++){
    let url=links[k].getAttribute('href');
    ajaxInspect(k, url); }



function ajaxInspect(n, url){ // XMLHttpRequestを使ってデータを取得
    url=url+'?ver='+new Date().getTime(); // キャッシュを抑止して取得
    let ajax=new XMLHttpRequest;
    ajax.open('GET', url, true);
    let pub_date;

    ajax.onload=function(){ // データ取得時の操作
        let tmp_='<div id="tmp_div" style="display: none"></div>';
        if(!document.querySelector('#tmp_div')){
            document.body.insertAdjacentHTML('beforeend', tmp_); }

        let tmp=document.querySelector('#tmp_div');
        if(tmp){
            tmp.innerHTML=ajax.responseText; // 取得データをtmpに展開
            let elem=tmp.querySelector('script[type="application/ld+json"]');
            if(elem){
                let elem_data=elem.textContent;
                let data=elem_data.split(',');
                let pub_data=data.filter(function(data_text){
                    return data_text.includes('datePublished'); });

                if(pub_data){
                    pub_date=pub_data.toString().replace(/[^0-9]/g, '').substr(0, 8);
                    pub_date=
                        pub_date.substr(0, 4) +'-'+ pub_date.substr(4, 2) +'-'+ pub_date.substr(6, 2);
                    date_all[n]=pub_date; }}}

        tmp.innerHTML=''; } // 取得データを削除

    ajax.send(null); }



setTimeout(()=>{

    let ok=confirm('💢 日付データをファイル出力しますか? 💢');
    if(ok){
        output(); }

}, 4000);

function output(){
    let write_json=JSON.stringify(date_all);
    let blob=new Blob([write_json], {type: 'application/json'});
    try{
        let a_elem=document.createElement('a');
        a_elem.href=URL.createObjectURL(blob);
        document.body.appendChild(a_elem);
        a_elem.download='js_tools_date.json'; // 保存ファイル名
        a_elem.click();
        URL.revokeObjectURL(a_elem.href);
        alert("✅  ファイルを保存しました\n"+
              "  ダウンロードフォルダーを確認してください"); }
    catch(e){
        alert("❌ ファイル保存時にエラーが発生しました\n"+
              "  ダウンロードフォルダーを確認してください"); }}


 

 

 

〔 JSTools Date Writer 〕 ver.0.1

 

// ==UserScript==
// @name          JSTools Date Writer
// @namespace  http://tampermonkey.net/
// @version      0.1
// @description  「スクリプトツール一覧表」に更新日付データを記入「Ctrl+Shift+F10」
// @author       Ameba Blog User
// @match        https://blog.ameba.jp/ucs/entry/srventry*
// @exclude      https://blog.ameba.jp/ucs/entry/srventrylist.do*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=ameba.jp
// @grant         none
// ==/UserScript==


let date_all=[]; // 一覧表の日付データの配列

let retry=0;
let interval=setInterval(wait_target, 100);
function wait_target(){
    retry++;
    if(retry>10){ // リトライ制限 10回 1sec
        clearInterval(interval); }
    let target=document.getElementById('cke_1_contents'); // 監視 target
    if(target){
        clearInterval(interval);
        main(); }}



function main(){
    let editor_iframe;
    let iframe_doc;

    let target=document.getElementById('cke_1_contents'); // 監視 target
    let monitor=new MutationObserver(catch_key);
    monitor.observe(target, {childList: true}); // ショートカット待受け開始

    catch_key();

    function catch_key(){
        editor_iframe=document.querySelector('.cke_wysiwyg_frame');
        if(editor_iframe){ // iframe がある「通常表示」の場合
            iframe_doc=editor_iframe.contentWindow.document;
            if(iframe_doc){
                iframe_doc.addEventListener("keyup", check_key); }

            function check_key(event){
                if(event.ctrlKey && event.shiftKey && event.keyCode==121){ //「Ctrl+Shift+F10」処理
                    event.preventDefault();
                    setTimeout(()=>{
                        write_table(); }, 100); } }
        } //「通常表示」の場合
        else{
        } //「HTML表示」の場合

    } // catch_key




    function write_table(){
        let links=iframe_doc.querySelectorAll('#ambt0 td:first-child a');

        if(links.length==date_all.length){ // 表データ数と日付データ数の一致を確認

            for(let k=0; k<links.length; k++){
                let table_tr=links[k].closest('tr');
                let target_td=table_tr.querySelector('td:last-child');
                if(target_td){
                    target_td.textContent=date_all[k]; }}

        }} // write_in()

} // main()




date_all=[
    "2021-11-02","2023-09-09","2023-11-15","2021-08-17","2023-12-15","2023-04-15",
    "2023-12-17","2023-12-22"]




/*
date_all=[
    "2023-12-18","2023-12-14","2023-07-03","2022-03-03","2022-08-25","2022-08-25",
    "2023-12-30","2022-04-19","2023-10-28","2023-08-23","2022-10-11","2023-10-27",
    "2021-03-14","2023-12-25","2023-05-31","2023-10-13","2022-09-16","2023-01-24",
    "2022-09-23","2022-07-27","2023-12-08","2019-12-25","2023-10-24","2023-08-02",
    "2023-08-05","2022-11-03","2022-11-04","2023-11-29","2023-05-20","2020-05-23",
    "2022-09-28","2023-12-20","2023-12-21","2023-12-04","2023-07-09","2023-08-25",
    "2023-08-25","2023-08-25","2023-08-25","2023-08-25","2023-08-25","2023-08-25",
    "2023-12-02","2023-12-02","2023-09-20","2023-09-16","2023-11-01","2023-03-31",
    "2021-08-23","2022-05-29","2023-11-03","2023-10-05","2022-07-21","2023-09-03",
    "2022-11-19","2022-11-21","2021-12-22","2023-02-24","2023-09-07","2022-09-06",
    "2023-12-31","2023-10-11","2023-12-15","2022-04-04","2023-11-14","2023-11-27",
    "2023-11-26","2023-10-10","2023-03-29","2023-08-26","2023-08-26","2023-07-26",
    "2023-10-23","2023-04-10","2023-04-12","2023-04-12","2021-01-28","2021-09-26",
    "2023-09-13"]
*/