{"id":41342681,"url":"https://github.com/txs1992/focus-outside","last_synced_at":"2026-01-23T06:52:39.028Z","repository":{"id":32695481,"uuid":"111075059","full_name":"txs1992/focus-outside","owner":"txs1992","description":"📦    一个很棒的 clickOutside 库，它解决了 iframe 无法触发 clickOutside 的问题，并且它支持分组绑定处理。A good clickOutside library, which solves the problem that iframe cannot trigger clickOutside, and it supports grouping binding processing. ","archived":false,"fork":false,"pushed_at":"2023-01-06T08:40:48.000Z","size":2889,"stargazers_count":93,"open_issues_count":21,"forks_count":12,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-10-24T16:39:48.394Z","etag":null,"topics":["click","click-away","click-outside","clickaway","clickoutside","clickoutside-library","focus-away","focus-outside","focusaway","focusoutside","iframe","iframe-click","iframe-click-outside","iframe-clickoutside","solver","trigger-clickoutside"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/txs1992.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":"2017-11-17T08:00:45.000Z","updated_at":"2025-05-14T08:51:57.000Z","dependencies_parsed_at":"2023-01-14T21:57:32.198Z","dependency_job_id":null,"html_url":"https://github.com/txs1992/focus-outside","commit_stats":null,"previous_names":["1969290646/focus-outside"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/txs1992/focus-outside","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/txs1992%2Ffocus-outside","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/txs1992%2Ffocus-outside/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/txs1992%2Ffocus-outside/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/txs1992%2Ffocus-outside/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/txs1992","download_url":"https://codeload.github.com/txs1992/focus-outside/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/txs1992%2Ffocus-outside/sbom","scorecard":{"id":112495,"data":{"date":"2025-08-04","repo":{"name":"github.com/txs1992/focus-outside","commit":"cedac065d93ce28ae40ac752deb07ae712bf3232"},"scorecard":{"version":"v5.2.1-28-gc1d103a9","commit":"c1d103a9bb9f635ec7260bf9aa0699466fa4be0e"},"score":1.7,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/3 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#dangerous-workflow"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#token-permissions"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 29 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"93 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-whgm-jr23-g3j9","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-fwr7-v2mv-hh25","Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-3wcq-x3mq-6r9p","Warn: Project is vulnerable to: GHSA-434g-2637-qmqr","Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m","Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw","Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p","Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747","Warn: Project is vulnerable to: GHSA-vjh7-7g9h-fjfh","Warn: Project is vulnerable to: GHSA-6h5x-7c5m-7cr7","Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc","Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx","Warn: Project is vulnerable to: GHSA-74fj-2j2h-c42q","Warn: Project is vulnerable to: GHSA-pw2r-vq6v-hr8c","Warn: Project is vulnerable to: GHSA-jchw-25xp-jwwc","Warn: Project is vulnerable to: GHSA-cxjh-pqwp-8mfp","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-ww39-953v-wcq6","Warn: Project is vulnerable to: GHSA-43f8-2h32-f4cj","Warn: Project is vulnerable to: GHSA-c7qv-q95q-8v27","Warn: Project is vulnerable to: GHSA-78xj-cgh5-2h22","Warn: Project is vulnerable to: GHSA-2p57-rm9w-gvfp","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-76p3-8jx3-jpfq","Warn: Project is vulnerable to: GHSA-3rfm-jhwj-7488","Warn: Project is vulnerable to: GHSA-hhq3-ff78-jv3g","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-92xj-mqp7-vmcj","Warn: Project is vulnerable to: GHSA-wxgw-qj99-44c2","Warn: Project is vulnerable to: GHSA-5rrq-pxf6-6jx5","Warn: Project is vulnerable to: GHSA-8fr3-hfg3-gpgp","Warn: Project is vulnerable to: GHSA-gf8q-jrpm-jvxq","Warn: Project is vulnerable to: GHSA-2r2c-g63r-vccr","Warn: Project is vulnerable to: GHSA-cfm4-qjh2-4765","Warn: Project is vulnerable to: GHSA-x4jg-mjrx-434g","Warn: Project is vulnerable to: GHSA-r8f7-9pfq-mjmv","Warn: Project is vulnerable to: GHSA-rp65-9cf3-cjxr","Warn: Project is vulnerable to: GHSA-76c9-3jph-rj3q","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w","Warn: Project is vulnerable to: GHSA-h7cp-r72f-jxh6","Warn: Project is vulnerable to: GHSA-v62p-rq8g-8h59","Warn: Project is vulnerable to: GHSA-566m-qj78-rww5","Warn: Project is vulnerable to: GHSA-hwj9-h5mp-3pm3","Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-gcx4-mw62-g8wm","Warn: Project is vulnerable to: GHSA-7mwh-4pqv-wmr8","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg","Warn: Project is vulnerable to: GHSA-hxcc-f52p-wc94","Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p","Warn: Project is vulnerable to: GHSA-vx3p-948g-6vhq","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-7p7h-4mm5-852v","Warn: Project is vulnerable to: GHSA-9m6j-fcg5-2442","Warn: Project is vulnerable to: GHSA-hh27-ffr2-f2jc","Warn: Project is vulnerable to: GHSA-rqff-837h-mm52","Warn: Project is vulnerable to: GHSA-8v38-pw62-9cw2","Warn: Project is vulnerable to: GHSA-hgjh-723h-mx2j","Warn: Project is vulnerable to: GHSA-jf5r-8hm2-f872","Warn: Project is vulnerable to: GHSA-5j4c-8p2g-v4jx","Warn: Project is vulnerable to: GHSA-g3ch-rx76-35fx","Warn: Project is vulnerable to: GHSA-wr3j-pwj9-hqq6","Warn: Project is vulnerable to: GHSA-4v9v-hfq4-rm2v","Warn: Project is vulnerable to: GHSA-9jgg-88mc-972h","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/c1d103a9bb9f635ec7260bf9aa0699466fa4be0e/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-15T12:52:07.160Z","repository_id":32695481,"created_at":"2025-08-15T12:52:07.160Z","updated_at":"2025-08-15T12:52:07.160Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28682263,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-23T05:48:07.525Z","status":"ssl_error","status_checked_at":"2026-01-23T05:48:07.129Z","response_time":59,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["click","click-away","click-outside","clickaway","clickoutside","clickoutside-library","focus-away","focus-outside","focusaway","focusoutside","iframe","iframe-click","iframe-click-outside","iframe-clickoutside","solver","trigger-clickoutside"],"created_at":"2026-01-23T06:52:38.921Z","updated_at":"2026-01-23T06:52:39.015Z","avatar_url":"https://github.com/txs1992.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003efocus-outside\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"http://img.shields.io/travis/txs1992/focus-outside.svg\"\u003e\n    \u003cimg src=\"http://img.shields.io/travis/txs1992/focus-outside.svg\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://img.shields.io/npm/dt/focus-outside.svg\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/dt/focus-outside.svg\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://img.shields.io/npm/dm/focus-outside.svg\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/dm/focus-outside.svg\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://img.shields.io/npm/v/focus-outside.svg\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/v/focus-outside.svg\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://img.shields.io/npm/l/focus-outside.svg\"\u003e\n    \u003cimg src=\"https://img.shields.io/npm/l/focus-outside.svg\" /\u003e\n  \u003c/a\u003e\n  \u003ca href=\"https://img.shields.io/node/v/passport.svg\"\u003e\n    \u003cimg src=\"https://img.shields.io/node/v/passport.svg\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e\n  \u003ch3\u003e\n    \u003ca href=\"https://github.com/txs1992/focus-outside#readme\"\u003e\n      English\n    \u003c/a\u003e\n    \u003cspan\u003e | \u003c/span\u003e\n    \u003ca href=\"https://github.com/txs1992/focus-outside/blob/master/docs/zh-cn.md#readme\"\u003e\n      中文\n    \u003c/a\u003e\n  \u003c/h3\u003e\n\u003c/div\u003e\n\n## what is this\n\n\u003e A good clickOutside library, which solves the problem that iframe cannot trigger clickOutside, and it supports grouping binding processing. \n## API\n\n| function | descrption | options |\n|:--------:|:--------:|:--------:|\n| `bind `  | Bind outside handlers to elements | `el`, `callback`, `key`, `className`, for details, see the `Bind Params` table below |\n| `unbind` | Clear element binding function | `el` Element Node |\n\n\n## Bind Params\n| parameter | type | descrption | required | default |\n|:--------:|:--------:|:--------:|:--------:|:--------:|\n| `el` | Element | Element to be bound | true | - |\n| `callback` | Function  | The processing function when the outside event is triggered | true | - |\n| `key` | String/Function | Divide elements or functions into a group of types. When the same group of elements is clicked, the outside event will not be triggered, while clicking on elements outside the same group will trigger the outside event. | false |`callback` function |\n| `className` | String  | The class name to bind to the element | false | \"focus-outside\" |\n\n\n## Notice\n\nWhen the element is bound, `focus-outside` sets the element as a focusable element, which will give it a highlight style when it gets the focus browser. If you don't want to see this style, you only need to put this element The CSS property outline is set to none. The bind function of the focsout-outside version 0.5.0 adds a className parameter, adding a class name for each bound element. The default class name is `focus-outside`, and the class name is removed from the element when the unbind function is executed.\n\n```js\n\u003cdiv id=\"focus-ele\"\u003e\u003c/div\u003e\n\n// js\nconst elm = document.querySelector('#focus-ele')\n// default classname is focus-outside\nfocusBind(elm, callback, 'key', 'my-focus-name')\n\n// css\n// If you need to override all the default styles, you can put this code in the global CSS.\n.my-focus-name {\n  outline: none;\n}\n```\n\n## Use FocusOutside\n\n#### Simple Example\n\n```js\n// import { bind, unbidn } from 'focus-outside'\n// It is recommended to use the following alias to prevent conflicts with your function naming.\nimport { bind: focusBind, unbind: focusUnbind } from 'focus-outside'\n\n// If you are using a CDN, you should use it like this.\n// \u003cscript src=\"https://unpkg.com/focus-outside@0.5.2/lib/index.js\"\u003e\u003c/script\u003e\n// const { bind: focusBind, unbind: focusUnbind } = FocusOutside\n\nconst elm = document.querySelector('#dorpdown-button')\n// bind function\nfocusBind(elm, callback)\n\nfunction callback () {\n  console.log('You clicked on the area outside the dropdown button.')\n  // clear bind\n  focusUnbind(elm)\n}\n```\n\n[View Online Example](https://jsfiddle.net/_MT_/z0dejc23/9/)\n\n#### Use of key\n\n```js\nimport { bind: focusBind, unbind: focusUnbind } from 'focus-outside'\n\nconst btnOne = document.querySelector('#button-one')\nconst btnTwo = document.querySelector('#button-two')\nconst btnThree = document.querySelector('#button-three')\nconst clearBtn = document.querySelector('#button-clear')\n\n// Binding function and key\nfocusBind(btnOne, callbackOne, 'button-group')\nfocusBind(btnTwo, callbackTwo, 'button-group')\nfocusBind(btnThree, callbackThree, 'custom-button')\nfocusBind(clearBtn, clearCallback)\n\nfunction callbackOne () {\n  console.log('if you click on btnOne and btnTwo will not trigger this function')\n}\n\nfunction callbackTwo () {\n  console.log('if I was triggered, it means you clicked on elements other than btnOne and btnTwo')\n}\n\nfunction callbackThree () {\n  console.log('you clicked outside the btn-three')\n}\n\nfunction clearCallback() {\n  console.log('Clear all button binding functions')\n  focusUnbind(btnOne)\n  focusUnbind(btnTwo)\n  focusUnbind(btnThree)\n  focusUnbind(clearBtn)\n}\n```\n\n#### Used in Vue\n\n```js\n\n// outside.js\nexport default {\n  bind (el, binding) {\n    focusBind(el, binding.value)\n  },\n\n  unbind (el, binding) {\n    focusUnbind(el)\n  }\n}\n\n// xx.vue\n\u003ctemplate\u003e\n  \u003cdiv v-outside=\"handleOutside\"\u003e\u003c/div\u003e\n\u003c/template\u003e\n\nimport outside from './outside.js'\n\nexport default {\n  directives: { outside },\n\n  methods: {\n    handleOutside () {\n      // Do something...\n    }\n  }\n}\n```\n\n[View Online Example](https://jsfiddle.net/_MT_/57Lmbpe9/)\n\n#### Used in Element\n\n```js\n\u003cel-dropdown\n  ref=\"dropdown\"\n  trigger=\"click\"\u003e\n  \u003cspan class=\"el-dropdown-link\"\u003e\n    dropdown menu\u003ci class=\"el-icon-arrow-down el-icon--right\"\u003e\u003c/i\u003e\n  \u003c/span\u003e\n  \u003cel-dropdown-menu\n    ref=\"dropdownContent\"\n    slot=\"dropdown\"\u003e\n    \u003cel-dropdown-item\u003eOyster\u003c/el-dropdown-item\u003e\n    \u003cel-dropdown-item\u003eGold cake\u003c/el-dropdown-item\u003e\n    \u003cel-dropdown-item\u003eLion head\u003c/el-dropdown-item\u003e\n    \u003cel-dropdown-item\u003eSnail powder\u003c/el-dropdown-item\u003e\n    \u003cel-dropdown-item\u003eDouble skin milk\u003c/el-dropdown-item\u003e\n  \u003c/el-dropdown-menu\u003e\n\u003c/el-dropdown\u003e\n\nimport { bind: focusBind, unbind: focusUnbind } from 'focus-outside'\n\nexport default {\n  mounted () {\n    focusBind(this.$refs.dropdown.$el, this.$refs.dropdown.hide)\n    focusBind(this.$refs.dropdownContent.$el, this.$refs.dropdown.hide)\n  },\n\n  destoryed () {\n    focusUnbind(this.$refs.dropdown.$el)\n    focusUnbind(this.$refs.dropdownContent.$el)\n  }\n}\n```\n\n[View Online Example](https://jsfiddle.net/_MT_/1wb8nk67/57/)\n\n#### Used in Ant Design\n\n```js\nimport { Menu, Dropdown, Icon, Button } from 'antd'\nimport { bind: focusBind, unbind: focusUnbind } from 'focus-outside'\n\nfunction getItems () {\n  return [1,2,3,4].map(item =\u003e {\n    return \u003cMenu.Item key={item}\u003e{item} st menu item \u003c/Menu.Item\u003e\n  })\n}\n\nclass MyMenu extends React.Component {\n  constructor (props) {\n    super(props)\n    this.menuElm = null\n  }\n\n  render () {\n    return (\u003cMenu ref=\"menu\" onClick={this.props.onClick}\u003e{getItems()}\u003c/Menu\u003e)\n  }\n\n  componentDidMount () {\n    this.menuElm = ReactDOM.findDOMNode(this.refs.menu)\n    if (this.menuElm \u0026\u0026 this.props.outside) focusBind(this.menuElm, this.props.outside)\n  }\n\n  componentWillUnmount () {\n    if (this.menuElm \u0026\u0026 this.props.outside) focusUnbind(this.menuElm)\n  }\n}\n\nclass MyDropdown extends React.Component {\n\n  constructor (props) {\n    super(props)\n    this.dropdownElm = null\n  }\n\n  state = {\n    visible: false\n  }\n\n  render () {\n    const menu = (\u003cMyMenu outside={ this.handleOutside } onClick={ this.handleClick } /\u003e)\n    return (\n      \u003cDropdown\n        ref=\"divRef\"\n        visible={this.state.visible}\n        trigger={['click']}\n        overlay={ menu }\u003e\n        \u003cButton style={{ marginLeft: 8 }} onClick={ this.handleClick }\u003e\n          Button \u003cIcon type=\"down\" /\u003e\n        \u003c/Button\u003e\n      \u003c/Dropdown\u003e\n    )\n  }\n\n  componentDidMount () {\n    this.dropdownElm = ReactDOM.findDOMNode(this.refs.divRef)\n    if (this.dropdownElm) focusBind(this.dropdownElm, this.handleOutside)\n  }\n\n  componentWillUnmount () {\n    if (this.dropdownElm) focusUnbind(this.dropdownElm)\n  }\n\n  handleOutside = () =\u003e {\n    this.setState({ visible: false })\n  }\n\n  handleClick = () =\u003e {\n    this.setState({ visible: !this.state.visible })\n  }\n}\n\nReactDOM.render(\n  \u003cMyDropdown/\u003e,\n  document.getElementById('container')\n)\n```\n\n[View Online Example](https://codepen.io/taoxusheng/pen/KeRyXL?editors=1010)\n\n## Build a development environment\n\n```shell\n1. Fork project, then clone to local.\ngit clone git@github.com:txs1992/focus-outside.git\n\n2. Installation dependencies (make sure your computer has Node.js installed)\nyarn install\n\n3. run the project\nyarn dev\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftxs1992%2Ffocus-outside","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftxs1992%2Ffocus-outside","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftxs1992%2Ffocus-outside/lists"}