Skip to content
This repository has been archived by the owner on Aug 9, 2022. It is now read-only.

Configurable tolerance proposal #52

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,17 @@ var os = new OnScreen({
The instance, `os`, has the following options:

`options.tolerance` is the number of pixels an element is allowed to enter its container boundaries before calling its callback. Defaults to `0`.
May be configured as a number which will be used for all boundaries or as an object containing tolerance values for each boundary. Missing property values also default to `0`.
```javascript
var os = new OnScreen({
tolerance: {
top: 10,
right: 20,
bottom: 30,
left: 40
}
});
```

`options.debounce` is the number of milliseconds to wait before calling an element's callback after the user has stopped scrolling. Defaults to `100`.

Expand Down
16 changes: 9 additions & 7 deletions lib/helpers/in-container.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
* @param {node} element The DOM node you want to check
* @return {boolean} A boolean value that indicates wether is on or off the container.
*/
function inContainer(el, options = { tolerance: 0, container: '' }) {
function inContainer(el,
options = { tolerance: { top: 0, right: 0, bottom: 0, left: 0 },
container: '' }) {
if (!el) {
throw new Error('You should specify the element you want to test');
}
Expand All @@ -15,7 +17,7 @@ function inContainer(el, options = { tolerance: 0, container: '' }) {
}
if (typeof options === 'string') {
options = {
tolerance: 0,
tolerance: { top: 0, right: 0, bottom: 0, left: 0 },
container: document.querySelector(options)
};
}
Expand All @@ -24,7 +26,7 @@ function inContainer(el, options = { tolerance: 0, container: '' }) {
}
if (options instanceof HTMLElement) {
options = {
tolerance: 0,
tolerance: { top: 0, right: 0, bottom: 0, left: 0 },
container: options
};
}
Expand All @@ -36,19 +38,19 @@ function inContainer(el, options = { tolerance: 0, container: '' }) {

return (
// // Check bottom boundary
(el.offsetTop + el.clientHeight) - options.tolerance >
(el.offsetTop + el.clientHeight) - options.tolerance.bottom >
options.container.scrollTop &&

// Check right boundary
(el.offsetLeft + el.clientWidth) - options.tolerance >
(el.offsetLeft + el.clientWidth) - options.tolerance.right >
options.container.scrollLeft &&

// Check left boundary
el.offsetLeft + options.tolerance <
el.offsetLeft + options.tolerance.left <
containerRect.width + options.container.scrollLeft &&

// // Check top boundary
el.offsetTop + options.tolerance <
el.offsetTop + options.tolerance.top <
containerRect.height + options.container.scrollTop
);
}
Expand Down
10 changes: 5 additions & 5 deletions lib/helpers/in-viewport.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* @param {node} element The DOM node you want to check
* @return {boolean} A boolean value that indicates wether is on or off the viewport.
*/
function inViewport(el, options = { tolerance: 0 }) {
function inViewport(el, options = { tolerance: { top: 0, right: 0, bottom: 0, left: 0 } }) {
if (!el) {
throw new Error('You should specify the element you want to test');
}
Expand All @@ -18,17 +18,17 @@ function inViewport(el, options = { tolerance: 0 }) {

return (
// Check bottom boundary
elRect.bottom - options.tolerance > 0 &&
elRect.bottom - options.tolerance.bottom > 0 &&

// Check right boundary
elRect.right - options.tolerance > 0 &&
elRect.right - options.tolerance.right > 0 &&

// Check left boundary
elRect.left + options.tolerance < (window.innerWidth ||
elRect.left + options.tolerance.left < (window.innerWidth ||
document.documentElement.clientWidth) &&

// Check top boundary
elRect.top + options.tolerance < (window.innerHeight ||
elRect.top + options.tolerance.top < (window.innerHeight ||
document.documentElement.clientHeight)
);
}
Expand Down
33 changes: 31 additions & 2 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,39 @@ function OnScreen(options = { tolerance: 0, debounce: 100, container: window })
},
tolerance: {
get() {
return parseInt(options.tolerance, 10) || 0;
if (typeof options.tolerance === 'number') {
const tolerance = parseInt(options.tolerance, 10) || 0;
return {
top: tolerance,
right: tolerance,
bottom: tolerance,
left: tolerance
};
}

return {
top: parseInt(options.tolerance.top, 10) || 0,
right: parseInt(options.tolerance.right, 10) || 0,
bottom: parseInt(options.tolerance.bottom, 10) || 0,
left: parseInt(options.tolerance.left, 10) || 0
};
},
set(value) {
options.tolerance = value;
if (typeof value === 'number') {
options.tolerance = {
top: value,
right: value,
bottom: value,
left: value
};
} else {
options.tolerance = {
top: value.top || 0,
right: value.right || 0,
bottom: value.bottom || 0,
left: value.left || 0
};
}
}
}
});
Expand Down
54 changes: 51 additions & 3 deletions test/index_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,65 @@ describe('Instantiation', () => {
it('should create an instance with default settings', () => {
const instance = new OnScreen();

expect(instance.options.tolerance).to.equal(0);
['top', 'right', 'bottom', 'left'].forEach((prop) => {
expect(instance.options.tolerance[prop]).to.equal(0);
});
expect(instance.options.debounce).to.equal(100);
});

it('should create an instance with custom settings', () => {
it('should create an instance with custom settings and single tolerance value', () => {
const instance = new OnScreen({
tolerance: 50,
debounce: 50
});

expect(instance.options.tolerance).to.equal(50);
['top', 'right', 'bottom', 'left'].forEach((prop) => {
expect(instance.options.tolerance[prop]).to.equal(50);
});
expect(instance.options.debounce).to.equal(50);
});

it('should create an instance with custom settings and multiple tolerance values', () => {
const instance = new OnScreen({
tolerance: {
top: 150,
right: 250,
bottom: 350,
left: 450
},
debounce: 50
});

const expectedTolerances = {
top: 150,
right: 250,
bottom: 350,
left: 450
};
['top', 'right', 'bottom', 'left'].forEach((prop) => {
expect(instance.options.tolerance[prop]).to.equal(expectedTolerances[prop]);
});
expect(instance.options.debounce).to.equal(50);
});

it('should create an instance with custom settings and some tolerances missing', () => {
const instance = new OnScreen({
tolerance: {
top: 150,
right: 250
},
debounce: 50
});

const expectedTolerances = {
top: 150,
right: 250,
bottom: 0,
left: 0
};
['top', 'right', 'bottom', 'left'].forEach((prop) => {
expect(instance.options.tolerance[prop]).to.equal(expectedTolerances[prop]);
});
expect(instance.options.debounce).to.equal(50);
});
});
Expand Down