Skip to content

Instantly share code, notes, and snippets.

@takuya
Created November 28, 2018 08:04
Show Gist options
  • Save takuya/b40b55d6f198ee439031c42ede7ce0bb to your computer and use it in GitHub Desktop.
Save takuya/b40b55d6f198ee439031c42ede7ce0bb to your computer and use it in GitHub Desktop.
/**
* Created by takuya on 20170809.
* 
*
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*
*
*
*  Usage Sample 01
*
* <img src='://example.com/example.jpg' 'data-modal-image'>
* <script src=/path/to/modal.js ><script>
* <script>
* var md = new ModaLayer();
* md.add_lisnters();
* </script>
*
* copyright takuya
* see http://takuya-1st.hatenablog.jp/entry/2017/08/09/064037
*/
'use strict'
var ModaLayer = function( args ){
var self = this;
this.attr_name = (args && args['attr_name']) ? args['attr_name'] : 'data-modal-image';
this.background_layer_name = (args && args['background_layer_name']) ? args['background_layer_name'] : 'modal_background_layer';
this.content_layer_name = (args && args['content_layer_name']) ? args['content_layer_name'] : 'modal_layer';
this.with_css = (args && args['with_css']) ? args['with_css'] : false;
this.add_lisnters = function( query ){
query = (query)? query:'*'
var elements = Array.from(document.querySelectorAll(query));
elements.forEach(function (element) {
if ( element.hasAttribute(this.attr_name)){
element.addEventListener('click', function(evt){
evt.preventDefault()
evt.cancelBubble = true;
this.clone_element = this.clone_node_recursively( element, true, self.with_css );
this.show()
}.bind(this))
}
}.bind(this))
}
this.clone_node_recursively = function( src, deep, with_css ){
var src = src
var dst = src.cloneNode(deep);
if (with_css){
dst.style.cssText = document.defaultView.getComputedStyle(src, "").cssText;
var a = src.querySelectorAll('*');
var b = dst.querySelectorAll('*');
var c = Array.from(a).map( function (e,idx) {
return [a[idx], b[idx]]
} )
c.forEach(function (e,i) {
e[1].style.cssText = document.defaultView.getComputedStyle(e[0], "").cssText;
})
}
return dst
}
this.show_layer = function(){
this.scrollY = window.scrollY;
this.scrollX = window.scrollY;
this.width = window.document.body.offsetWidth;
this.height = window.document.body.offsetHeight;
//
this.layer = window.document.createElement('div')
this.layer.classList.add(this.background_layer_name)
this.layer.style.width = '100%';
this.layer.style.height = this.height+'px'
this.layer.style.backgroundColor = 'rgba(0,0,0, 0.88)';
this.layer.style.position = 'absolute';
this.layer.style.zIndex = 100;
this.layer.style.top = 0
this.layer.style.left= 0;
this.layer.style.display = 'hidden';
this.layer.style.flexDirection = 'row'
this.layer.style.justifyContent = 'center';
this.layer.style.alignItems = 'center'
document.body.appendChild(this.layer);
this.layer.addEventListener('click', function(ev){
this.hide()
}.bind(this))
}
this.prevent_scroll = function(){
this.prevent_scroll_handler = function(evt){
this.fit_scroll()
}.bind(this)
window.addEventListener('scroll',this.prevent_scroll_handler)
}
this.permit_scroll = function(){
window.removeEventListener('scroll',this.prevent_scroll_handler)
}
this.revert_scroll = function(){
window.scrollTo(this.scrollX,this.scrollY)
}
this.fit_scroll = function(){
var x = window.document.body.offsetWidth/2 - window.innerWidth/2
var y = window.document.body.offsetHeight/2 - window.innerHeight/2
window.scrollTo( x, y )
}
this.follow_resize = function(){
this.follow_resize_handler = function(evt){
this.hide()
this.show()
}.bind(this)
window.addEventListener('orientationchange', this.follow_resize_handler);
window.addEventListener('resize', this.follow_resize_handler);
}
this.unfollow_resize = function(){
window.removeEventListener('orientationchange', this.follow_resize_handler);
window.removeEventListener('resize', this.follow_resize_handler);
}
this.show_content_layer = function( element ){
var div = document.createElement('div');
this.layer.appendChild(div);
this.content_layer = div;
this.content_layer.style.maxHeight = window.innerHeight*0.9 +'px';
this.content_layer.style.maxWidth = window.innerWidth*0.9 +'px';
element.style.maxWidth = '100%';
element.style.maxHeight = '100%';
this.content_layer.classList.add(this.content_layer_name)
this.content_layer.appendChild(element)
}
this.show = function(){
this.show_layer()
this.show_content_layer( this.clone_element )
this.layer.style.display = 'flex';
this.prevent_scroll();
this.fit_scroll()
this.follow_resize();
}
this.hide = function(){
this.layer.remove();
this.revert_scroll();
this.permit_scroll();
this.unfollow_resize();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment