Skip to content

Commit a96b855

Browse files
authored
Merge pull request danbovey#196 from timbielawski/feature/passive-event-listeners
Feature/passive event listeners
2 parents 777d63b + 7dc2dbe commit a96b855

File tree

3 files changed

+92
-18
lines changed

3 files changed

+92
-18
lines changed

dist/InfiniteScroll.js

Lines changed: 46 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ var InfiniteScroll = (function(_Component) {
9696
);
9797

9898
_this.scrollListener = _this.scrollListener.bind(_this);
99+
_this.eventListenerOptions = _this.eventListenerOptions.bind(_this);
100+
_this.mousewheelListener = _this.mousewheelListener.bind(_this);
99101
return _this;
100102
}
101103

@@ -104,6 +106,7 @@ var InfiniteScroll = (function(_Component) {
104106
key: 'componentDidMount',
105107
value: function componentDidMount() {
106108
this.pageLoaded = this.props.pageStart;
109+
this.options = this.eventListenerOptions();
107110
this.attachScrollListener();
108111
}
109112
},
@@ -126,8 +129,40 @@ var InfiniteScroll = (function(_Component) {
126129
value: function componentWillUnmount() {
127130
this.detachScrollListener();
128131
this.detachMousewheelListener();
129-
}
132+
},
133+
},
134+
{
135+
key: 'isPassiveSupported',
136+
value: function isPassiveSupported() {
137+
var passive = false;
138+
139+
var testOptions = {
140+
get passive() {
141+
passive = true;
142+
},
143+
};
130144

145+
try {
146+
document.addEventListener('test', null, testOptions);
147+
} catch (e) {
148+
// ignore
149+
}
150+
return passive;
151+
},
152+
},
153+
{
154+
key: 'eventListenerOptions',
155+
value: function eventListenerOptions() {
156+
var options = false;
157+
158+
if (this.isPassiveSupported()) {
159+
options = {
160+
useCapture: this.props.useCapture,
161+
passive: this.props.passive,
162+
};
163+
}
164+
return options;
165+
}
131166
// Set a defaut loader for all your `InfiniteScroll` components
132167
},
133168
{
@@ -147,7 +182,7 @@ var InfiniteScroll = (function(_Component) {
147182
scrollEl.removeEventListener(
148183
'mousewheel',
149184
this.mousewheelListener,
150-
this.props.useCapture
185+
this.options ? this.options : this.props.useCapture
151186
);
152187
}
153188
},
@@ -162,12 +197,12 @@ var InfiniteScroll = (function(_Component) {
162197
scrollEl.removeEventListener(
163198
'scroll',
164199
this.scrollListener,
165-
this.props.useCapture
200+
this.options ? this.options : this.props.useCapture
166201
);
167202
scrollEl.removeEventListener(
168203
'resize',
169204
this.scrollListener,
170-
this.props.useCapture
205+
this.options ? this.options : this.props.useCapture
171206
);
172207
}
173208
},
@@ -205,17 +240,17 @@ var InfiniteScroll = (function(_Component) {
205240
scrollEl.addEventListener(
206241
'mousewheel',
207242
this.mousewheelListener,
208-
this.props.useCapture
243+
this.options ? this.options : this.props.useCapture,
209244
);
210245
scrollEl.addEventListener(
211246
'scroll',
212247
this.scrollListener,
213-
this.props.useCapture
248+
this.options ? this.options : this.props.useCapture,
214249
);
215250
scrollEl.addEventListener(
216251
'resize',
217252
this.scrollListener,
218-
this.props.useCapture
253+
this.options ? this.options : this.props.useCapture
219254
);
220255

221256
if (this.props.initialLoad) {
@@ -228,7 +263,10 @@ var InfiniteScroll = (function(_Component) {
228263
value: function mousewheelListener(e) {
229264
// Prevents Chrome hangups
230265
// See: https://stackoverflow.com/questions/47524205/random-high-content-download-time-in-chrome/47684257#47684257
231-
if (e.deltaY === 1) {
266+
if (
267+
e.deltaY === 1 &&
268+
(!this.props.passive || !this.isPassiveSupported())
269+
) {
232270
e.preventDefault();
233271
}
234272
}

package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,7 @@
99
"url": "git://github.com/CassetteRocks/react-infinite-scroller.git"
1010
},
1111
"scripts": {
12-
"build":
13-
"mkdirp dist && babel src/InfiniteScroll.js --out-file dist/InfiniteScroll.js",
12+
"build": "mkdirp dist && babel src/InfiniteScroll.js --out-file dist/InfiniteScroll.js",
1413
"prepublish": "npm run build",
1514
"test": "nyc npm run spec",
1615
"spec": "_mocha -R spec ./test/test_helper.js --recursive test/*_test.js",
@@ -23,7 +22,11 @@
2322
"git add"
2423
]
2524
},
26-
"keywords": ["infinite", "scroll", "react"],
25+
"keywords": [
26+
"infinite",
27+
"scroll",
28+
"react"
29+
],
2730
"author": "CassetteRocks",
2831
"license": "MIT",
2932
"bugs": {

src/InfiniteScroll.js

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,13 @@ export default class InfiniteScroll extends Component {
3636
super(props);
3737

3838
this.scrollListener = this.scrollListener.bind(this);
39+
this.eventListenerOptions = this.eventListenerOptions.bind(this);
40+
this.mousewheelListener = this.mousewheelListener.bind(this);
3941
}
4042

4143
componentDidMount() {
4244
this.pageLoaded = this.props.pageStart;
45+
this.options = this.eventListenerOptions();
4346
this.attachScrollListener();
4447
}
4548

@@ -60,6 +63,36 @@ export default class InfiniteScroll extends Component {
6063
this.detachMousewheelListener();
6164
}
6265

66+
isPassiveSupported() {
67+
let passive = false;
68+
69+
const testOptions = {
70+
get passive() {
71+
passive = true;
72+
}
73+
};
74+
75+
try {
76+
document.addEventListener('test', null, testOptions);
77+
document.removeEventListener('test', null, testOptions);
78+
} catch (e) {
79+
// ignore
80+
}
81+
return passive;
82+
}
83+
84+
eventListenerOptions() {
85+
let options = this.props.useCapture;
86+
87+
if (this.isPassiveSupported()) {
88+
options = {
89+
useCapture: this.props.useCapture,
90+
passive: true
91+
};
92+
}
93+
return options;
94+
}
95+
6396
// Set a defaut loader for all your `InfiniteScroll` components
6497
setDefaultLoader(loader) {
6598
this.defaultLoader = loader;
@@ -74,7 +107,7 @@ export default class InfiniteScroll extends Component {
74107
scrollEl.removeEventListener(
75108
'mousewheel',
76109
this.mousewheelListener,
77-
this.props.useCapture
110+
this.options ? this.options : this.props.useCapture
78111
);
79112
}
80113

@@ -87,12 +120,12 @@ export default class InfiniteScroll extends Component {
87120
scrollEl.removeEventListener(
88121
'scroll',
89122
this.scrollListener,
90-
this.props.useCapture
123+
this.options ? this.options : this.props.useCapture
91124
);
92125
scrollEl.removeEventListener(
93126
'resize',
94127
this.scrollListener,
95-
this.props.useCapture
128+
this.options ? this.options : this.props.useCapture
96129
);
97130
}
98131

@@ -124,17 +157,17 @@ export default class InfiniteScroll extends Component {
124157
scrollEl.addEventListener(
125158
'mousewheel',
126159
this.mousewheelListener,
127-
this.props.useCapture
160+
this.options ? this.options : this.props.useCapture
128161
);
129162
scrollEl.addEventListener(
130163
'scroll',
131164
this.scrollListener,
132-
this.props.useCapture
165+
this.options ? this.options : this.props.useCapture
133166
);
134167
scrollEl.addEventListener(
135168
'resize',
136169
this.scrollListener,
137-
this.props.useCapture
170+
this.options ? this.options : this.props.useCapture
138171
);
139172

140173
if (this.props.initialLoad) {
@@ -145,7 +178,7 @@ export default class InfiniteScroll extends Component {
145178
mousewheelListener(e) {
146179
// Prevents Chrome hangups
147180
// See: https://stackoverflow.com/questions/47524205/random-high-content-download-time-in-chrome/47684257#47684257
148-
if (e.deltaY === 1) {
181+
if (e.deltaY === 1 && !this.isPassiveSupported()) {
149182
e.preventDefault();
150183
}
151184
}

0 commit comments

Comments
 (0)