Horic Design

a-blog cmsやJavaScriptなどの情報を発信しています。

4ページ目 | js

uikitで自分の欲しいCSS,JSのみをgulpで書き出す方法

CSSフレームワークはとても柔軟な作りになっています。例えばそのフレームワークから自分の欲しいパーツのみを切り出して使うなんてことも可能です。
今回はUIkitを使って、オフキャンバスのCSS,JSのみを書き出しを紹介したいと思います。

UIkitをダウンロード

https://github.com/uikit/uikitから下の図のようにzipファイルをダウンロードしましょう。


lessファイルの編集

中身を展開したら、/src/lessの中にあるuikit.lessを編集します。variable.less及びoffcanvas.less以外のインポートをコメントアウトしましょう

// LESS related
@import "core/variables.less";

// Defaults
//@import "core/base.less";

// Layout
//@import "core/grid.less";
//@import "core/panel.less";
//@import "core/article.less";
//@import "core/comment.less";

// Navs
//@import "core/nav.less";
//@import "core/navbar.less";
//@import "core/subnav.less";
//@import "core/breadcrumb.less";
//@import "core/pagination.less";
//@import "core/tab.less";

// Elements
//@import "core/list.less";
//@import "core/description-list.less";
//@import "core/table.less";
//@import "core/form.less";

// Common
//@import "core/button.less";
//@import "core/icon.less";
//@import "core/close.less";
//@import "core/badge.less";
//@import "core/alert.less";
//@import "core/thumbnail.less";
//@import "core/overlay.less";
//@import "core/progress.less";
//@import "core/animation.less";

// JavaScript
//@import "core/dropdown.less";
//@import "core/modal.less";
@import "core/offcanvas.less";
//@import "core/switcher.less";
//@import "core/tooltip.less";

// Need to be loaded last
//@import "core/text.less";
//@import "core/utility.less";
//@import "core/print.less";

gulp.jsの編集

次にgulpfile.jsの編集です。59行目に読み込むjsを定義した配列がありますので、core.jsoffcanvas.js以外をコメントアウトしましょう。

    corejs = [
        './src/js/core/core.js',
        // './src/js/core/touch.js',
        // './src/js/core/utility.js',
        // './src/js/core/smooth-scroll.js',
        // './src/js/core/scrollspy.js',
        // './src/js/core/toggle.js',
        // './src/js/core/alert.js',
        // './src/js/core/button.js',
        // './src/js/core/dropdown.js',
        // './src/js/core/grid.js',
        // './src/js/core/modal.js',
        // './src/js/core/nav.js',
        './src/js/core/offcanvas.js',
        // './src/js/core/switcher.js',
        // './src/js/core/tab.js',
        // './src/js/core/tooltip.js'
    ];

コマンド操作

あとはコマンド操作でcssとjsを書き出すだけです。npm installで依存ファイルをダウンロードした後、gulp dist defaultと入力し、コンパイルしましょう。distディレクトリの中のcssディレクトリ及びjsディレクトリにminifyされたファイルが出力されていると思います。それぞれuikit.min.js及びuikit.min.cssです。

DEMO

実際に書き出したファイルでDEMOページを作りました。とても簡素ですが、ちゃんとオフキャンバスが動作していることが確認できます。

DEMOページへ

読み込んでいるCSS内に指定したルールが記述されているかを確かめるメソッドを書いてみた

このページでこのクラスを読み込んでたっけ?とCSSファイルを探さないとすぐには分からない場合があるとおもいます。そこで今回は、$.isRuleExist()というメソッドを作成してみました。以下がそのソースになります。

ソース

(function($){
     $.extend({
       isRuleExist:function(className){
              var classes = [];
              var sheets = document.styleSheets;
              var push = Array.prototype.push;
              for(var i = 0,n = sheets.length; i < n; i++){
                push.apply(classes, sheets[i].rules || sheets[i].cssRules);
              }
              for(var i = 0,n = classes.length; i < n; i++){
                 if(classes[i].selectorText == className){
                         return true;
                 }
             }
             return false;
          }
     });
})(jQuery);

使い方

$.isRuleExist(".entryList li");

もしCSSファイルにこのルールが存在すればtrueなければfalseを返します


うーん、でも普通にChrome Dev Toolでリソースを調べた方が速いかも。


gruntでjsファイルどうしを結合

1つのjsが変更されたら、すべてのjsファイルを結合して1つのjsにまとめるための処理をgruntで書いてみました。今回はそのメモになります。
結合することのメリットとすれば、例えば下の図のようにオフキャンバス用のjsやモーダルウィンドウ用のjs、カルーセル用のjsを1つのファイルとしてまとめられることではないでしょうか?


