项目作者: sk-rt

项目描述 :
Modal dialog
高级语言: TypeScript
项目地址: git://github.com/sk-rt/moodal.git
创建时间: 2019-12-17T08:04:18Z
项目社区:https://github.com/sk-rt/moodal

开源协议:MIT License

下载


Moodal

A pure JavaScript library for modal dialog.

NPM

npm version

Get Started

1. Install

Install from NPM

  1. npm install moodal --save
  2. # or using yarn
  3. yarn add moodal
  1. // import Moodal js
  2. import Moodal from 'moodal';
  3. // import required style
  4. import 'moodal/lib/css/moodal-core.css';

Use CDN

  1. <script
  2. src="https://unpkg.com/moodal/lib/standalone/moodal.min.js"
  3. defer
  4. ></script>
  5. <link
  6. rel="stylesheet"
  7. href="https://unpkg.com/moodal/lib/css/moodal-core.css"
  8. />

Use ES modules in browser.

  1. <script type="module" src="https://unpkg.com/moodal/lib/esm/index.mjs"></script>
  2. <link
  3. rel="stylesheet"
  4. href="https://unpkg.com/moodal/lib/css/moodal-core.css"
  5. />

2. Add markup

  • [data-moodal-container] element is requied. And this shoud be left empty. (will be rewrited innerHTML)
  • [data-moodal-close] elements can be anywhere. The modal is close on it clicked.
  1. <div class="c-moodal" tabindex="-1" aria-hidden="true">
  2. <div class="c-moodal__bg"></div>
  3. <div class="c-moodal__loader">...Loading</div>
  4. <div class="c-moodal__container">
  5. <!-- close modal on `data-moodal-close` element clicked -->
  6. <div class="c-moodal__overlay" data-moodal-close></div>
  7. <div class="c-moodal__inner">
  8. <div class="c-moodal__body">
  9. <button class="c-moodal__close" type="button" data-moodal-close>
  10. Close
  11. </button>
  12. <div
  13. class="c-moodal__content"
  14. role="dialog"
  15. aria-modal="true"
  16. data-moodal-container
  17. >
  18. <!-- Will be appended content here -->
  19. </div>
  20. </div>
  21. </div>
  22. </div>
  23. </div>

Minimum

  1. <div class="c-moodal" tabindex="-1" aria-hidden="true">
  2. <div class="c-moodal__container">
  3. <div class="c-moodal__inner">
  4. <div class="c-moodal__body">
  5. <div
  6. class="c-moodal__content"
  7. role="dialog"
  8. aria-modal="true"
  9. data-moodal-container
  10. ></div>
  11. </div>
  12. </div>
  13. </div>
  14. </div>

3. Initialize Core

new Moodal( wrapperElement: string|HTMLElement, <options>);

  1. // Init Core
  2. const myModal = new Moodal('.c-moodal'); // selector or HTMLElement
  1. // Init Core with options
  2. const myModal = new Moodal('.c-moodal', {
  3. noBackgroundScroll: true,
  4. backgroundElement: document.querySelector('.page-wrapper'),
  5. waitContentLoaded: true,
  6. stateClasses: {
  7. isVissible: 'is-vissible',
  8. isLoading: 'is-loading',
  9. },
  10. });

4. Add Controller

moodal.addController(<params>)

  • Example 1: Get content from DOM element in the page.
  1. <!-- controller -->
  2. <button type="button" data-moodal-anchor="myContent">
  3. Show Modal of `myContent`
  4. </button>
  5. <!-- template for content -->
  6. <template id="myContent" style="display:none;">
  7. <p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,...</p>
  8. </template>
  1. const modalCtrl = myModal.addController({
  2. controllerAttr: 'data-moodal-anchor',
  3. getContent: (trigger) => {
  4. // `trigger` is value of attribute `data-moodal-anchor`.
  5. const targetEl = document.getElementById(trigger);
  6. if (!targetEl) return;
  7. const content = document.createElement('div');
  8. content.innerHTML = targetEl.innerHTML;
  9. // Must return a HTMLElement
  10. return content;
  11. },
  12. });
  13. // You can show/hide modal by JavaScript
  14. modalCtrl.show('myContent');
  15. modalCtrl.hide();
  • Example 2: Get content from page by fetch
  1. <!-- controller -->
  2. <button data-moodal-ajax="target.html">Show Modal of `target.html`</button>
  1. const modalCtrlAjax = myModal.addController({
  2. controllerAttr: 'data-moodal-ajax',
  3. getContent: async (trigger) => {
  4. const response = await fetch(trigger, {
  5. method: 'GET',
  6. });
  7. const data = await response.text();
  8. const wrapper = document.createElement('div');
  9. wrapper.innerHTML = data;
  10. const content = wrapper.querySelector('article');
  11. if (!content) {
  12. throw new Error('No Content!');
  13. }
  14. return content;
  15. },
  16. });

5. Styling

No theme styles is included in this library.
You need to add the theme css yourself.

  1. .c-moodal__bg {
  2. background-color: rgba(0, 0, 0, 0.7);
  3. }
  4. .c-moodal__inner {
  5. padding-top: 60px;
  6. padding-bottom: 60px;
  7. }
  8. .c-moodal__body {
  9. border-radius: 6px;
  10. padding: 40px;
  11. background-color: #fff;
  12. }

Life cycle

life cycle diagram


Core Params

Param Name Type Default Desc
containerSelector string “[data-moodal-container]“ Selector for the element appended content
hideOnClickSelector string “[data-moodal-close]“ Selector for elements that close modal when clicked
noBackgroundScroll boolean false if true, fix scrolling element
backgroundElement HTMLElement undefined The element you want to stop scrolling. ex. document.querySelector(".page-wrapper")
* require if noBackgroundScroll is true
waitContentLoaded boolean true if true, the modal is shown after <img> or <iframe> element is loaded.
stateClasses Object Classes for showing / loading state
stateClasses.isVissible string \ string[] is-vissible Class on showing modal
stateClasses.isLoading string \ string[] is-loading Class on loading modal
logLevel number 2 0 = off, 1 = error, 2 = warning, 3 = info, 4 = debug
enableFocusTrap boolean true Trap focus within a modal container on showing
hideByEscKey boolean true Hide modadal using the ESC Key

Controller Params

  1. myModal.addController({
  2. getContent: (trigger) => {
  3. // You must make content element form `trigger`
  4. // ...some code
  5. return content; // return HTMLElement
  6. },
  7. controllerAttr: 'data-modal-control',
  8. });
Param Name Type Default Desc
getContent (trigger: string) => Promise\ \ HTMLElement undefind * required Get the content(HTMLElement) from trigger argment
controllerAttr string “” Data attribute name for button elements.
waitContentLoaded boolean initialParam.waitContentLoaded Overide the core option
manualShow boolean false if true, you need show the modal manualy

Lifecycle Hooks

  1. myModal.addController({
  2. getContent: (target)=> {
  3. ...
  4. },
  5. beforeAppend: (context) => {
  6. // context argment is object { content: HTMLElement, trigger:string }
  7. console.log('on before append:',context);
  8. },
  9. afterAppend: ({content,trigger}) => {
  10. // if this return `Promise`, proccess wait for resolve.
  11. return new Promise((resolve, rejects) => {
  12. console.log('content:',content,'trigger:',trigger);
  13. setTimeout(() => {
  14. console.log('1000ms later after appending');
  15. resolve();
  16. }, 1000);
  17. });
  18. }
  19. })

Hooks

Hook Name Type Desc
beforeAppend (context) => Promise\ \ void; Hook before appending the content
afterAppend (context) => Promise\ \ void; Hook after appending the content
beforeShow (context) => Promise\ \ void; Hook before showing the modal
afterShow (context) => Promise\ \ void; Hook after showing the modal
beforeHide (context) => Promise\ \ void; Hook before hiding the modal
afterHide (context) => Promise\ \ void; Hook after hiding the modal

Filter

Hook Name Type Desc
contentCreated() (content: HTMLElement) => HTMLElement \ Promise\ \ void; Filtering the content before beforeAppend running

Browser support

Moodal is using Promose. Can I use
If you need support legacy browser like IE11, use polyfill


License

MIT