ソースコード
;$$way_grid = (function(){
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)});}
};
// [共通関数] URL情報分解
var __urlinfo = function(uri){
uri = (uri) ? uri : location.href;
var data={};
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(":","")
, hash : (urls_hash[1]) ? urls_hash[1] : ""
, query : (urls_query[1])?(function(urls_query){
var data = {};
var sp = urls_query.split("#")[0].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]):[]
};
return data;
};
// 起動scriptタグを選択
var __currentScriptTag = (function(){
var scripts = document.getElementsByTagName("script");
return __currentScriptTag = scripts[scripts.length-1].src;
})();
// [初期設定] 基本CSSセット(jsと同じ階層同じファイル名.cssを読み込む)
var __initCSS = function(){
var head = document.getElementsByTagName("head");
var base = (head) ? head[0] : document.body;
var modal_pathinfo = __urlinfo(__currentScriptTag);
var css = document.createElement("link");
css.rel = "stylesheet";
var model_css = modal_pathinfo.dir + modal_pathinfo.file.replace(".js",".css");
var query = [];
for(var i in modal_pathinfo.query){
query.push(i);
}
css.href = model_css +"?"+ query.join("");
base.appendChild(css);
};
// elementのstyle情報を取得
var __getStyle = function(e,s){
if(!s){return}
//対象項目チェック;
if(typeof e == 'undefined' || e == null || !e){
e = document.body;
}
//属性チェック;
var d = '';
if(typeof e.currentStyle != 'undefined'){
d = e.currentStyle[__camelize(s)];
if(d == 'medium'){
d = "0";
}
}
else if(typeof document.defaultView != 'undefined'){
d = document.defaultView.getComputedStyle(e,'').getPropertyValue(s);
}
return d;
};
var __camelize = function(v){
if(typeof(v)!='string'){return}
return v.replace(/-([a-z])/g , function(m){return m.charAt(1).toUpperCase();});
};
// [共通関数] JS読み込み時の実行タイミング処理(body読み込み後にJS実行する場合に使用)
var __construct = function(){
switch(document.readyState){
case "complete" : new $$;break;
case "interactive" : __event(window , "DOMContentLoaded" , function(){new $$});break;
default : __event(window , "load" , function(){new $$});break;
}
};
var __options = {
baseSelector : ".way-grid",
column_count : "auto",
column_width : 200,
$ : null
};
var $$ = function(options){
switch(document.readyState){
case "complete" : this.start(options);break;
case "interactive" : __event(window , "DOMContentLoaded" , (function(options,e){this.start(options)}).bind(this,options));break;
default : __event(window , "load" , (function(options,e){this.start(options)}).bind(this,options));break;
}
};
$$.prototype.start = function(options){
// option初期設定
this.replaceOptions(options);
// 初期設定
this.initBase();
// 並べ設定
this.setBases();
};
// [初期設定] インスタンス引数を基本設定(options)と入れ替える
$$.prototype.replaceOptions = function(options){
var default_options = __options;
if(options){
for(var i in options){
default_options[i] = options[i];
}
}
this.options = default_options;
};
// lists-parent部分の初期設定
$$.prototype.initBase = function(){
var bases = document.querySelectorAll(this.options.baseSelector);
if(!bases){return;}
for(var i=0; i<bases.length; i++){
if(bases[i].getAttribute("data-way-grid-base")){continue;}
bases[i].setAttribute("data-way-grid-base","1");
this.initBoxes(bases[i]);
}
this.resize_flg = null;
__event(window , "resize" , (function(){
if(this.resize_flg !== null){
clearTimeout(this.resize_flg);
this.resize_flg = null;
}
this.resize_flg = setTimeout((function(){this.resize()}).bind(this),300);
}).bind(this));
};
$$.prototype.resize = function(){
if(!this.resize_count){
this.resize_count = 1;
}
else{
this.resize_count++;
}
var bases = document.querySelectorAll(this.options.baseSelector);
if(!bases){return;}
for(var i=0; i<bases.length; i++){
this.setBoxes(bases[i]);
}
};
// lists部分の初期設定
$$.prototype.initBoxes = function(base){
var boxes = base.querySelectorAll(":scope > *");
if(!boxes){return};
for(var i=0; i<boxes.length; i++){
if(boxes[i].getAttribute("data-way-grid-box")){continue;}
boxes[i].setAttribute("data-way-grid-box","1");
// boxes[i].style.setProperty("position","absolute","");
}
};
//
$$.prototype.setBases = function(){
var bases = document.querySelectorAll(this.options.baseSelector);
if(!bases){return;}
for(var i=0; i<bases.length; i++){
this.setBoxes(bases[i]);
}
};
//
$$.prototype.setBoxes = function(base){
if(!base){return;}
var baseSize = this.getSize(base);
if(this.options.column_width === "auto" && this.options.column_count !== "auto"){
var column_count = this.options.column_count;
var column_width = Math.floor(baseSize.w / column_count);
}
else if(this.options.column_width !== "auto" && this.options.column_count === "auto"){
var column_width = this.options.column_width;
var column_count = Math.floor(baseSize.w / column_width);
}
else if(this.options.column_width !== "auto" && this.options.column_count !== "auto"){
var column_count = this.options.column_count;
var column_width = this.options.column_width;
}
else if(this.options.column_width === "auto" && this.options.column_count === "auto"){
console.log("Error !!!");
}
else{
console.log("Error : way-grid (options column_count,column_width is fail.");
return;
}
var boxes = base.querySelectorAll(":scope > *");
var cols = 0;
// var rows = 0;
var bottom_element = [];
for(var i=0; i<boxes.length; i++){
boxes[i].style.setProperty("width" , column_width + "px" , "");
// 最上段処理
if(bottom_element.length < column_count){
var top = 0;
boxes[i].style.setProperty("top" , top + "px" , "");
boxes[i].setAttribute("data-top" , top);
var left = column_width * cols;
boxes[i].style.setProperty("left" , left + "px" , "");
bottom_element[cols] = boxes[i];
cols++;
if(cols > column_count -1){
cols = 0;
}
}
// 次段以降の処理
else{
var bottom_datas = this.getMinPositions(bottom_element);
var top = bottom_datas.min_pos;
boxes[i].style.setProperty("top" , top + "px" , "");
boxes[i].setAttribute("data-top" , top);
var left = column_width * bottom_datas.min_col;
boxes[i].style.setProperty("left" , left + "px" , "");
bottom_element[bottom_datas.min_col] = boxes[i];
}
}
}
// get-size
$$.prototype.getSize = function(elm){
if(elm){
return {
w : elm.offsetWidth,
h : elm.offsetHeight
};
}
else{
return null;
}
};
// 最下部の位置情報を取得
$$.prototype.getMinPositions = function(elms){
if(!elms || !elms.length){return;}
var datas = {
min_col : null,
min_pos : null
};
for(var i=0; i<elms.length; i++){
var top = Number(elms[i].getAttribute("data-top"));
var bottom_pos = top + elms[i].offsetHeight;
if(datas.min_pos === null || datas.min_pos > bottom_pos){
datas.min_pos = bottom_pos;
datas.min_col = i;
}
}
return datas;
};
__initCSS();
return $$;
})();
[data-way-grid-base="1"]{
position : relative !important;
display : block;
}
[data-way-grid-box="1"]{
position : absolute !important;
-webkit-transition-property: left, right, top;
-moz-transition-property: left, right, top;
-ms-transition-property: left, right, top;
-o-transition-property: left, right, top;
transition-property: left, right, top;
transition-duration: 0.7s;
}
jsファイルとcssファイルを同じ階層に設置してお使いください。
設置サンプル
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>grid-column-1</title>
<link rel="stylesheet" href="column-1.css">
<script src="way_grid.js"></script>
</head>
<body>
<ul class="datas way-grid"></ul>
<script>
var datas = document.querySelector("ul.datas");
for(var i=0; i<10; i++){
var li = document.createElement("li");
li.innerHTML = "<div class='box' style='font-size:20px;'>"+i+"</div>";
var h = Math.floor(Math.random() * 100 ) + 50;
li.style.setProperty("height", h + "px","");
datas.appendChild(li);
}
</script>
<script>
new $$way_grid({
column_count : "auto",
column_width : 200
});
</script>
</body>
</heml>
html,body{
width:100%;
height:100%;
margin:0;
padding:0;
}
*, *: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;
}
ul.datas{
font-size:0;
width:100%;
}
ul.datas,
ul.datas > li{
list-style:none;
margin:0;
padding:0;
}
ul.datas > li{
width:200px;
display:inline-block;
vertical-align:top;
}
.box{
width:100%;
height:100%;
border:1px solid red;
background-color:rgba(255,0,0,0.5);
margin:0;
padding:0;
}
前回記事に設置をしてみました。
"new $$way_grid({*options*});"optionsは何も書かなくてもデフォルトで動作しますが、以下の設定を入れてサイト専用の起動にした方がいいでしょう。
{
column_count : "auto", //カラム数 ( 数値 or "auto" )
column_width : 200, //カラムサイズ ( 数値 or "auto" )
}
カラム数とカラム値のどちらかは"auto"にして使ったほうがレスポンシブ対応もできて便利でしょう。
デフォルトは、サイズ固定なので、自動的にレスポンシブ対応になります。
デモ
See the Pen way-grid by YugetaKoji (@geta1972) on CodePen.
0 件のコメント:
コメントを投稿