ソースコード
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Modal.js</title>
<link rel="stylesheet" href="modal.css">
<script src="modal.js"></script>
</head>
<body>
<h1>Modal.JS</h1>
<button class="modal-alert" type="button">Modal-Alert</button>
<button class="modal-confirm" type="button">Modal-Confirm</button>
<script>
var btn1 = document.querySelector(".modal-alert");
btn1.onclick = function(){
new $$modal({
title : "アラート",
close : {
html : "",
size : 30
},
message : "このウィンドウを閉じるには、「×」ボタンを押すか、OKをクリックしてください。",
button : [
{
mode : "close",
text : "OK"
}
],
bgClick : "none"
});
};
var btn2 = document.querySelector(".modal-confirm");
btn2.onclick = function(){
new $$modal({
title : "確認ウィンドウ",
close : {
html : "",
size : 16
},
message : "このウィンドウを閉じるには、「×」ボタンを押すか、OKをクリックしてください。",
button : [
{
mode : "close",
text:"キャンセル",
click:function(){console.log("cancel");}
},
{
mode : "close",
text:"OK"
}
],
bgClick : "close"
});
};
</script>
</body>
</html>
*, *:before, *:after {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
-o-box-sizing: border-box;
-ms-box-sizing: border-box;
box-sizing: border-box;
}
.modal{
position:absolute;
top:0;
left:0;
width:100%;
height:100%;
background-color:rgba(0,0,0,0.5);
}
.modal * {
font-size:12px;
color:#666;
}
.modal-base{
position:relative;
width:300px;
background-color:white;
border-radius:4px;
padding:10px;
}
.modal-close{
position:absolute;
top:10px;
right:10px;
}
.modal-close > .modal-close-icon{
position:relative;
width:100%;
height:100%;
margin:0;
padding:0;
cursor:pointer;
}
.modal-close > .modal-close-icon:empty:hover{
opacity:0.5;
}
.modal-close > .modal-close-icon:empty:before{
content:"";
position:absolute;
top:calc(50% - 1px);
left:10%;
width:80%;
height:1px;
border-bottom:1px solid #666;
transform:rotate(45deg);
transform-origin:center;
}
.modal-close > .modal-close-icon:empty:after{
content:"";
position:absolute;
top:calc(50% - 1px);
left:10%;
width:80%;
height:1px;
border-bottom:1px solid #666;
transform:rotate(-45deg);
transform-origin:center;
}
.modal-title{
width:100%;
font-size:14px;
text-align:center;
}
.modal-message{
width:100%;
min-height:100px;
font-size:12px;
padding:10px;
display:table-cell;
vertical-align:middle;
}
.modal-button-area{
text-align:center;
}
button.modal-button{
display:inline;
min-width:80px;
height:30px;
font-size:12px;
margin:8px;
padding:0 8px;
border-radius:4px;
box-shadow:0px 0px 4px rgba(0,0,0,0.3);
cursor:pointer;
}
button.modal-button:hover{
opacity:0.5;
}
/* Animation */
.modal{
opacity:0;
}
.modal,
.modal .modal-base{
animation-duration: 0.3s;
animation-fill-mode: forwards;
}
.modal[data-view="1"]{
/* animation: anim-modal-view 0.3s linear forwards; */
animation-name: anim-modal-view;
animation-timing-function: linear;
}
@keyframes anim-modal-view{
0%{
opacity:0;
}
100%{
opacity:1;
}
}
.modal[data-view="1"] .modal-base{
/* animation: anim-modal-slidein 0.3s ease-out forwards; */
animation-name: anim-modal-slidein;
animation-timing-function: ease-out;
}
@keyframes anim-modal-slidein{
0%{
transform:translateY(-150px);
}
100%{
transform:translateY(0px);
}
}
.modal[data-view="0"]{
/* nimation: anim-modal-close 0.3s linear forwards; */
animation-name: anim-modal-close;
animation-timing-function: linear;
}
@keyframes anim-modal-close{
0%{
opacity:1;
}
100%{
opacity:0;
}
}
.modal[data-view="0"] .modal-base{
/* animation: anim-modal-slideout 0.3s ease-out forwards; */
animation-name: anim-modal-slideout;
animation-timing-function: ease-out;
}
@keyframes anim-modal-slideout{
0%{
transform:translateY(0px);
}
100%{
transform:translateY(-150px);
}
}
;$$modal = (function(){
/**
* ModalJS
* ==
* [Summary]
* alertやconfirm処理をデザイン対応する時のモーダル表示処理。
* 背景に黒半透明elmを置くことで、画面のelementにアタッチできなくさせる。
* [Howto]
*
*
*/
var $$event = function(target, mode, func){
if (typeof target.addEventListener !== "undefined"){target.addEventListener(mode, func, false);}
else if(typeof target.attachEvent !== "undefined"){target.attachEvent('on' + mode, function(){func.call(target , window.event)});}
};
var $$urlinfo = function(uri){
uri = (uri) ? uri : location.href;
var urls_hash = uri.split("#");
var urls_query = urls_hash[0].split("?");
var sp = urls_query[0].split("/");
var data={
uri : uri,
url : sp.join("/"),
dir : sp.slice(0 , sp.length-1).join("/") +"/",
file : sp.pop(),
domain : sp[2],
protocol : sp[0].replace(":",""),
query : (urls_query[1])?(function(urls_query){
var data={};
var sp = urls_query.split("&");
for(var i=0;i<sp .length;i++){
var kv = sp[i].split("=");
if(!kv[0]){continue}
data[kv[0]]=kv[1];
}
return data;
})(urls_query[1]) : [] , hash : (urls_hash[1]) ? urls_hash[1] : ""
};
return data;
};
var $$init = function(){
switch(document.readyState){
case "complete" : new $$; break;
case "interactive" : $$event(window , "DOMContentLoaded" , (function(e){new $$}).bind(this)); break;
default : $$event(window , "load" , (function(e){new $$}).bind(this)); break;
}
};
var $$ = function(options){
this.reflectOptions(options);
this.view();
};
$$.prototype.options = {
size : {
width : "300px",
height: "auto"
},
close : {
html : "",
size : 16
},
title : "Title",
message : "Message",
button : [
{
mode:"close",
text:"Click"
}
],
bgClick : "close" // [ "close" , "none" ]
};
$$.prototype.reflectOptions = function(options){
if(!options){return;}
for(var i in options){
this.options[i] = options[i];
}
};
$$.prototype.view = function(){
if(!document.body){return}
// BG
var bg = document.createElement("div");
bg.className = "modal";
if(this.options.bgClick === "close"){
$$event(bg , "click" , (function(e){this.clickBg(e)}).bind(this));
}
document.body.appendChild(bg);
// Base
var base = document.createElement("div");
base.className = "modal-base";
base.style.setProperty("width" , this.options.size.width , "");
base.style.setProperty("height" , this.options.size.height , "");
bg.appendChild(base);
// Close
var close = document.createElement("div");
close.className = "modal-close";
var closeHTML = "";
closeHTML = "<div class='modal-close-icon'>";
closeHTML += this.options.close.html;
closeHTML += "</div>";
close.innerHTML = closeHTML;
close.style.setProperty("width" , this.options.close.size + "px" , "");
close.style.setProperty("height" , this.options.close.size + "px" , "");
close.onclick = (function(e){this.close(e);}).bind(this);
base.appendChild(close);
// Title
var title = document.createElement("div");
title.className = "modal-title";
title.innerHTML = this.options.title;
base.appendChild(title);
// Message
var message = document.createElement("div");
message.className = "modal-message";
message.innerHTML = this.options.message;
base.appendChild(message);
// Buttons
var btnArea = document.createElement("div");
btnArea.className = "modal-button-area";
base.appendChild(btnArea);
var btn = [];
for(var i in this.options.button){
btn[i] = document.createElement("button");
btn[i].className = "modal-button";
btn[i].innerHTML = this.options.button[i].text;
if(this.options.button[i].click){
btn[i].onclick = this.options.button[i].click;
$$event(btn[i] , "click" , (function(e){this.options.button[i].click}).bind(this));
}
if(this.options.button[i].mode === "close"){
$$event(btn[i] , "click" , (function(e){this.close(e);}).bind(this));
}
btnArea.appendChild(btn[i]);
}
// position
base.style.setProperty("top" , (window.innerHeight / 2) - (base.offsetHeight / 2) + "px" , "");
base.style.setProperty("left" , (window.innerWidth / 2) - (base.offsetWidth / 2) + "px" , "");
// animation
bg.setAttribute("data-view","1");
};
$$.prototype.close = function(){
var modal = document.querySelector(".modal");
if(!modal){return;}
modal.setAttribute("data-view" , "0");
setTimeout(function(){
var modal = document.querySelector(".modal");
modal.parentNode.removeChild(modal);
},500);
};
$$.prototype.clickBg = function(e){
var target = e.target;
if(!target.matches(".modal")){return;}
this.close();
};
return $$;
})();
使い方
new $$modal({
title : "アラート",
close : {
html : "",
size : 30
},
message : "このウィンドウを閉じるには、「×」ボタンを押すか、OKをクリックしてください。",
button : [
{
mode : "close",
text : "OK",
click: function(){console.log("cancel");}
}
],
bgClick : "none"
});
ボタンを押したタイミングや、リンククリックのタイミングで、上記のように"$$modal"をインスタンス化して、送り値としてオプションを設定すれば、モーダルダイアログが機能するようになります。
注意点としては、"button"設定は、1つだけでも、必ず配列にしてください。
サンプルプログラムを見るとわかるかもしれませんが、button設定に"click"という設定をすると、そのボタンを押した時に、任意のプログラムを実行することができるので、機能連動させることができます。
buttonの"mode"は、デフォルトでは「close」となっていて、押した後モーダルを閉じるようにしていますが、閉じない場合は"none"にしてください。
"bgClick"というのは、モーダルが表示されている時に背景が黒の半透明になっていますが、そこをクリックした場合にモーダルを閉じるかどうかのモード設定になっています。
デフォルトは"none"で、何もしないのですが、枠外クリックでモーダルを閉じたい場合は、"close"としてください。
あとは、記入できる文字列は全てinnerHTMLで表示されるので、タグ記述が可能になります。
サンプル
See the Pen modal-js by YugetaKoji (@geta1972) on CodePen.
0 件のコメント:
コメントを投稿