Skip to content

Instantly share code, notes, and snippets.

@ashikawa
Created November 9, 2012 11:04
Show Gist options
  • Save ashikawa/4045165 to your computer and use it in GitHub Desktop.
Save ashikawa/4045165 to your computer and use it in GitHub Desktop.
JS勉強会資料 $.data, $.each, クロージャ

1.サンプルプログラム、処理の流れ

  • リスト要素の生成 初期位置を記録 => $.data

  • イベントリスナ スクロールに応じてリストを動かす

    縦の位置 = 初期位置 + ( スクロール量 * 補正値(z-index) );

2.$.data とそれ以外書き方を比較

HTMLの属性

$(element).attr('data-defaultTop', positionY);
// <div data-defaultTop="100"> ...
  • メリット
    • CSS が効く
    • HTMLからJSにデータを渡せる ( SNSウィジェットとか、JS本体に触れない時 )
  • デメリット
    • 文字列しか保存できない。
    • 開発ツールで見ると邪魔

変数に保存

var position = [];

//保存
for(i=0;;){
	positionTop[i] = ... 
}

//読み込み
$.each(lists, function (i, element) {
	defaultTop = positionTop[i];
});
  • メリット
    • 普通
    • コードを追いやすい
  • デメリット
    • 変数が増えまくる
    • スコープの問題 保存と読み込みを同じ場所に書かなければいけない

$.data

  • メリット
    • DOM要素に付けるので、どこからでも呼び出せる (別のプラグイン間でデータを受け渡しできる)
  • デメリット
    • 中に何が入っているのか見え辛い

3.$.each

$.each(element, function ... )
$('element').each( function ...)

// 配列に順番に処理
var arr = [1,2,3,4,5];
$.each(arr, function ...)


// ループでも一緒
for(key in arr){
	arr[key] ... 
}

処理の内容を関数で渡すので、 each の方が見やすいかもしれない。

  • for (i=0; i<n; i++) 決まった回数のループ
  • for (key in obj) 連想配列を走査
  • $.each ... jQery っぽい。 ループの中で $(this) とか使える
  • forEach IE爆発しろ

map とか filter とかも便利だよ。 JavaScript の配列と連想配列の違い Amachangの記事がかなりわかりやすい。

4.クロージャ

関数内で関数を生成して返す

function hoge(){}

var hoge = function () {};

var hoge = (function (){
	return function () {}
}());

ここまでは全部一緒

変数のスコープを分けたい時

// 呼び出すたびにカウントアップとか
var countup = (function (){
	var i = 0;

	return function () {
		return i++;
	}
}());

countup();	=> 0
countup();	=> 1
countup();	=> 2

引数がやたら多い時とか

function joinFour(a, b, c, d) {	
	return a + b + c + d;
}

joinFour('my ', 'name ', 'is ', 'bob');
joinFour('my ', 'name ', 'is ', 'tom');
joinFour('my ', 'name ', 'is ', 'john');

いつも同じようなパラメータで呼び出しているのを

function joinFour(a, b, c, d) {	
	return a + b + c + d;
}

function builder(a, b, c) {
	
	return function (d) {
		return joinFour(a, b, c, d);
	}
}

// 前半の引数(a, b, c)を固定して、新しい関数を作る
sayMyName = builder('my ', 'name ', 'is ');

sayMyName('bob');
sayMyName('tom');
sayMyName('john');

その他

builder('my ', 'name ', 'is ')('who');
builder()()()()()();

のようにも使えるが、くどいから使い過ぎに注意。

<html lang="ja">
<head>
<meta charset="UTF-8">
<title>title</title>
<link rel="stylesheet" href="./reset.css?v=1.0">
<style>
body{
height: 1000px;
}
#sample1 li{
width: 300px;
height: 100px;
position: absolute;
}
</style>
</head>
<body>
<ul id="sample1"></ul>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script>
<script src="./main.js"></script>
</body>
</html>
/*global $*/
$(function () {
var $window = $(window),
$container = $('#sample1'),
partsDom = '<li></li>',
/**
* @var array.<jQuery>
*/
lists = [];
/**
* 要素の生成と初期化
*/
(function () {
var $parts,
params = {},
clickEvents = $.noop,
color = '',
PARTS_NUM = 10,
i = 0;
// #FFFFFF 形式のフォーマットで色情報を作成
function makeRGB(index) {
var color = (0x111111 * index).toString(16);
// Zero_Padding
return '#' + ('000000' + color).slice(-6);
}
for (i = 0; i < PARTS_NUM; i++) {
$parts = $(partsDom);
color = makeRGB(i);
// 細かい値は今回適当です
params = {
'z-index': i,
'background-color': color,
'top': i * 100 + 300,
'left': i * 40
};
$parts.css(params);
// data で元の座標を保存しておく
$parts.data('params', params);
$container.append($parts);
lists[i] = $parts;
// 上手く動かない例
// clickEvents = function (event) {
// console.log(i);
// };
// クロージャを使った書き方
// clickEvents = (function (num) {
// return function (event) {
// console.log(num);
// };
// }(i));
$parts.on('click', clickEvents);
}
}());
/**
* スクロールイベントに連動して、要素の座標を変更
*/
(function () {
$window.on('scroll', function (event) {
var scrollTop = $window.scrollTop();
// $('#sample1 li').each() と同じ
$.each(lists, function (i, element) {
var $element = $(element),
params = $element.data('params');
// 座標 : 初期座標 - 移動量
// 移動量 : ウインドウスクロール * 補正値 手前の物(z-index が大きい)ほど大きく移動
$element.css({
'top': params['top'] - (scrollTop * params['z-index'] * 0.5)
});
});
});
}());
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment