{"slug": "accessible-nouislider", "title": "Accessible noUiSlider", "summary": "The article describes a JavaScript plugin called `noUiSliderA11y.js` that adds an accessibility layer to the noUiSlider range slider. It enhances the slider by adding ARIA attributes (such as `role=\"slider\"`, `aria-valuemin`, `aria-valuemax`, and `aria-valuenow`) and enabling keyboard navigation, allowing users to adjust the slider value using arrow keys, page up/down, and home/end keys.", "body_md": "noUiSliderA11y.js\n\n      This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.\n      \nLearn more about bidirectional Unicode characters\n\n \n    Show hidden characters\n\n/**\n\n *\tAdds an accessibility layer to the default noUiSlider.\n\n *\n\n *\t\n@see\n $.fn.noUiSlider()\n\n */\n\n$\n.\nfn\n.\nnoUiSliderA11y\n \n=\n \nfunction\n(\noptions\n,\n \nrebuild\n)\n \n{\n\n \nvar\n \nslider\n \n=\n \nthis\n;\n\n \nif\n \n(\n!\n(\n'noUiSlider'\n \nin\n \nslider\n)\n)\n \n{\n\n \nthrow\n \nnew\n \nError\n(\n'noUiSlider is not loaded.'\n)\n;\n\n \n}\n\n \n// step must be defined in order for the keyboard navigation to work\n\n \nif\n \n(\n_\n.\nisObject\n(\noptions\n)\n)\n \n{\n\n \n_\n.\ndefaults\n(\noptions\n,\n \n{\n\n \nstep\n: \n1\n\n \n}\n)\n;\n\n \n}\n\n \nslider\n.\nnoUiSlider\n(\noptions\n,\n \nrebuild\n)\n;\n\n \nvar\n \nhandles\n \n=\n \nslider\n.\nfind\n(\n'.noUi-handle'\n)\n;\n\n \nvar\n \nmin\n \n=\n \nfindLimit\n(\noptions\n,\n \n_\n.\nfirst\n)\n;\n\n \nvar\n \nmax\n \n=\n \nfindLimit\n(\noptions\n,\n \n_\n.\nlast\n)\n;\n\n \nhandles\n.\neach\n(\nfunction\n(\ni\n)\n \n{\n\n \nsetupHandle\n(\nslider\n,\n \n$\n(\nthis\n)\n,\n \ni\n,\n \nmin\n,\n \nmax\n)\n;\n\n \n}\n)\n;\n\n}\n;\n\n/**\n\n *\tFinds a limit in the given set of options.\n\n *\n\n *\t\n@param\n object options Options.\n\n *\t\n@param\n function find Function to find a limit in the options.\n\n */\n\nfunction\n \nfindLimit\n(\noptions\n,\n \nfind\n)\n \n{\n\n \nvar\n \nlimit\n \n=\n \nfind\n(\n\n \n_\n.\nvalues\n(\noptions\n.\nrange\n)\n\n \n)\n;\n\n \nreturn\n \n_\n.\nisArray\n(\nlimit\n)\n\n\t\t? \nfind\n(\nlimit\n)\n\n\t\t: \nlimit\n;\n\n}\n\n/**\n\n *\tFinds a limit in the given set of options.\n\n *\n\n *\t\n@param\n object slider Slider.\n\n *\t\n@param\n object handle Handle.\n\n *\t\n@param\n int handleIndex Index of the handle.\n\n *\t\n@param\n int min Minimum value.\n\n *\t\n@param\n int max Maximum value.\n\n */\n\nfunction\n \nsetupHandle\n(\nslider\n,\n \nhandle\n,\n \nhandleIndex\n,\n \nmin\n,\n \nmax\n)\n \n{\n\n \n// adds aria attributes\n\n \nhandle\n.\nattr\n(\n'tabindex'\n,\n \n0\n)\n;\n\n \nhandle\n.\nattr\n(\n'role'\n,\n \n'slider'\n)\n;\n\n \nhandle\n.\nattr\n(\n'aria-valuemin'\n,\n \nmin\n)\n;\n\n \nhandle\n.\nattr\n(\n'aria-valuemax'\n,\n \nmax\n)\n;\n\n \nhandle\n.\nattr\n(\n'aria-valuenow'\n,\n \nslider\n.\nval\n(\n)\n)\n;\n\n \n// updates the current value when it changes\n\n \nslider\n.\non\n(\n'set'\n,\n \nfunction\n(\n)\n \n{\n\n \nhandle\n.\nattr\n(\n'aria-valuenow'\n,\n \nslider\n.\nval\n(\n)\n)\n;\n\n \n}\n)\n;\n\n \n// handles keyboard updates\n\n \n// see http://refreshless.com/nouislider/examples/#section-keypress\n\n \nhandle\n.\non\n(\n'keydown'\n,\n \nfunction\n(\nevent\n)\n \n{\n\n \nvar\n \nvalue\n \n=\n \nNumber\n(\nslider\n.\nval\n(\n)\n)\n;\n\n \nvar\n \nsteps\n \n=\n \nslider\n.\nnoUiSlider\n(\n'step'\n)\n;\n\n \nvar\n \nhandleSteps\n \n=\n \nsteps\n[\nhandleIndex\n]\n;\n\n \nswitch\n \n(\nevent\n.\nwhich\n)\n \n{\n\n \ncase\n \n40\n: \n// down\n\n \ncase\n \n37\n: \n// left\n\n \n// decrements value by a single step\n\n \nslider\n.\nval\n(\nvalue\n \n-\n \nhandleSteps\n[\n0\n]\n)\n;\n\n \nbreak\n;\n\n \ncase\n \n38\n: \n// up\n\n \ncase\n \n39\n: \n// right\n\n \n// increments value by a single step\n\n \nslider\n.\nval\n(\nvalue\n \n+\n \nhandleSteps\n[\n1\n]\n)\n;\n\n \nbreak\n;\n\n \ncase\n \n34\n: \n// page down\n\n \n// decrements value by 10 steps\n\n \nslider\n.\nval\n(\nvalue\n \n-\n \n(\nhandleSteps\n[\n0\n]\n \n*\n \n10\n)\n)\n;\n\n \nbreak\n;\n\n \ncase\n \n33\n: \n// page up\n\n \n// increments value by 10 steps\n\n \nslider\n.\nval\n(\nvalue\n \n+\n \n(\nhandleSteps\n[\n1\n]\n \n*\n \n10\n)\n)\n;\n\n \nbreak\n;\n\n \ncase\n \n36\n: \n// home\n\n \nslider\n.\nval\n(\nmin\n)\n;\n\n \nbreak\n;\n\n \ncase\n \n35\n: \n// end\n\n \nslider\n.\nval\n(\nmax\n)\n;\n\n \nbreak\n;\n\n \ndefault\n:\n\n \nreturn\n;\n\n \n}\n\n \nevent\n.\npreventDefault\n(\n)\n;\n\n \n}\n)\n;\n\n}", "url": "https://wpnews.pro/news/accessible-nouislider", "canonical_source": "https://gist.github.com/felixgirault/3fcb18ee0268b1c3127c", "published_at": "2015-03-30 10:24:42+00:00", "updated_at": "2026-05-22 15:09:22.715725+00:00", "lang": "en", "topics": ["developer-tools"], "entities": ["noUiSlider"], "alternates": {"html": "https://wpnews.pro/news/accessible-nouislider", "markdown": "https://wpnews.pro/news/accessible-nouislider.md", "text": "https://wpnews.pro/news/accessible-nouislider.txt", "jsonld": "https://wpnews.pro/news/accessible-nouislider.jsonld"}}