回答編集履歴
5
Function#bind のサンプルをjsfiddleにUP
answer
CHANGED
@@ -87,7 +87,9 @@
|
|
87
87
|
jQuery(window).on('resize', sampleA1.resizeEvent.bind(sampleA1));
|
88
88
|
```
|
89
89
|
|
90
|
-
もう一つは `initialEvent()` 時に予め `bind` しておく方法(Lhankor_Mhy さんのアイデア
|
90
|
+
もう一つは `initialEvent()` 時に予め `bind` しておく方法(Lhankor_Mhy さんのアイデア)。
|
91
|
+
jsfiddleにサンプルをUPしています。
|
92
|
+
- [Function#bind で this 値を束縛する - JSFiddle](https://jsfiddle.net/066ko0qg/)
|
91
93
|
|
92
94
|
```JavaScript
|
93
95
|
SampleClassA.prototype.initialEvent = function initialEvent () {
|
4
pointA, pointC がインクリメントされていなかった不具合修正
answer
CHANGED
@@ -38,8 +38,9 @@
|
|
38
38
|
this.doDisplay(); // (修正) 関数呼び出しする
|
39
39
|
},
|
40
40
|
updateResizeData: function updateResizeData () {
|
41
|
-
|
41
|
+
var data = this.data;
|
42
|
+
++data.pointA; // (修正) インクリメントされていなかった不具合を修正
|
42
|
-
|
43
|
+
++data.pointC; // (修正) インクリメントされていなかった不具合を修正
|
43
44
|
},
|
44
45
|
resizeEvent: function resizeEvent (event) {
|
45
46
|
console.log(event);
|
3
Lhankor_Mhy さんのアイデアをお借りして `initialEvent\(\)` 時に予め `bind` しておくコードを追加
answer
CHANGED
@@ -13,19 +13,16 @@
|
|
13
13
|
|
14
14
|
```JavaScript
|
15
15
|
'use strict';
|
16
|
-
function SampleClassA () {
|
16
|
+
function SampleClassA () { ; }
|
17
|
-
|
17
|
+
|
18
|
-
this.object;
|
19
|
-
}
|
20
18
|
SampleClassA.prototype = { // (修正) SampleClassAに修正
|
21
19
|
setDefaultData: function setDefaultData () {
|
22
20
|
this.data = {
|
23
21
|
pointA: 10,
|
24
22
|
pointB: 10,
|
25
23
|
pointC: 10,
|
26
|
-
pointD: 10
|
24
|
+
pointD: 10
|
27
25
|
};
|
28
|
-
return true;
|
29
26
|
},
|
30
27
|
doDisplay: function doDisplay (/* [window] */) {
|
31
28
|
// this.object = new SampleLibrary.display(this.data); // (修正) ReferenceError の為、コメントアウト
|
@@ -35,25 +32,28 @@
|
|
35
32
|
console.log(window.innerWidth, window.innerHeight);
|
36
33
|
}
|
37
34
|
console.log(this.data);
|
38
|
-
return true;
|
39
35
|
},
|
40
36
|
initialEvent: function initialEvent () {
|
41
37
|
this.setDefaultData(); // (修正) 関数呼び出しする
|
42
38
|
this.doDisplay(); // (修正) 関数呼び出しする
|
43
|
-
return true;
|
44
39
|
},
|
45
40
|
updateResizeData: function updateResizeData () {
|
46
41
|
this.data.pointA = this.data.pointA++;
|
47
42
|
this.data.pointC = this.data.pointC++;
|
48
|
-
return true;
|
49
43
|
},
|
50
44
|
resizeEvent: function resizeEvent (event) {
|
45
|
+
console.log(event);
|
51
46
|
this.updateResizeData(); // TypeError: this.updateResizeData is not a function (修正) 関数呼び出しする
|
52
47
|
this.doDisplay(event.target); // (修正) 関数呼び出しする
|
53
|
-
return true;
|
54
|
-
}
|
48
|
+
}
|
55
49
|
};
|
56
50
|
|
51
|
+
SampleClassA.prototype.initialEvent = function initialEvent () {
|
52
|
+
this.resizeEvent = this.resizeEvent.bind(this);
|
53
|
+
this.setDefaultData(); // (修正) 関数呼び出しする
|
54
|
+
this.doDisplay(); // (修正) 関数呼び出しする
|
55
|
+
}
|
56
|
+
|
57
57
|
// (修正) 呼び出しコードを後ろに持ってくる
|
58
58
|
var sampleA1 = new SampleClassA();
|
59
59
|
//初期イベント
|
@@ -80,10 +80,34 @@
|
|
80
80
|
|
81
81
|
# (方法2) `Function.prototype.bind` を使う
|
82
82
|
|
83
|
+
一つは `onresize` のイベント定義時に `bind` する方法。
|
84
|
+
|
83
85
|
```JavaScript
|
84
86
|
jQuery(window).on('resize', sampleA1.resizeEvent.bind(sampleA1));
|
85
87
|
```
|
86
88
|
|
89
|
+
もう一つは `initialEvent()` 時に予め `bind` しておく方法(Lhankor_Mhy さんのアイデアです)。
|
90
|
+
|
91
|
+
```JavaScript
|
92
|
+
SampleClassA.prototype.initialEvent = function initialEvent () {
|
93
|
+
this.resizeEvent = this.resizeEvent.bind(this); // 予め bind しておく
|
94
|
+
this.setDefaultData();
|
95
|
+
this.doDisplay();
|
96
|
+
}
|
97
|
+
|
98
|
+
var sampleA1 = new SampleClassA();
|
99
|
+
sampleA1.initialEvent();
|
100
|
+
jQuery(window).on('resize', sampleA1.resizeEvent); // bind 済みの resizeEvent を指定する
|
101
|
+
|
102
|
+
/**
|
103
|
+
* ただし、sampleA1.resizeEvent は bind 済みの為、後から Function.prototype.call で this 値を変更できない(意図的に汎用的ではない)
|
104
|
+
* this 値を変更するためには SampleClassA.prototype.resizeEvent を経由する必要がある
|
105
|
+
*/
|
106
|
+
console.log(sampleA1.resizeEvent !== SampleClassA.prototype.resizeEvent); // true
|
107
|
+
sampleA1.resizeEvent.call(null, {target:{innerWidth: 777, innerHeight: 777}}); // Function.prototype.bind で束縛された this 値は書き換え不可能な為、TypeError にならない
|
108
|
+
SampleClassA.prototype.resizeEvent.call({updateResizeData: Function(), doDisplay: console.log.bind(console)}, {target:{innerWidth: 777, innerHeight: 777}}); // bind されていない為、this 値を変更できる
|
109
|
+
```
|
110
|
+
|
87
111
|
# (方法3) `event.data` (jQuery API) を使う
|
88
112
|
|
89
113
|
- [event.data | jQuery API Documentation](https://api.jquery.com/event.data/)
|
@@ -105,4 +129,9 @@
|
|
105
129
|
|
106
130
|
jQuery に拘りがないのなら `addEventListener` の `handleEvent` を使う方法が最もスマートだと思います。
|
107
131
|
|
132
|
+
## 更新履歴
|
133
|
+
|
134
|
+
**(2016/1/19 23:28追記)**
|
135
|
+
Lhankor_Mhy さんのアイデアをお借りして `initialEvent()` 時に予め `bind` しておくコードを追加しました。
|
136
|
+
|
108
137
|
Re: ゲストユーザーさん
|
2
setDefaultData の関数名追加
answer
CHANGED
@@ -18,7 +18,7 @@
|
|
18
18
|
this.object;
|
19
19
|
}
|
20
20
|
SampleClassA.prototype = { // (修正) SampleClassAに修正
|
21
|
-
setDefaultData: function() {
|
21
|
+
setDefaultData: function setDefaultData () {
|
22
22
|
this.data = {
|
23
23
|
pointA: 10,
|
24
24
|
pointB: 10,
|
1
SampleClassA\.prototype\.doDisplay のコード調整\(resize時の動作がわかりやすいように\)
answer
CHANGED
@@ -12,39 +12,46 @@
|
|
12
12
|
(地味に手間なのでサンプルでも動く事を確認してから掲載するようにしていただけると助かります)
|
13
13
|
|
14
14
|
```JavaScript
|
15
|
+
'use strict';
|
15
|
-
function SampleClassA() {
|
16
|
+
function SampleClassA () {
|
16
|
-
|
17
|
+
this.data;
|
17
|
-
|
18
|
+
this.object;
|
18
19
|
}
|
19
20
|
SampleClassA.prototype = { // (修正) SampleClassAに修正
|
20
|
-
|
21
|
+
setDefaultData: function() {
|
21
|
-
|
22
|
+
this.data = {
|
22
|
-
|
23
|
+
pointA: 10,
|
23
|
-
|
24
|
+
pointB: 10,
|
24
|
-
|
25
|
+
pointC: 10,
|
25
|
-
|
26
|
+
pointD: 10,
|
26
|
-
|
27
|
+
};
|
27
|
-
|
28
|
+
return true;
|
28
|
-
|
29
|
+
},
|
29
|
-
|
30
|
+
doDisplay: function doDisplay (/* [window] */) {
|
30
|
-
//
|
31
|
+
// this.object = new SampleLibrary.display(this.data); // (修正) ReferenceError の為、コメントアウト
|
32
|
+
|
33
|
+
if (arguments.length > 0) {
|
34
|
+
var window = arguments[0];
|
35
|
+
console.log(window.innerWidth, window.innerHeight);
|
36
|
+
}
|
37
|
+
console.log(this.data);
|
31
|
-
|
38
|
+
return true;
|
32
|
-
|
39
|
+
},
|
33
|
-
|
40
|
+
initialEvent: function initialEvent () {
|
34
|
-
|
41
|
+
this.setDefaultData(); // (修正) 関数呼び出しする
|
35
|
-
|
42
|
+
this.doDisplay(); // (修正) 関数呼び出しする
|
36
|
-
|
43
|
+
return true;
|
37
|
-
|
44
|
+
},
|
38
|
-
|
45
|
+
updateResizeData: function updateResizeData () {
|
39
|
-
|
46
|
+
this.data.pointA = this.data.pointA++;
|
40
|
-
|
47
|
+
this.data.pointC = this.data.pointC++;
|
41
|
-
|
48
|
+
return true;
|
42
|
-
|
49
|
+
},
|
43
|
-
|
50
|
+
resizeEvent: function resizeEvent (event) {
|
44
|
-
|
51
|
+
this.updateResizeData(); // TypeError: this.updateResizeData is not a function (修正) 関数呼び出しする
|
45
|
-
|
52
|
+
this.doDisplay(event.target); // (修正) 関数呼び出しする
|
46
|
-
|
53
|
+
return true;
|
47
|
-
|
54
|
+
},
|
48
55
|
};
|
49
56
|
|
50
57
|
// (修正) 呼び出しコードを後ろに持ってくる
|
@@ -52,7 +59,7 @@
|
|
52
59
|
//初期イベント
|
53
60
|
sampleA1.initialEvent();
|
54
61
|
//windowサイズ変更時のイベント等
|
55
|
-
|
62
|
+
jQuery(window).on('resize', sampleA1.resizeEvent);
|
56
63
|
```
|
57
64
|
|
58
65
|
## 解決法
|