{"id":16894277,"url":"https://github.com/jsor/domestique","last_synced_at":"2025-07-16T21:07:27.540Z","repository":{"id":57214949,"uuid":"144012799","full_name":"jsor/domestique","owner":"jsor","description":"A modular DOM helper library.","archived":false,"fork":false,"pushed_at":"2021-07-19T12:19:57.000Z","size":733,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-23T07:34:11.162Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jsor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-08-08T12:47:53.000Z","updated_at":"2025-02-06T07:01:56.000Z","dependencies_parsed_at":"2022-08-24T21:41:44.276Z","dependency_job_id":null,"html_url":"https://github.com/jsor/domestique","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsor%2Fdomestique","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsor%2Fdomestique/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsor%2Fdomestique/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jsor%2Fdomestique/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jsor","download_url":"https://codeload.github.com/jsor/domestique/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248409856,"owners_count":21098771,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-13T17:18:13.056Z","updated_at":"2025-04-11T13:33:31.682Z","avatar_url":"https://github.com/jsor.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"Domestique\n==========\n\nA modular DOM helper library.\n\n[![Build Status](https://travis-ci.org/jsor/domestique.svg?branch=main)](https://travis-ci.org/jsor/domestique)\n[![BrowserStack Status](https://automate.browserstack.com/badge.svg?badge_key=cTVLQkMzR2c3K3RyczhNcFhRdDBCcVlBcTNmOXB4cnRsbXM3UE9FTmsrcz0tLUl2c3cwRmJKRGxvNnozRGtnSXBFaWc9PQ==--3dac58a116961a1e6c7c0aa0de2780e9cc5cd48c)](https://automate.browserstack.com/public-build/cTVLQkMzR2c3K3RyczhNcFhRdDBCcVlBcTNmOXB4cnRsbXM3UE9FTmsrcz0tLUl2c3cwRmJKRGxvNnozRGtnSXBFaWc9PQ==--3dac58a116961a1e6c7c0aa0de2780e9cc5cd48c)\n\nInstallation\n------------\n\n```bash\nnpm install domestique\n```\n\n\u003e **Note:** This library is written as ES2015 code and published as such to\n  [npm](https://www.npmjs.com/package/domestique).\n  Read the [Compatibility](#compatibility) section for more information.\n\nUsage\n-----\n\n```javascript\nimport {\n     // Dimension\n    inViewport,\n    scrollbarSize,\n    viewportHeight,\n    viewportWidth,\n\n    // Element\n    activeElement,\n    create,\n    addClass,\n    removeClass,\n    hasClass,\n    data,\n    focus,\n    isFocusable,\n    isTabbable,\n    parents,\n    render,\n\n    // Event\n    delegate,\n    dispatch,\n    on,\n    onTransitionEnd,\n    off,\n    ready,\n\n    // Query\n    closest,\n    find,\n    focusable,\n    matches,\n    select,\n    selectAll,\n    tabbable\n} from 'domestique';\n```\n\nAPI\n---\n\n* [Dimension](#dimension)\n  * [inViewport()](#inviewport)\n  * [scrollbarSize()](#scrollbarsize)\n  * [viewportHeight()](#viewportheight)\n  * [viewportWidth()](#viewportwidth)\n* [Element](#element)\n  * [activeElement()](#activeelement)\n  * [create()](#create)\n  * [addClass()](#addclass)\n  * [removeClass()](#removeclass)\n  * [hasClass()](#hasclass)\n  * [data()](#data)\n  * [focus()](#focus)\n  * [isFocusable()](#isfocusable)\n  * [isTabbable()](#istabbable)\n  * [parents()](#parents)\n  * [render()](#render)\n* [Event](#event)\n  * [delegate()](#delegate)\n  * [dispatch()](#dispatch)\n  * [on()](#on)\n  * [onTransitionEnd()](#ontransitionend)\n  * [off()](#off)\n  * [ready()](#ready)\n* [Query](#query)\n  * [closest()](#closest)\n  * [find()](#find)\n  * [focusable()](#focusable)\n  * [matches()](#matches)\n  * [select()](#select)\n  * [selectAll()](#selectall)\n  * [tabbable()](#tabbable)\n\n### Dimension\n\n#### inViewport()\n\n```\ninViewport(element: Element): bool\n```\n\nReturns `true` if any part of an element is in the viewport.\n\n##### Example\n\n```javascript\nconst inVp = inViewport(element);\n```\n\n#### scrollbarSize()\n\n```\nscrollbarSize(): number\n```\n\nReturns the size of the scrollbar in pixels.\n\n##### Example\n\n```javascript\nconst size = scrollbarSize();\n```\n\n#### viewportHeight()\n\n```\nviewportHeight(): number\n```\n\nReturns the viewport height.\n\n\u003e **Note:** The height represent the CSS viewport height\n  ([@media (height)](https://www.w3.org/TR/mediaqueries-4/#height)) including the\n  size of a rendered scroll bar (if any).\n\n##### Example\n\n```javascript\nconst vpHeight = viewportHeight();\n```\n\n#### viewportWidth()\n\n```\nviewportWidth(): number\n```\n\nReturns the viewport width.\n\n\u003e **Note:** The width represent the CSS viewport width\n  ([@media (width)](https://www.w3.org/TR/mediaqueries-4/#width)) including the\n  size of a rendered scroll bar (if any).\n\n##### Example\n\n```javascript\nconst vpWidth = viewportWidth();\n```\n\n### Element\n\n#### activeElement()\n\n```\nactiveElement(): Element\n```\n\nReturns the element that currently has focus.\n\n##### Example\n\n```javascript\nconst element = activeElement();\n```\n\n#### create()\n\n```\ncreate(html: string): Element\n```\n\nCreates a DOM element from a HTML string. If it's already a DOM node, the node\nis returned as is.\n\n##### Example\n\n```javascript\nconst element = create('\u003cdiv/\u003e');\n```\n\n#### addClass()\n\n```\naddClass(element: Element, className: string): void\n```\n\nAdds a class (or multiple classes separated by space) to an element.\n\n##### Example\n\n```javascript\naddClass(element, 'my-class');\naddClass(element, 'my-class my-other-class');\n```\n\n#### removeClass()\n\n```\nremoveClass(element: Element, className: string): void\n```\n\nRemoves a class (or multiple classes separated by space) from an element.\n\n##### Example\n\n```javascript\nremoveClass(element, 'my-class');\nremoveClass(element, 'my-class my-other-class');\n```\n\n#### hasClass()\n\n```\nhasClass(element: Element, className: string): bool\n```\n\nChecks whether an element has a class (or multiple classes separated by space).\n\n##### Example\n\n```javascript\nconst hasClass = hasClass(element, 'my-class');\nconst hasAllClasses = hasClass(element, 'my-class my-other-class');\n```\n\n#### data()\n\n```\ndata(element: Element, name: string): bool\n```\n\nReads and parses data from an data-* attribute.\n\n##### Example\n\n```html\n\u003cdiv\n   data-string=\"string\"\n   data-true=\"true\"\n   data-false=\"false\"\n   data-null=\"null\"\n   data-integer=\"1\"\n   data-float=\"1.2\"\n   data-json-object=\"{\u0026quot;foo\u0026quot;: \u0026quot;bar\u0026quot;}\"\n   data-json-array=\"[\u0026quot;foo\u0026quot;]\"\n\u003e\u003c/div\u003e\n```\n\n```javascript\nconst stringValue = data(element, 'string');\nconst trueValue = data(element, 'true');\nconst falseValue = data(element, 'false');\nconst nullValue = data(element, 'null');\nconst integerValue = data(element, 'integer');\nconst floatValue = data(element, 'float');\nconst jsonObjectValue = data(element, 'json-object');\nconst jsonArrayValue = data(element, 'json-array');\n```\n\n#### focus()\n\n```\nfocus(element: Element[, options: object]): void\n```\n\nShifts focus to an element.\n\n##### Example\n\n```javascript\nfocus(element);\n```\n\nBrowsers scroll the focused element into view. `focus()` provides an option\n`restoreScrollPosition` to restore scroll positions of all scroll containers of\nthe focused element to the state before the element got focus.\n\n##### Example\n\n```javascript\nfocus(element, {\n    restoreScrollPosition: true\n});\n```\n\n#### isFocusable()\n\n```\nisFocusable(element: Element): bool\n```\n\nChecks whether an element is focusable.\n\nUnlike [`isTabbable()`](#istabbable), the function also returns `true` for\nelements which are not focusable by the keyboard, but only by script \n(`element.focus()`) and possibly the mouse (or pointer). Usually, those are\nelements with a negative `tabindex` attribute value, like `-1`.\n\n##### Example\n\n```javascript\nconst isFocusableElement = isFocusable(element);\n```\n\n#### isTabbable()\n\n```\nisTabbable(element: Element): bool\n```\n\nChecks whether an element is tabbable.\n\nUnlike [`isFocusable()`](#isfocusable), the function returns `true` **only** for\nelements which are focusable by the keyboard (by pressing the \u003ckbd\u003eTAB\u003c/kbd\u003e and\n\u003ckbd\u003eSHIFT\u003c/kbd\u003e+\u003ckbd\u003eTAB\u003c/kbd\u003e keys). Elements that are only focusable by\nscript (`element.focus()`) and possibly the mouse (or pointer) are excluded.\n\n##### Example\n\n```javascript\nconst isFocusableElement = isFocusable(element);\n```\n\n#### parents()\n\n```\nparents(element: Element): Array\n```\n\nReturns an array of the element's parent elements.\n\n##### Example\n\n```javascript\nconst parentElements = parents(element);\n```\n\n#### render()\n\n```\nrender(html: string): object\n```\n\nCreates and returns DOM element references from a HTML string.\n\nElements must have a `ref` attribute with the reference name. The value of this\nattribute will get mapped to the property name of the returned object.\n\n##### Example\n\n```javascript\nconst {list, 'list-items': listItems} = render(`\n\u003cul ref=\"list\"\u003e\n    \u003cli ref=\"list-items[]\"\u003e\u003c/l\u003e\n    \u003cli ref=\"list-items[]\"\u003e\u003c/l\u003e\n\u003c/ul\u003e\n`);\n```\n\n\u003e **Note:** The `ref` attributes will be removed from the returned elements.\n\n### Event\n\n#### delegate()\n\n```\ndelegate(target: EventTarget, type: string, selector: string, listener: EventListener[, options: object]): function\n```\n\nRegisters a `listener` for the event `type` on `target` with `options` that\nprocesses events from descendant elements of `target` matching the specified\n`selector`.\n\nThe function returns another function which can be used to unregister the event listener.\n\n##### Example\n\n```javascript\nconst listener = function (e, target) {\n    target.classList.add('my-target-clicked');\n\n    console.log('My Button clicked');\n};\nconst options = {\n    passive: true\n};\n\nconst remove = delegate(\n    document, // Listen on document\n    'click',\n    '.my-button',\n    listener,\n    options\n);\n\nremove(); // Remove event listener\n```\n\n#### dispatch()\n\n```\ndispatch(target: EventTarget, type: string[, eventInit: CustomEventInit]): bool\n```\n\nDispatches a [CustomEvent](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent) \n`type` at the specified `target` optionally using the `eventInit` options.\n\nThe function returns `false` if the event is cancelable and at least one of the\nevent handlers which handled this event called `Event.preventDefault()`.\nOtherwise it returns `true`.\n\n##### Example\n\n```javascript\nconst clickNotCancelled = dispatch(document, 'click');\n\nconst myEventNotCancelled = dispatch(\n    document.querySelector('.my-button'),\n    'my:event',\n    {\n        bubbles: true,\n        cancelable: true,\n        detail: {\n            foo: 'bar'\n        }\n    }\n);\n```\n\n#### on()\n\n```\non(target: EventTarget, type: string, listener: EventListener[, options: object]): function\n```\n\nRegisters a `listener` for the event `type` on `target` with `options`.\n\n`options` is **always** an object that specifies characteristics about the event\nlistener, see https://developer.mozilla.org/docs/Web/API/EventTarget/addEventListener.\n\nIf one of the options isn't supported by the browser, the behavior is as \nfollows:\n\n* `capture`: Always supported.\n* `once`: Will be polyfilled.\n* `passive`: Will be ignored.\n\nThe function returns another function which can be used to unregister the event listener.\n\n##### Example\n\n```javascript\nconst target = document.querySelector('.my-button');\nconst listener = function () {\n    console.log('My Button clicked');\n};\nconst options = {\n    once: true\n};\n\nconst remove = on(\n    target, \n    'click',\n    listener,\n    options\n);\n\nremove(); // Remove event listener\n```\n\n#### onTransitionEnd()\n\n```\nonTransitionEnd(target: EventTarget, listener: EventListener): function\n```\n\nRegisters a one-time `listener` for the `transitionend` event on `target`.\n\nThe function returns another function which can be used to unregister the event listener.\n\n##### Example\n\n```javascript\nconst target = document.querySelector('.my-element');\nconst listener = function (target) {\n    target.classList.add('transition-ended');\n\n    console.log('Transition ended');\n};\n\nconst remove = onTransitionEnd(\n    target,\n    listener\n);\n\nremove(); // Remove event listener\n```\n\n#### off()\n\n```\noff(target: EventTarget, type: string, listener: EventListener[, options: object]): void\n```\n\nRemoves a listener previously registered via `on()`.\n\n##### Example\n\n```javascript\noff(\n    target, \n    'click',\n    listener,\n    options\n);\n```\n\n#### ready()\n\n```\nready(listener: function): void\n```\n\nRegisters a listener to be called once the DOM is ready.\n\nUnlike `DOMContentLoaded`, this also works when called after the DOM was loaded.\n\n##### Example\n\n```javascript\nready(function () {\n    console.log('DOM is ready!');\n});\n```\n\n### Query\n\n#### closest()\n\n```\nclosest(element: Element, selector: string): Element\n```\n\nReturns the closest ancestor of the `element` (or the `element` itself) which\nmatches the specified `selector`. \n\nIf there isn't such an ancestor, it returns `null`.\n\n##### Example\n\n```javascript\nconst closestParagraph = closest(element, 'p');\n```\n\n#### find()\n\n*Deprecated in favor of [selectAll()](#selectall). To be removed in 2.0.*\n\n```\nfind(selector: string[, element: Element]): array\n```\n\nReturns an `array` of elements matching the specified `selector` which are\ndescendants of the `document` or the `element` specified as optional second \nargument.\n\n##### Example\n\n```javascript\nconst paragraphs = find('p');\n\nconst spansInsideFirstParagraph = find('span', paragraphs[0]);\n```\n\n#### focusable()\n\n```\nfocusable([element: Element]): array\n```\n\nReturns an `array` of focusable elements in the DOM which are\ndescendants of the `document` or the `element` specified as optional first\nargument.\n\nUnlike [`tabbable()`](#tabbable), the array also includes elements which are not\nfocusable by the keyboard, but only by script (`element.focus()`) and possibly\nthe mouse (or pointer). Usually, those are elements with a negative `tabindex`\nattribute value, like `-1`.\n\n\u003e **Note:** The elements in the array are ordered according to the \n  [sequential focus navigation order](https://html.spec.whatwg.org/multipage/interaction.html#sequential-focus-navigation)\n  which may be different from the DOM order.\n\n##### Example\n\n```javascript\nconst focusableElements = focusable();\n```\n\n#### matches()\n\n```\nmatches(element: Element, selector: string): boolean\n```\n\nReturns `true` if the `element` would be selected by the specified `selector`, \n`false` otherwise.\n\n##### Example\n\n```javascript\nconst isParagraph = matches(element, 'p');\n```\n\n#### select()\n\n```\nselect(context: Element, selector: string): Element\n```\n\nReturns the descendant of `context` (`document` or `Element`) which matches the \nspecified `selector`. If no element could be found, `null` is returned.\n\n##### Example\n\n```javascript\nconst paragraph = select(document, 'p');\n\nconst spanInsideParagraph = select(paragraph, 'span');\n```\n\n#### selectAll()\n\n```\nselect(context: Element, selector: string): array\n```\n\nReturns an `array` of all descendants of `context` (`document` or `Element`)\nwhich match the specified `selector`.\n\n##### Example\n\n```javascript\nconst allParagraphs = selectAll(document, 'p');\n\nconst allSpansInsideFirstParagraph = selectAll(paragraph[0], 'span');\n```\n\n#### tabbable()\n\n```\ntabbable([element: Element]): array\n```\n\nReturns an `array` of keyboard focusable (\"tabbable\") elements in the DOM which\nare descendants of the `document` or the `element` specified as optional first\nargument.\n\nUnlike [`focusable()`](#focusable), the array **only** includes elements which\nare focusable by the keyboard (by pressing the \u003ckbd\u003eTAB\u003c/kbd\u003e and\n\u003ckbd\u003eSHIFT\u003c/kbd\u003e+\u003ckbd\u003eTAB\u003c/kbd\u003e keys). Elements that are only focusable by\nscript (`element.focus()`) and possibly the mouse (or pointer) are excluded.\n\n\u003e **Note:** The elements in the array are ordered according to the \n  [sequential focus navigation order](https://html.spec.whatwg.org/multipage/interaction.html#sequential-focus-navigation)\n  which may be different from the DOM order.\n\n##### Example\n\n```javascript\nconst tabbableElements = tabbable();\n```\n\nCompatibility\n-------------\n\nThis library is written as ES2015 code and published as such to\n[npm](https://www.npmjs.com/package/domestique).\nIt is compatible with\n[modern browsers](http://browserl.ist/?q=Chrome+%3E%3D+60%2C+Edge+%3E%3D+15%2C+Firefox+%3E%3D+54%2C+iOS+%3E%3D+10.3%2C+Safari+%3E%3D+10.1)\nwhich natively support `\u003cscript type=\"module\"\u003e`.\n\nIf support for older browsers is required, code from `domestique` must be\ntranspiled, eg. by using [Babel](https://github.com/babel/babel).\n\nMost bundlers (like [Webpack](https://github.com/babel/babel-loader#usage) and\n[Rollup](https://github.com/rollup/rollup-plugin-babel#usage)) recommend\nto not transpile anything from the `node_modules/` directory. It must be\nensured, that code from `domestique` is **not** excluded from transpilation.\n\nIf you're using Webpack and Babel, that could look like:\n\n```javascript\n{\n    module: {\n        rules: [\n            {\n                test: /\\.js$/,\n                exclude: /node_modules\\/(?!domestique)/,\n                loader: 'babel-loader'\n            }\n        ]\n    }\n}\n```\n\nAfter transpilation, `domestique` supports the\n[most common browsers including IE 10](http://browserl.ist/?q=defaults%2C+IE+10)\nwithout polyfills.\n\nThank You\n---------\n\n* [BrowserStack](https://www.browserstack.com/) for providing free VMs for automated testing.\n* [GitHub](https://github.com/) for providing free Git repository hosting.\n* [npm](https://www.npmjs.com/) for providing the package manager for JavaScript.\n* [TravisCI](https://travis-ci.org/) for providing a free build server.\n\nLicense\n-------\n\nCopyright (c) 2018-2021 Jan Sorgalla.\nReleased under the [MIT](LICENSE) license.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsor%2Fdomestique","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjsor%2Fdomestique","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjsor%2Fdomestique/lists"}