操作の手順としては以下のようになります。

  1. package.jsonの定義
  2. Gruntfile.coffeeの記述
  3. grunt watchで監視

1.package.jsonの定義

依存するファイルを記述しておきます

  "dependencies": {
    "grunt": "~0.4.5",
    "grunt-contrib-concat": "~0.4.0",
    "grunt-contrib-clean": "~0.6.0",
    "grunt-contrib-watch": "~0.6.1",
    "load-grunt-tasks": "~0.6.0",
    "nib": "~1.0.3"
  },

dependenciesを記述したら依存ファイルをnpm installで一気にダウンロードしちゃいましょう

2.Gruntfile.coffeeの記述

module.exports = (grunt) ->
  grunt.initConfig
    pkg: grunt.file.readJSON 'package.json'
    watch:
      js:
        files: 'js/**/*.js'
        tasks: 'js'
    concat:
      dist:
        src: ['js/**/*.js']
        dest: 'dist/js/callisto.js'
  require('load-grunt-tasks')(grunt)
  grunt.registerTask 'js', ['concat:dist']

gruntでは、CofeeScriptが使えるので記述がすごくシンプルになります。

3.grunt watchで監視

あとは、grunt watchでjsを監視するだけです。jsファイルのうち1つでも変更があればすぐに、結合ファイルが作成されます。


JSでスライダーを実装してみたよ

今回は、プラグインを使わず自らの力でスライダーを実装してみたいとおもい、一からスライダーを作りました。
とはいってもjQueryは使っています。

DEMO

スライダーの下にある黒い丸をクリックしてスライダーをスライドしてみてください。

仕組み

slider()メソッドが実行されると、リスト1つあたりの大きさを取得し、そのリストの大きさ×リストの数分、スライダーの幅を拡大します。そして、スライダーの下にボタンを追加します。
そのボタンがクリックされると、現在のスライダーのスライド量とスライドさせたい位置のオフセット値を取得し、setInterval関数を使い、すこしずつオフセット値を埋めていきます。

使い方

下のように画面に表示する、スライド数をitemsにアニメーションにかかるフレーム数をtimeに格納します。

$(".cs-slider").slider({items:3,time:60});

HTML

<ul class="cs-slider">
	<li><img src="http://placehold.it/300x300/333333/FFFFFF&text=HELLO" /></li>
	<li><img src="http://placehold.it/300x300/FFFF00/FFFFFF&text=HELLO" /></li>
	<li><img src="http://placehold.it/300x300/00FF00/FFFFFF&text=HELLO" /></li>
	<li><img src="http://placehold.it/300x300/FFFF00/FFFFFF&text=HELLO" /></li>
	<li><img src="http://placehold.it/300x300/00FFFF/FFFFFF&text=HELLO" /></li>
	<li><img src="http://placehold.it/300x300/333333/FFFFFF&text=HELLO" /></li>
</ul>

CSS

.cs-slider-wrapper {
  overflow-x: hidden;
}
.cs-slider {
  zoom: 1;
  padding-left: 0;
  position: relative;
  overflow-x: hidden;
}
.cs-slider:before,
.cs-slider:after {
  content: "";
  display: table;
}
.cs-slider:after {
  clear: both;
}
.cs-slider li {
  list-style-type: none;
  float: left;
}
.cs-slider img {
  width: 100%;
  height: auto;
}
.cs-slider-btn-wrapper {
  text-align: center;
}
.cs-slider-btn {
  background-color: #666;
  width: 10px;
  height: 10px;
  -webkit-border-radius: 5px;
  border-radius: 5px;
  display: inline-block;
  margin-right: 5px;
  cursor: pointer;
}
.cs-slider-btn.active {
  background-color: #000;
}

JavaScript

/*$(".slider").slider()*/
$.fn.extend({
	slider:function(json){
		var json = json || {};
		json.items = json.items || 3;
		json.time = json.time || 60;
		var $that = $(this);
		$that.wrap("<div class='cs-slider-wrapper'></div>");
		$parent = $that.parent(".cs-slider-wrapper");
		var width = $parent.width();
		var itemWidth = parseInt(width / json.items);
		var $children = $that.children("li");
		$children.width(itemWidth);
		$that.width($children.length * itemWidth);
		var $btnWrapper = $("<div class='cs-slider-btn-wrapper'>");
		var cnt = Math.ceil($children.length / json.items);
		var $btn = $("<div class='cs-slider-btn'></div>");
		for(var i = 0; i < cnt; i++){
			var $tmp = $btn.clone()
			if(i == 0){
				$tmp.addClass('active');
			}
			$btnWrapper.append($tmp);
		}
		$parent.append($btnWrapper);
		$that.attr("data-items",json.items);
		$that.attr("data-time",json.time);
	}
});
/*スライダーのボタンが押されたとき*/
$(document).on("click touchstart",".cs-slider-btn",function(){
	$(".cs-slider-btn").removeClass('active');
	$(this).addClass('active');
	var index = $(".cs-slider-btn").index(this);
	var $slider = $(this).parent().parent(".cs-slider-wrapper").children(".cs-slider");
	var itemWidth = $slider.children("li").width();
	var left = $slider.css("left") ==  "auto" ? 0 : parseInt($slider.css("left"));
	var offset = -left - (parseInt($slider.data("items")) * itemWidth * index);
	var time = $slider.data("time");
	var cnt = 0;
	var add = offset / parseInt(time);
	var interval = setInterval(function(){
		if(cnt <= time){
			x = left + offset*(cnt/time);
		}else{
			clearInterval(interval);
		}
		cnt++;
		$slider.css("left",x+"px");
	});
});

今回のパーツについて

わたしがブログで作ったパーツはすべてgithubで公開しています
stylusでビルドしています。良かったらダウンロードして遊んでみてください。



1つのJSで複数のページを管理

あるページにしか使わないJavaScriptを書くばあい、別ファイルに記述して読み込ませることがあると思います。
ただ、JavaScriptを複数のファイルに書いていると管理が大変になりますよね。
そこで今回は,1つのファイルでページの処理を切り分ける方法をご紹介します。
KAYACが2010年8月に紹介しているdispatcherという関数を使います。

手順

  1. dispatcherという関数の定義
  2. dispatcherに実行するページのURLの文字列パターンと実行命令を記述
  3. dispatcherにlocation.pathnameを格納

1. dispatcherという関数を定義

/*
    path:正規表現
    func:条件にあてはまるURLの際に実行する関数
*/
function dispatcher (path, func) {
    dispatcher.path_func = dispatcher.path_func || []
    if (func) return dispatcher.path_func.push([path, func]);
    for(var i = 0, l = dispatcher.path_func.length; i < l; ++i) { // >
        var func = dispatcher.path_func[i];
        var match = path.match(func[0]);
        match && func[1](match);
    };
};

2. dispatcherに実行するページのURLの文字列パターンと実行命令を記述

/*トップページ
http://horicdesign.com/
のときに命令を実行
*/
dispatcher("^/$",function(){
        //処理
});

/*カテゴリーページ及び、子ブログのトップページ
http://horicdesign.com/hoge/
のURLの時に命令を実行
*/
dispatcher("^/hoge/$",function(){
        //処理
});


/*エントリーページ
http://horicdesign.com/hoge/~.html
のURLの時に命令を実行
*/
dispatcher("^/hoge/.*\.html$",function(){
        //処理
});

もしjQueryを使ってロード時に命令を実行したいなら以下のように記述すれば良いでしょう。

dispatcher("^/$",function(){
    $(function(){
        //処理
    });
});

dispatcher("^/hoge/$",function(){
    $(function(){
        //処理
    });
});

dispatcher("^/hoge/.*\.html$",function(){
    $(function(){
        //処理
    });
});

3.dispatcherにlocation.pathnameを格納

dispatcher(location.pathname);

全体のJavaScriptは以下のようになります。

function dispatcher (path, func) {
    dispatcher.path_func = dispatcher.path_func || []
    if (func) return dispatcher.path_func.push([path, func]);
    for(var i = 0, l = dispatcher.path_func.length; i < l; ++i) { // >
        var func = dispatcher.path_func[i];
        var match = path.match(func[0]);
        match && func[1](match);
    };
};
/*
http://horicdesign.com/
*/
dispatcher("^/$",function(){
    $(function(){
        //処理
    });
});
/*
http://horicdesign.com/hoge/
*/
dispatcher("^/hoge/$",function(){
    $(function(){
        //処理
    });
});
/*
http://horicdesign.com/hoge/~.html
*/
dispatcher("^/hoge/.*\.html$",function(){
    $(function(){
        //処理
    });
});
dispatcher(location.pathname);

参考


感想

ただ、これを使いこなすには正規表現を軽く知っておかなきゃいけないので、それがネックですね。
任意の文字列を表す.*や、開始記号^、終了記号$くらいは覚えておくといいのではないでしょうか?


堀 悟大

有限会社アップルップル マークアップエンジニア。2014年高知大学理学部卒業。学生時代にHTML5のCanvas要素を使ってゲームを作っていたことでWeb全般に興味をもつ。アップルップル入社後はa-blog cmsを便利に使うための機能の実装や、HTML5の技術を使ったデジタルサイネージの実装を行う。趣味は英語。読むことも話すことも好き。

エントリーリスト

カテゴリーリスト

タグクラウド