はじめに
プログラミングしていると、よく、alert()が数秒後には、自動消去してくれたらいいと思う場面がよくあります。毎回、OKボタンを押さなければならないというのが面倒です。そこで、サンプルをつくりました。これはプラグイン形式ですが、自分のwebページであれば、ページのスクリプトでも移植可能です。
プラグインにしているのは、stampTubeプラグインで、すべてのwebページでも動作テストしたかったからです。プラグインであれば、yahooページでも、アメバページでも動作確認できます。
このstampTubeプラグインは、yoytubeの動画を再生するプラグインです。
では、このサンプルがどう動作するのかについて、以降で、サンプルで説明します。
その前に、プラグインをダウンロードするリンクを以下に示します。
ダウンロードリンク
stampTubeプラグイン
インストール方法
ここをクリックして、パソコンの任意のフォルダーへzipファイルを保存します。そこで、zipファイルを任意のフォルダーへ解凍します。chromeの設定で拡張機能->拡張機能を管理->パッケージ化されていない拡張機能を読み込むボタンをクリックして、解凍したフォルダーを指定してフォルダーの選択を押すとインストールできます。
動作サンプル
この画面は、yahoo!JAPANページで、ctrlキー+clickすると表示されます。(stampTubeプラグインがインストールされていること)
画面の右上にpop画面が表示されます。
ここで、alert()もどきのalertX()をテストするため、ランダムボタンを改良しています。このボタンをクリックすると、popメッセージがalert()のようなイメージで表示されます。自動消去して、タイマーで数秒後に次のalertX()を表示しています。
薄緑色のpop表示がaletX()で表示したメッセージです。このメッセージが数秒後に自動消去します。続けて次のメッセージも表示され、数秒後に消去します。
alertX()の自動消去のイメージがつかめると思います。
このように、alert()のようなメッセージを自動消去するメソッドです。このメソッドはwindow.alertX()で呼び出しています。alertX()はwindowに追加したものです。
stampTubeプラグインのコード
このコードはサンプルのコードですが、youtuve動画は動作します。(コードはダーティです。)
参照するコードはalertX部分のところを見てください。
/******************************************************************************
*表題: stampTubeプラグイン
*プラグイン: このプラグインは、すべてのタブで動作する小型のyoutubeプレーヤーです。
* iframeでサイトのurlをロードし再生します。
* url=https://favorite.tecoyan.net/slim/index_radio_simple.php
*このドメインであれば、すべてのWebサイトのタブで動作します。same origin制約で許可されています。
*
*ファイル名: content.js
*説明: すべてのタブで動作するcontent.jsファイルです。このスクリプトでbody要素に
* iframeプレーヤーをアペンドします。
* 検索結果を保存します。
* リストキーと本体データ(サムネイルとタイトルの配列)
* あらかじめ、jquery.jsをロードしています。
*ロード元: C:\拡張プラグイン\stampTube
*サイズ:
******************************************************************************/
//このファイルで使用している変数のみにする
let yahoo_search;
let params;
let tab_sw;
let p_element;
let subdomain; //
//グローバルオブジェクト変数
let other;
//
other = {
//
main: function () {
window.alertX=function(msg,n){
//すでにあればアペンドしない。
if($("#apop").length===0){
let html = "<div id='apop' style='padding:5px;z-index:999999;width:200px;height:100px;background-color:lightgreen;position:fixed;top:10%;left:10%;'>"+msg+"</div>";
$("body").append(html);
}
$("#apop").css("display","block");
$("#apop").draggable();
setTimeout(()=>{
$("#apop").css("display","none");
},n);
};
alertX("<br>このブラウザーには、<br>「stampTubeプラグイン」が<br>インストールされています。(8秒後、消去)",8000);
/********************************************************************************
*iframeのsrcに指定しているURLのphpファイルでheader("Access-Control-Allow-Origin: *");を
*指定しているため、このhtmlページはすべてのサイトで動作可能
*
*********************************************************************************/
//プレーヤー要素の追加
//alert("youtube_radio要素をアペンドします。");
let html ="<!-- youtubeラジオ -->\n\
<div id='youtube_radio' title='この枠はドラッグすることができます。' style='background-color:lightyellow;z-index:999999;border: 10px solid lawngreen; width: 270px;height: 465px; position: fixed;zoom: 1.0;top:42px;right:0px;'>\n\
<img style='zoom:0.5;' src='https://favorite.tecoyan.net/slim/images/radio_small.png'><span style='zoom:0.9;position:absolute;top:0px;right:10px;font-size:10px;'>TinyYoutubePlayerPlusプラグインv1.0</span>\n\
<iframe class='iframe_radio' style='position:relative;top:0px;border:solid 2px orange; width:250px;height:440px;' src='https://favorite.tecoyan.net/slim/index_stampTube.php?vid=YNQT68uHpyg&title=%E4%BB%8A%E6%97%A5%E3%81%AE%E6%97%A5%E3%81%AF%E3%81%95%E3%82%88%E3%81%86%E3%81%AA%E3%82%89%E3%80%80%E6%A3%AE%E5%B1%B1%E8%89%AF%E5%AD%90%E3%80%801967&url=&db_id=3120'></iframe>\n\
</div>";
$("body").append(html);
$("#youtube_radio").css("display","none");
// ユーザーエージェントを取得
var userAgent = navigator.userAgent.toLowerCase();
// スマホかどうかを判定
var isSmartphone = /iphone|ipod|android.*mobile|windows.*phone|blackberry.*mobile/.test(userAgent);
// PCかどうかを判定
var isPC = !isSmartphone;
// スマホの場合の処理
if (isSmartphone) {
console.log("このデバイスはスマホです");
// ここにスマホの場合の処理を記述
}
// PCの場合の処理
if (isPC) {
console.log("このデバイスはPCです");
// ここにPCの場合の処理を記述
}
//
document.getElementById("youtube_radio").onpointermove = function(event){
if(event.buttons){
this.style.left = this.offsetLeft + event.movementX + 'px';
this.style.top = this.offsetTop + event.movementY + 'px';
this.style.position = 'absolute';
this.draggable = false;
this.setPointerCapture(event.pointerId);
}
//
$("#youtube_radio").css("position","fixed");
};
}
};
/*******************************************************************************
* アメバ編集のyoutubeボタンでリストを保存
*
*********************************************************************************/
//検索結果を取得します。
//$(".js-video-item")
$(".js-accessoryTab-button").on('click',(e)=>{
let query_key;
//document.getElementsByClassName("js-accessoryTab-button").addEventListener('click', (e) => {
//alert("bodyでクリックしました。");
let aaa = document.getElementsByClassName("js-video-item");
if (aaa.length !== 0) {
//ここで、リストデータを生成して保存
//val.innerHTML この中の<imgタグのsrcを取得
//val.innereText タイトル
let src;
let title;
let data = [];
let aa = {};
let thumb;
$.each(aaa, (i, val) => {
//<imgタグを抽出
src = val.innerHTML.match(/<img[\s\S].*\/div><div/)[0].replace(/<\/div><div/, "");
title = src.split("alt=")[1].replace(/>/, "");
title = title.replace(/"/g, "");
thumb = src.replace(/alt=.*>/, ">");
//srcからサムネイルとタイトルを分けて
aa = {"サムネイル": thumb, "タイトル": title};
data.push(aa);
// console.log(src);
// dd.push(src);
});
//dd(配列データ)を保存します。サーバへ
//このリストをサーバーへ保存
//<imgタグのhtmlデータ
query_key = $("#js-searchBox-youtube")[0].value;
var params = {
query_key: query_key,
data: data
};
var resp = $.ajax({
url: 'https://favorite.tecoyan.net/slim/save_ameba_youtube_list.php',
type: 'POST',
dataType: 'html',
data: params,
cache: true,
async: false
}).responseText;
//
alert("リストデータを" + resp);
}
});
$("body").on('click',(e)=>{
if(e.ctrlKey===true){
if(window.confirm("youtubeプレーヤで再生しますか?")){
//alert("プレーヤーを開きます。");
//ラジオプラグインを利用
$("#youtube_radio").css("display","block");
$("#youtube_radio").draggable();
}else{// 「キャンセル」時の処理開始
$("#youtube_radio").css("display","none");
//ここで再生を停止
//プラグインからiframeのプレーヤーへ再生停止要求を出すには。
//テスト的に"play_video"メッセージをbackground.jsへ出す
chrome.runtime.sendMessage({data: 'play_video'}, function (msg) {
//応答は? 特になし。
});
return;
}
}
});
/*EXTENTION IDをセット */
var myid = chrome.runtime.id;
$("#ex_id").html(myid);
tab_sw = tab_case();
//
//この要素は親タブの要素のため、子タブでは取得できず、nullになります。
//content.jsはひとつのファイルで二つのタブの処理を行います。
subdomain = $("#plugin_id").html();
console.log("先頭のsubdomainチェックで " + subdomain);
/**********************************************************************
メソッド名: yahooサーチオブジェクト
ステータス : 機能しています。
内容: ページで文字列をセレクトしてマウスアップするとyahooサーチで検索します。
**********************************************************************/
yahoo_search = {
p_element: document.querySelector("body"),
main: (event)=>{
if (window.getSelection().toString().length === 0) {
return;
}
if(location.href.indexOf("favorite.tecoyan.net")!==-1&&$("#search_sw")[0].innerText.indexOf("オン")!==-1){
//yahoo検索をリクエスト
yahoo_search.yahoo(window.getSelection().toString());
}else if(location.href.indexOf("favorite.tecoyan.net")===-1){
yahoo_search.yahoo(window.getSelection().toString());
}
},
yahoo:(k_w)=>{
var w = null;
var char_ = "";
if (document.all) {
char_ = document.charset;
} else {
char_ = document.characterSet;
}
if (char_ === "utf-8" || char_ === "UTF-8") {
} else {
}
var k_w = k_w.replace(/ /g, ' ');
if (typeof (k_w) !== "undefined") {
var gg = 'http://search.yahoo.co.jp/search?ei=' + char_ + '&p=' + k_w;
if (w === undefined || w === null) {
w = window.open(gg, '_blank');
w.focus();
} else {
w.close();
w = window.open(gg, '_blank');
w.focus();
}
window.getSelection().empty();
}
}
};
/*このイベントは、文字列を選択すると実行するリスナー*/
yahoo_search.p_element.addEventListener('mouseup', yahoo_search.main, true);
/********************************************************************************
*タブ処理へ分岐
* slim_content.jsは、タブ毎に処理空間を持つ
* タブ毎の処理を分岐 タブ毎にオブジェクト定義 その中のmain()メソッドをコールしている
* tab_swで分岐
* ここで、#temp_pluginをチェックして、オンオフにより、
********************************************************************************/
switch (tab_sw) {
case "other":
other.main();
break;
case "youtube":
yahoo_search.main();
break;
}
//******************************************************************************
//スイッチ変数
//タブ処理分岐
//******************************************************************************
function tab_case() {
//プレーヤータブが複数ある場合、favoriteにする
if (location.href.indexOf("results?search_query=") !== -1) {
return "youtube";
}else {
//その他
return "other";
}
}
/*****************************************************************************************
* このリスナーは、タブがアメバ編集のときのみ可能
* bodyでそりにそのしてもそのタブがアメバ編集タブでなければ、エラーになるため、事前にチェックしておく
* locationをチェック
******************************************************************************************/
document.getElementsByTagName("body")[0].addEventListener('click', (e) => {
//アメバ編集か?
if(location.href.indexOf("entry/srventryupdateinput.do?") !== -1){
//
//alert("bodyでクリックしました。");
let aaa = document.getElementsByClassName("cke_wysiwyg_frame")[0].contentDocument.getElementsByTagName("iframe");
//このsrcにリピート属性を追加
let sw = 0;
$.each(aaa,(i,val)=>{
if(val.src.indexOf("/embed/")!==-1){
//?があれば
if(val.src.indexOf("/embed/?")!==-1){
//val.src = val.src.replace(/embed/,"embed\/?autoplay=1&loop=1&playlist=");
return true;
}else{
//let src = val.src;
//リピート追加
//?autoplay=1&loop=1&playlist=
val.src = val.src.replace(/embed\//,"embed\/?autoplay=1&loop=1&playlist=");
sw = 1;
return true;
}
}
});
//
if(sw === 1){
alert("リピート機能を追加しました。");
}else{
}
}
});
stampTube.js(長いため、省略します)
ランダムボタンのイベントリスナーは、このコードの中にあります。
このスクリプトファイルは、pop画面の中にiframeタグで読み込むためのhtmlファイルの中で定義しています。そのhtmlファイルで、youtubeプレーヤーとリストをロードしています。これらは、今回のalertX()メソッドには無関係ですが、サンプルとして利用したためです。
//一部抜粋
window.alertX=function(msg,n){
//すでにあればアペンドしない。
//setTimeout(()=>{
$("#apop").remove();
if($("#apop").length===0){
let html = "<div id='apop' style='padding:5px;z-index:999999;width:200px;height:100px;background-color:lightgreen;position:fixed;top:10%;left:10%;'>"+msg+"</div>";
$("body").append(html);
}
$("#apop").css("display","block");
$("#apop").draggable();
setTimeout(()=>{
$("#apop").css("display","none");
},n);
//},n);
};
//一部抜粋
$("#random").on('click',()=>{
//alert("ランダム再生");
glistobj.get_lists("ランダムリスト");
/*****************************************************
*Promiseテスト
*このパターンをすぐに忘れるため。
*プロミスオブジェクト(promise3)のコンストラクターを定義して、
*****************************************************/
const promise3 = new Promise((resolve, reject) => {
alertX("同期処理でalertX()を表示",5000);
//5秒後にresolveしている。
setTimeout(resolve, 6000, 'foo');
console.log("promise3");
});
//コンストラクターを実行して、同期処理(resolve)で'foo'valueを返すので、
//それをalert()で表示している。
promise3.then((value)=>{
const promise4 = new Promise((resolve, reject) => {
alertX("次の同期処理でalertX()を表示",5000);
//5後にresolveしている。
setTimeout(resolve, 6000, value);
console.log("promise4");
}).then(()=>{
//alert("これは、promise4の"+value+"です。")
});
//2秒後に結果が返る
//'foo'を表示
//alert(value);
});
return false;
});
alert()自体には、自動消去の機能はないようです。
alert()は、簡単でちょっとしたデバッグには、よく使いますが、あっちこっちに入れすぎると都度のOKボタンを押すのが面倒になります。
ネットでも自動消去の質問が多く出ています。やはり、皆さんも同じなのかと思います。
これは、pop表示する自作のalert()もどきのメソッドを作っておくといいかもしれません。今回のサンプルも10ステップ程度です。
あとがき
まだ、作成してテスト中ですので、使い勝手はいまいちかもしれません。
時間があれば、手を加えて行きたいと思います。