Skip to content
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
14 changes: 8 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,13 +176,13 @@ domassist.html('.my-div', 'hello world'); // add html
domassist.html('.my-div', ''); // remove html
```

### closest(element, selector)
### closest(origin, selector)

Find the closest parent element that matches the given selector

#### Parameters:

`element` - {Element} the element where you want to start looking from
`origin` - {string|Element} - the element where you want to start looking from. It can be either a valid CSS selector or an Element.

`selector` - {string} A valid CSS of the element to be found.

Expand Down Expand Up @@ -262,7 +262,7 @@ domassist.modify('.my-div', {
```


### on(selector, event, callback, capture)
### on(selector, event, callback, [capture])

Attach an event to an element based on a valid CSS selector or an Element.

Expand All @@ -287,7 +287,7 @@ domassist.on('a', 'click', (e) => {
```


### off(selector, event)
### off(selector, event, [capture])

Remove an attached event.

Expand All @@ -297,20 +297,22 @@ Remove an attached event.

`event` - {string} The name of the event to remove such as `click`, `mouseenter`, or `touchend`

`[capture = false]` - {Boolean} Determines which phase to the attach the event to. Default is `false` when means the event is attached to the bubble phase. If `true` then it's attached to the capture phase.

### Example:

```javascript
domassist.off('a', 'click');
```


### once(element, event, callback, capture)
### once(selector, event, callback, capture)

Attach an event to an element to be fired once.

#### Parameters:

`selector` - {Element}
`selector` - {string|Element}

`event` - {string} The name of the event to attach such as `click`, `mouseenter`, or `touchend`

Expand Down
5 changes: 4 additions & 1 deletion lib/closest.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import matches from './matches';
import findOne from './findOne';

function closest(origin, selector) {
const el = (selector instanceof HTMLElement) ? origin : findOne(origin);

function closest(el, selector) {
let parent = el.parentElement;
while (parent.parentElement && !matches(parent, selector)) {
parent = parent.parentElement;
Expand Down
4 changes: 2 additions & 2 deletions lib/off.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import find from './find';

function off(selector, event) {
function off(selector, event, capture = false) {
if (Array.isArray(selector)) {
selector.forEach((item) => off(item, event));
selector.forEach((item) => off(item, event, capture));
}
if (!window._domassistevents) {
window._domassistevents = {};
Expand Down
6 changes: 3 additions & 3 deletions lib/once.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import on from './on';
import off from './off';

function once(el, event, run, capture = false) {
on(el, event, e => {
off(el, event);
function once(selector, event, run, capture = false) {
on(selector, event, e => {
off(selector, event, capture);
run(e);
}, capture);
}
Expand Down
46 changes: 46 additions & 0 deletions test/closest.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import domassist from '../domassist';
import test from 'tape-rollup';

function addNodes() {
return `
<div class="level-1">1
<div class="level-2">2
<div class="level-3">3
<div class="level-4">4</div>
</div>
</div>
</div>`;
}

const teardown = (el) => {
while (el.firstChild) {
el.removeChild(el.firstChild);
}
};

test('closest - element', assert => {
const el = domassist.findOne('#domassist');
const levels = 4;
domassist.html(el, addNodes());
const startEl = domassist.findOne(`.level-${levels}`);
let count = levels - 1;
while (count) {
assert.ok(domassist.closest(startEl, `.level-${count}`), `Should find element with class of level-${count}`);
--count;
}
teardown(el);
assert.end();
});

test('closest - selector', assert => {
const el = domassist.findOne('#domassist');
const levels = 4;
domassist.html(el, addNodes());
let count = levels - 1;
while (count) {
assert.ok(domassist.closest(`.level-${levels}`, `.level-${count}`), `Should find element with class of level-${count}`);
--count;
}
teardown(el);
assert.end();
});
59 changes: 2 additions & 57 deletions test/domassist.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import './on.test';
import './off.test';
import './html.test';
import './modify.test';
import './closest.test';
import './once.test';
import './show-hide.test';
import './styles.test';

Expand Down Expand Up @@ -71,37 +73,6 @@ test('matches', assert => {
assert.end();
});

test('closest', assert => {
const el = domassist.findOne('#domassist');
const levels = 4;
// clean up test dom
while (el.firstChild) {
el.removeChild(el.firstChild);
}
function addNode(num) {
const node = document.createElement('div');
node.innerText = num;
node.classList.add(`level-${num}`);
const children = el.children;
if (children.length) {
const child = domassist.findOne(`.level-${num - 1}`);
child.appendChild(node);
} else {
el.appendChild(node);
}
}
for (let i = 0; i < levels; i += 1) {
addNode(i + 1);
}
const startEl = domassist.findOne(`.level-${levels}`);
let count = levels - 1;
while (count) {
assert.ok(domassist.closest(startEl, `.level-${count}`), `Should find element with class of level-${count}`);
--count;
}
assert.end();
});

test('Events - delegate', assert => {
const el = domassist.findOne('#domassist');

Expand All @@ -120,32 +91,6 @@ test('Events - delegate', assert => {
page.sendEvent('click', pos.left + pos.width / 2, pos.top + pos.height / 2);
});

test('Events - once', assert => {
const el = domassist.findOne('#domassist');

el.innerHTML = `
<a href="#">Click</a>
`;

const link = domassist.findOne('a', el);
const pos = link.getBoundingClientRect();

let clicks = 0;

domassist.once(link, 'click', e => {
clicks++;
});

page.sendEvent('click', pos.left + pos.width / 2, pos.top + pos.height / 2);
page.sendEvent('click', pos.left + pos.width / 2, pos.top + pos.height / 2);
page.sendEvent('click', pos.left + pos.width / 2, pos.top + pos.height / 2);

setTimeout(() => {
assert.equal(clicks, 1, 'Only fired once');
assert.end();
}, 500);
});

test('Events - hover', assert => {
const el = domassist.findOne('#domassist');

Expand Down
63 changes: 63 additions & 0 deletions test/once.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import domassist from '../domassist';
import test from 'tape-rollup';

const page = window.phantom.page;

const teardown = (el) => {
while (el.firstChild) {
el.removeChild(el.firstChild);
}
};

test('Events - once with Element', assert => {
const el = domassist.findOne('#domassist');

el.innerHTML = `
<a href="#">Click</a>
`;

const link = domassist.findOne('a', el);
const pos = link.getBoundingClientRect();

let clicks = 0;

domassist.once(link, 'click', e => {
clicks++;
});

page.sendEvent('click', pos.left + pos.width / 2, pos.top + pos.height / 2);
page.sendEvent('click', pos.left + pos.width / 2, pos.top + pos.height / 2);
page.sendEvent('click', pos.left + pos.width / 2, pos.top + pos.height / 2);

setTimeout(() => {
assert.equal(clicks, 1, 'Element only fired once');
teardown(el);
assert.end();
}, 500);
});

test('Events - once with selector', assert => {
const el = domassist.findOne('#domassist');

el.innerHTML = `
<a href="#">Click</a>
`;
const link = domassist.findOne('a', el);
const pos = link.getBoundingClientRect();

let clicks = 0;

domassist.once('a', 'click', e => {
clicks++;
});

page.sendEvent('click', pos.left + pos.width / 2, pos.top + pos.height / 2);
page.sendEvent('click', pos.left + pos.width / 2, pos.top + pos.height / 2);
page.sendEvent('click', pos.left + pos.width / 2, pos.top + pos.height / 2);

setTimeout(() => {
assert.equal(clicks, 1, 'Selector only fired once');
teardown(el);
assert.end();
}, 500);
});