検索結果が1000件を超えた時
先日たまたま、「ブログ」の検索語で「ブログ内検索」をすると、「END」ボタンの動作が正常でない事に気付きました。 検索結果が1000件を超えていて、これが関係していました。
1000件を超えるヒットは少なく問題に気付かなかったのですが、1000件以上の記事があるユーザーなら、「。」(句読点)の検索で状況が再現できると思います。
「END」ボタンの機能
「次の10件」「前の10件」のボタンは、隣のページに移動するだけで、「ページ番号」のボタンで代用できます。 その「ページ番号」ボタンは、4~5ページの移動がせいぜいです。 記事のリストは投稿日順にソートされています。 もし、探している記事がブログ初期の記事と判っている時は、リストの末尾から探した方が早いわけです。
そこで、不要な「次の10件」「前の10件」のボタンを「TOP」「END」に変えて、早い移動を可能にしています。
ページ移動は、クエリ文字列にページ数を指定して移動できます。「TOP」は「1ページ」を指定するだけで簡単ですが、❶「END」は検索のヒット件数で変化します。
そこで、上図の ❷の検索ヒットの表示から、リストのページ数を計算しています。 これは上手く行くのですが、1000件以上は想定していなかったわけです。
1000件(100ページ)以上は表示しない仕様
調べると「101ページ」以降はリストを表示しない仕様です。「100ページ」も遡るユーザーはいないだろうという事でしょう。 しかし、これは今回の問題の直接の原因ではありませんでした。
原因は、ページ計算に使っていた表示が「カンマ付き表示」だったからです。
上の様に、ヒット件数が「1052」ではなく「1,052」になっています。 ヒット件数を取得するコードは、文字列中で数を表す文字列の最初のみを取得するコードですが、カンマが入ったために「1」を取得していました。
ここの処理は、最初に「カンマ」を削除してから処理すれば、正しく対応できます。 その上で、1000件(100ページ)以上の場合は、「END」を押すと「100」ページ目を表示する様に修正しました。(101ページはエラーになるので)
今回の「ver 2.4」の 255行からの以下の部分が、修正したコードです。
ページのCSS適用を高速化
「with CSS」版では「CSS適用」の高速化をしていましたが、こちらのバージョンは「CSS適用」を「Stylus」に頼るため高速化をしていませんでした。 しかし、リロード時が余り美しくなく、これは「Ameba Search Repeat」の「CSS」適用の遅れが目立ちます。 今回は、少し適用タイミングを調整しました。
ヘルプ とツールチップ
「ヘルプ」ボタンの設置は、各種のツールで進めている事です。 制作する側は当然に思っている事が、初めてツールを扱うユーザーにとって「謎仕様」という事が、想像以上に多いかも知れません。 これは、判り易い「マニュアル」を作り、操作のポイントを理解してもらうしかなく、「ヘルプ」ボタンで「マニュアル」のページを表示するのは、悪くない方法と思っています。
今回、このツールも ❸「ヘルプ」ボタンを設置しました。 また、❹「ツールチップ」の説明も、より判り易い内容に改めました。
「ヘルプ」ボタンは以下の「マニュアル」ページのリンクになっています。
「Ameba Search Repeat」を利用するには
❶ 拡張機能「Stylus」の導入
「Ameba Search Repeat」は「Ameblo Management」「Ameblo Neo Search」の検索画面のアレンジを前提にしています。 これらのスタイルは、使用ブラウザに対応した拡張機能「Stylus」の導入が必要です。 既に「Stylus」を導入されている場合は、この ❶の手順は不要です。
「Stylus」の導入手順や扱い方については、以下のリンク先の記事の中から、使用しているブラウザに関する記事を参照ください。
拡張機能「Stylus」の Chrome・Edge版 / Firefox版 の入手先は以下です。 使用しているブラウザに適合する版を導入してください。
❷「Ameblo Management」「Ameblo Neo Search」の入手
「Stylus」の導入後に、以下のリンク先ページで2個のスタイルを入手してください。インストールは、スタイルのサンプル画像下の install のボタンを押します。
「Stylus」の編集画面の様な画面が表示されますが、左上の「インストール{S}」のボタンをもう一度押します。 これでインストールが完了します。
◎既にこれらのスタイルを利用されている場合は、スタイルのアップデートをお勧めします。「Stylus」の管理画面で上記スタイルのスタイル名欄の「 」アイコンをクリックすると、スタイルのアップデートが簡単に出来ます。
◎「Ameblo Management」をインストールすると、「ホーム画面」「各種管理画面」「ブログページ」「画像一覧ページ」等、アメーバブログの各種画面のデザインが強力にアレンジされます。 これが困る場合は、以下の回避方法があります。
①「Stylus」の管理画面で「Ameblo Management」を通常はOFFとし、「Ameba Search Repeat」の使用時のみONにする。
➁ 上記 ❶❷ の導入をせず、「Ameba Search Repeat / with CSS」を導入する。
❸ 拡張機能「Tampermonkey」の導入
◎ 使用しているブラウザに拡張機能「Tampermonkey」を導入する事が必要です。
既に「Tampermonkey」を導入している場合は、この手順 ❸ は不要です。
拡張機能の導入については、以下のページに簡単な説明があるので参照ください。
❹「Tampermonkey」にスクリプトを登録します
◎「Tampermonkey」の「+」マークの「新規スクリプト」タブを開きます。
◎「新規スクリプト」には、最初からテンプレートが記入されています。 これは全て削除して、完全に空白の編集枠に 下のコードをコピー&ペーストします。
〔コピー方法〕 右サイドバーの マークのボタンを1度押してください。
コード枠内の右クリック ➔ コード全体の選択 ➔ コピー操作 が可能になります。
◎ 最後に「ファイル」メニューの「保存」を押すと、ツールが使用可能になります。
〔 Ameba Search Repeat 〕 ver. 2.4
// ==UserScript== // @name Ameba Search Repeat // @namespace http://tampermonkey.net/ // @version 2.4 // @description ブログ内検索の再検索を実行可能にする // @author Ameba Blog User // @match https://search.ameba.jp/search/entry/*.html?aid=* // @run-at document-start // @grant none // ==/UserScript== let edit_mode=0; // リストを常に再編集で開くモード in_view(); // ページにCSSを適用 window.addEventListener('load', function(){ let target=document.body; // 監視 target let monitor=new MutationObserver(check_page); monitor.observe(target, {childList: true}); // 検索待受け開始 check_page(); function check_page(){ if(location.search.startsWith('?aid=')){ search_next(); } else{ if(document.head.querySelector('.sih')){ document.head.querySelector('.sih').remove(); }}}}); function search_next(){ // 検索結果ページごとにURLは更新される let blogDB={}; // 閲覧記事のID/チェックフラグの記録配列 let entry_id_DB; // ID検索用の配列 let read_json=localStorage.getItem('ASR_DB_back'); // ローカルストレージ 保存名 blogDB=JSON.parse(read_json); if(blogDB==null){ blogDB=[['ASR00000000', '0']]; } if(blogDB[0][0]=='ASR00000001'){ // ストレージのフラグで edit_mode が「1」 edit_mode=1; } if(get_userid(0) !=null){ blogDB[0][1]=get_userid(0); } // スクリプト起動時に開いたユーザーIDを記録 let write_json=JSON.stringify(blogDB); localStorage.setItem('ASR_DB_back', write_json); // ローカルストレージ 保存 reg_set(); function reg_set(){ let k; entry_id_DB=[]; // リセット for(k=0; k<blogDB.length; k++){ entry_id_DB[k]=blogDB[k][0]; }} // ID検索用の配列を作成 list_set(); function list_set(){ let entrylist=[]; let entrylink=[]; let entryhref=[]; let history=[]; entrylist=document.querySelectorAll('.PcEntryListItem'); for(let k=0; k<entrylist.length; k++){ entrylink[k]=entrylist[k].querySelector('.PcEntryListItem >a'); entryhref[k]=entrylink[k].getAttribute('href').slice(-16, -5); mark(k); list_listen(k); hmark_listen(k); } function mark(k){ let history_='<p class="history">\u00A0</p>'; if(entrylink[k].querySelector('.history')){ entrylink[k].querySelector('.history').remove(); } entrylink[k].insertAdjacentHTML('beforeend', history_); history[k]=entrylink[k].querySelector('.history'); let list_size=entrylink[k].getBoundingClientRect().height; let img_size=entrylist[k].querySelector('.UserThumbnail').getBoundingClientRect().height; let top=(list_size + img_size)/2 - 6; history[k].style.top=top + 'px'; // サムネイルとリストの上下間にマークを配置 let index=entry_id_DB.indexOf(entryhref[k]); if(index !=-1){ if(blogDB[index][1]==1){ history[k].style.background='#009688'; } // フラグ1ならグリーン else if(blogDB[index][1]==2){ history[k].style.background='#ff8800'; } // フラグ2ならオレンジ else if(blogDB[index][1]==0){ history[k].style.background='#fff'; }}} // フラグ0なら白 function list_listen(k){ entrylink[k].addEventListener('click', function(event){ event.preventDefault(); event.stopImmediatePropagation(); all_click(); if(edit_mode==0){ // 別タブに記事画面を開く let pass=entrylink[k].getAttribute('href'); window.open(pass, "_blank"); } if(edit_mode==1){ // 別タブに再編集画面を開く let pass= 'https://blog.ameba.jp/ucs/entry/srventryupdateinput.do?id='+entryhref[k]; window.open(pass, "_blank"); }}, false); entrylink[k].addEventListener('contextmenu', function(){ all_click(); }, false); function all_click(){ let index=entry_id_DB.indexOf(entryhref[k]); if(index==-1){ blogDB.push([entryhref[k], 1]); } // 閲覧履歴に記事ID/フラグ1を追加 else{ blogDB[index]=[entryhref[k], 1]; } // この記事IDの履歴をフラグ1に更新 let histo=document.querySelectorAll('.history'); histo[k].style.background='#009688'; let write_json=JSON.stringify(blogDB); localStorage.setItem('ASR_DB_back', write_json); // ストレージ保存 reg_set(); }} function hmark_listen(k){ history[k].addEventListener('click', function(event){ event.preventDefault(); event.stopImmediatePropagation(); let index=entry_id_DB.indexOf(entryhref[k]); if(index==-1){ blogDB.push([entryhref[k], 1]); // 閲覧履歴に記事ID/フラグ1を追加 history[k].style.background='#009688'; } // グリーン else{ if(blogDB[index][1]==1){ blogDB[index]=[entryhref[k], 2]; // この記事IDの履歴をフラグ2に更新 history[k].style.background='#ff8800'; } // オレンジ(Noteフラグ) else if(blogDB[index][1]==2){ blogDB[index]=[entryhref[k], 0]; // この記事IDの履歴をフラグ0に更新 history[k].style.background='#fff'; } // 白(履歴のフラグをリセット) else if(blogDB[index][1]==0){ blogDB[index]=[entryhref[k], 1]; // この記事IDの履歴をフラグ1に更新 history[k].style.background='#009688'; }} // グリーン let write_json=JSON.stringify(blogDB); localStorage.setItem('ASR_DB_back', write_json); // ストレージ保存 reg_set(); }, false); } } // list_set() reset_sw(); function reset_sw(){ let box=document.querySelector('.PcResultPagination'); if(box){ let sw_= '<p id="history_reset">Reset</p>'+ '<p id="sw_tooltip2">全記事の履歴マークをリセットします</p>'; if(!box.querySelector('#history_reset')){ box.insertAdjacentHTML('beforeend', sw_); } let history_reset=box.querySelector('#history_reset'); if(history_reset){ history_reset.onclick=function(){ let conf_str='🟩 リストの履歴マーク(閲覧/編集)をリセットします'; let ok=confirm(conf_str); if(ok){ if(edit_mode==0){ blogDB=[['ASR00000000', blogDB[0][1]]]; } if(edit_mode==1){ blogDB=[['ASR00000001', blogDB[0][1]]]; } let write_json=JSON.stringify(blogDB); localStorage.setItem('ASR_DB_back', write_json); // ストレージ保存 reg_set(); list_set(); }}}}} edit_sw(); function edit_sw(){ let box=document.querySelector('.PcResultPagination'); if(box){ let sw_= '<p id="edit"></p>'+ '<p id="sw_tooltip3">記事のクリックで開く画面 Read: ブログ画面 Edit: 編集画面</p>'; if(!box.querySelector('#edit')){ box.insertAdjacentHTML('beforeend', sw_); } let edit=box.querySelector('#edit') if(edit){ if(edit_mode==0){ edit.textContent='Read'; edit.style.background='#72adc8'; } else if(edit_mode==1){ edit.textContent='Edit'; edit.style.background='red'; } edit.onclick=function(){ let read_json=localStorage.getItem('ASR_DB_back'); // ローカルストレージ 保存名 blogDB=JSON.parse(read_json); if(edit_mode==0){ edit.textContent='Edit'; edit.style.background='red'; edit_mode=1; blogDB[0][0]='ASR00000001'; } // edit_mode 「1」のフラグ else if(edit_mode==1){ edit.textContent='Read'; edit.style.background='#72adc8'; edit_mode=0; blogDB[0][0]='ASR00000000'; } let write_json=JSON.stringify(blogDB); localStorage.setItem('ASR_DB_back', write_json); // ストレージ保存 reg_set(); list_set(); }}}} jump_sw(); function jump_sw(){ let more_l; let more_r; let more_link=document.querySelectorAll('.PcResultPagination_MoreLink'); if(more_link.length!=0){ if(more_link[0].querySelector('.s-triangle-left')){ more_l=more_link[0]; } if(more_link[0].querySelector('.s-triangle-right')){ more_r=more_link[0]; } if(more_link[1]){ if(more_link[1].querySelector('.s-triangle-right')){ more_l=more_link[0]; more_r=more_link[1]; }}} let hit_str=document.querySelector('.PcEntryList .PcHitCountRange'); if(hit_str){ let q_str=window.location.search.split('&')[0]; if(more_l){ let more_lavel=more_l.querySelector('.PcResultPagination_MoveLabel'); more_lavel.textContent='TOP'; more_l.style.display='block'; let jump_url=window.location.href.split('?')[0] + q_str + '&p=1'; more_l.onclick=function(e){ event.preventDefault(); location.href=jump_url; }} if(more_r){ let more_lavel=more_r.querySelector('.PcResultPagination_MoveLabel'); more_lavel.textContent='END'; more_r.style.display='block'; let hit=hit_str.textContent.replace(/,/g, '').match(/\d+/); let end=Math.ceil(hit/10); if(end>100){ end=100; } // 100以上は表示できない仕様 end=end.toString(); let jump_url=window.location.href.split('?')[0] + q_str + '&p=' + end; more_r.onclick=function(e){ event.preventDefault(); location.href=jump_url; }}}} back_sw(); function back_sw(){ let box=document.querySelector('.PcNavigationSearch'); if(box){ let help= '<p id="asr_help">?</p>'; if(!box.querySelector('#asr_help')){ box.insertAdjacentHTML('afterbegin', help); } let sw_= '<p id="back_blog">⏏</p>'+ '<p id="sw_tooltip">ブログTOPへ</p>'; if(!box.querySelector('#back_blog')){ box.insertAdjacentHTML('beforeend', sw_); } let asr_help=box.querySelector('#asr_help'); asr_help.onclick=function(){ let url='https://ameblo.jp/personwritep/entry-12758463897.html'; window.open(url, '_blank'); } let back_blog=box.querySelector('#back_blog'); back_blog.onclick=function(){ location.href='https://ameblo.jp/' + blogDB[0][1]; }}} let user_id=get_userid(1); if(user_id){ let search_box_react=document.querySelector('#react-autowhatever-1'); if(search_box_react){ search_box_react.remove(); } let search_button=document.querySelector('.PcSearchForm_Button'); search_button.addEventListener('click', function(e){ let input_box=document.querySelector('.PcSuggestForm_Input').value if(input_box!=''){ location.href='https://search.ameba.jp/search/entry/' + input_box + user_id; } e.preventDefault(); e.stopPropagation(); }, false); } function get_userid(n){ let this_url=location.href; let index_after=this_url.indexOf('.html?aid='); let caption=document.querySelector('.PcEntryList_Caption'); if(index_after==-1){ // ブログ内検索から出た時 何もしない if(caption){ caption.textContent='ブログ記事'; caption.style.color='#298538'; caption.style.background='transparent'; }} else{ if(caption){ caption.textContent='ブログ内検索'; caption.style.color='#fff'; caption.style.background='#2196f3'; } let user_id_a=this_url.slice(index_after); let index_before=user_id_a.indexOf('&p='); let user_id; if(index_before==-1){ user_id=user_id_a; } else{ user_id=user_id_a.substring(0, index_before); } if(n==1){ return user_id; } else if(n==0){ user_id=user_id.replace('.html?aid=', ''); return user_id; }}} } // search_next function in_view(){ let style= '<style class="sty0">'+ '.PcNavigationSearch { position: relative; }'+ '.AmebaLogo { width: 100px; }'+ '.PcNavigationSearch_Logo > img { width: 36px; }'+ '.PcSearchForm_Button { width: 80px; }'+ '#asr_help { position: absolute; top: 12px; left: -35px; '+ 'font: bold 16px/21px Meiryo; height: 17px; padding: 1px 2px 2px 3px; '+ 'color: #fff; border-radius: 30px; background: #666; cursor: pointer; }'+ '#back_blog { font-size: 24px; padding: 4px; margin-left: 20px; cursor: pointer; '+ 'border: 1px solid #fff; border-radius: 6px; color: #fff; background: #2196f3; }'+ '#sw_tooltip { position: relative; left: -165px; white-space: nowrap; '+ 'font-size: 14px; padding: 4px 10px 0; border: 1px solid #ccc; background: #fff; '+ 'box-shadow: 4px 4px 6px rgba(0, 0, 0, 0.5); display: none; }'+ '#back_blog:hover + #sw_tooltip { display: block; }'+ '.PcEntryList_Caption { padding: 5px 10px 2px !important; '+ 'margin: 0 10px 6px 0 !important; }'+ '.PcResultPagination { position: relative; padding: 0 0 4px 140px !important; }'+ '.PcResultPagination_MoreLink { font-weight: bold; display: none }'+ '.PcEntryListItem_Link { position: relative; height: 75px; }'+ '#history_reset { position: absolute; left: 0; padding: 2px 6px 0; cursor: pointer; '+ 'color: #fff; border: 1px solid #fff; border-radius: 4px; background: #009688; }'+ '#edit { position: absolute; left: 70px; padding: 2px 6px 0; cursor: pointer; '+ 'color: #fff; border: 1px solid #fff; border-radius: 4px; background: #72adc8; }'+ '#sw_tooltip2, #sw_tooltip3 { position: absolute; top: -39px; left: 0; z-index: 2; '+ 'font-size: 14px; padding: 5px 10px 2px; border: 1px solid #ccc; '+ 'background: #fff; box-shadow: 4px 4px 6px rgba(0, 0, 0, 0.5); display: none; }'+ '#history_reset:hover + #sw_tooltip2 { display: block; }'+ '#edit:hover + #sw_tooltip3 { display: block; }'+ '.PcEntryListItem_Link::before { display: none; }'+ '.history { position: absolute; left: 10px; border: thin solid #ccc; '+ 'width: 14px; height: 14px; background: #fff; border-radius: 4px; }'+ '</style>'; if(!document.querySelector('.sty0')){ document.documentElement.insertAdjacentHTML('beforeend', style); }}
〔追記〕「Ameblo Neo Search」のアップデートに関して
今回の「Ameba Search Repeat」ver. 2.4 の更新で、リストページのリロード時の表示の乱れを改善を図りました。「Ameblo Neo Search」のCSSコードも、この改善に関連し、一部ですがコードを更新しています。 既にご利用の方は、「Stylus」の管理画面で、「Ameblo Neo Search」のアップデートをお願いいたします。
「Ameba Search Repeat」最新版について
旧いバージョンの JavaScriptツールは、アメーバのページ構成の変更で動作しない場合があり、導入する場合は最新バージョンをお勧めします。
●「Ameba Search Repeat」の最新バージョンへのリンクは、以下のページのリンクリストから探せます。