Dialog is a new semantic double TAB in HTML5 that displays an interactive modal dialog box.

Most browsers don’t support it, only Chrome and others do.

attribute

open

Use to control the explicit and implicit mode box, that is, if the open attribute is displayed, otherwise hidden.

<dialog open>
  <p>hello world</p>
</dialog>
Copy the code

The browser renders as follows, with some default styles and centered horizontally only.

Display time style.

Hide the time style.

returnValue

Keep the arguments passed in to the close method.

methods

show()

Display the modal box and add the open attribute to it.

<button>show</button>
<dialog>
  <p>hello world</p>
</dialog>

<script>
  var btn = document.querySelector('button')
  var dialog = document.querySelector('dialog')

  btn.addEventListener('click'.() = > {
    dialog.show()
  })
</script>
Copy the code

showModel()

Display the mode box, add the open property to it and display the mask box, while monitoring the ESC key (to close when pressed).

<button>showModal</button>
<dialog>
  <p>hello world</p>
</dialog>

<script>
  var btn = document.querySelector('button')
  var dialog = document.querySelector('dialog')

  btn.addEventListener('click'.() = > {
    dialog.showModal()
  })
</script>
Copy the code

Click showModal as follows to display and press ESC to close.

You can also turn it offESCThe default behavior of.

document.onkeydown = ev= > {
  if (ev.key === 'Escape') {
    ev.preventDefault()
  }
}
Copy the code

close()

Close the mode box and remove its open property, leaving the close method parameter on the Dialog.returnValue property.

<button class="show">showModal</button>
<button class="returnValue">returnValue</button>
<dialog>
  <p>hello world</p>
  <button class="close">close</button>
</dialog>

<script>
  var showBtn = document.querySelector('.show')
  var closeBtn = document.querySelector('.close')
  var returnValueBtn = document.querySelector('.returnValue')
  var dialog = document.querySelector('dialog')

  showBtn.addEventListener('click'.() = > {
    dialog.showModal()
  })

  closeBtn.addEventListener('click'.() = > {
    dialog.close('hello world')
  })

  returnValueBtn.addEventListener('click'.() = > {
    console.log(dialog.returnValue)
  })
</script>
Copy the code

The event

close

Triggered when the mode box is closed.

<dialog open>
  <p>hello world</p>
  <button>close</button>
</dialog>

<script>
  var btn = document.querySelector('button')
  var dialog = document.querySelector('dialog')

  btn.addEventListener('click'.() = > {
    dialog.close()
  })

  dialog.addEventListener('close'.(ev) = > {
    console.log('close')})</script>
Copy the code

cancel

Triggered when ESC is pressed to close the mode box.

<button>showModal</button>
<dialog>
  <p>hello world</p>
</dialog>

<script>
  var btn = document.querySelector('button')
  var dialog = document.querySelector('dialog')

  btn.addEventListener('click'.() = > {
    dialog.showModal()
  })

  dialog.addEventListener('cancel'.(ev) = > {
    console.log('cancel')})</script>
Copy the code

Application scenarios

Nested modal boxes

When the modal box is nested, the visual effect will be superimposed if the mask background color is transparent.

<style>
    dialog::backdrop {
        background: rgba(0.0.0.0.5);
    }
</style>

<button class='outer-btn'>Open the outer mode box</button>

<dialog class="outer-dig">
    <p>hello world</p>
    <button class="outer-close-btn">Shut down</button>
    <button class="outer-open-btn">Open the inner mode box</button>
</dialog>

<dialog class="inner-dig">
    <p>hello world</p>
    <button class="inner-close-btn">Shut down</button>
</dialog>

<script>
    var outerBtn = document.querySelector('.outer-btn')
    var outerCloseBtn = document.querySelector('.outer-close-btn')
    var outerOpenBtn = document.querySelector('.outer-open-btn')
    var innerCloseBtn = document.querySelector('.inner-close-btn')
    var outerDig = document.querySelector('.outer-dig')
    var innerDig = document.querySelector('.inner-dig')

    outerBtn.addEventListener('click'.() = > {
        outerDig.showModal()
    })

    outerOpenBtn.addEventListener('click'.() = > {
        innerDig.showModal()
    })

    outerCloseBtn.addEventListener('click'.() = > {
        outerDig.close()
    })

    innerCloseBtn.addEventListener('click'.() = > {
        innerDig.close()
    })
</script>
Copy the code

Click Modal to close Dialog

Refer to the Element UI’s Dialog component, which adds the close-on-click-modal attribute to close the Dialog by clicking on modal.

So you first need to implement modal to close the Dialog.

<style>
    dialog::backdrop {
        background: rgba(0.0.0.0.5);
    }
</style>

<button>showModal</button>
<dialog>
    <p>hello world</p>
</dialog>

<script>
    var btn = document.querySelector('button')
    var dialog = document.querySelector('dialog')

    btn.addEventListener('click'.() = > {
        dialog.showModal()
    })

    dialog.addEventListener('click'.(ev) = > {
        console.log(ev.target)
    })
</script>
Copy the code

Dialog has a 1em margin and border by default, and clicking on the blank area around the P label will also print the Dialog.

So remove both the margin and border from the Dialog and create the div element inside it.

dialog {
    padding: 0;
    border: none;
}

dialog .content {
    padding: 1em;
}

<dialog>
    <div class="content">
        <p>hello world</p>
    </div>
</dialog>
Copy the code

The Dialog is then closed based on the nodeName of the node.

dialog.addEventListener('click'.function (ev) {
    if (ev.target.nodeName === 'DIALOG') this.close()
})
Copy the code

Finally, consider adding the close-on-click-modal attribute to enable this function and encapsulate js and style as Dialog module at the same time.

Create the dialog folder, add index.css and index.js, and be careful not to add events by window.onload = function(){}, because window.onload may be overwritten by the outside, and the function will become invalid.

// dialog/index.css
dialog {
    padding: 0;
    border: none;
}

dialog .content {
    padding: 1em;
}

dialog::backdrop {
    background: rgba(0.0.0.0.5);
}

// dialog/index.js
window.addEventListener('load'.() = > {
    document.querySelectorAll('dialog[close-on-click-modal]').forEach(dialog= > {
        dialog.addEventListener('click'.function (ev) {
            if (ev.target.nodeName === 'DIALOG') this.close()
        })
    })
})
Copy the code

HTML is imported into the Dialog module.

<head>
    <script src="dialog/index.js"></script>
    <link rel="stylesheet" href="dialog/index.css">
</head>

<body>
    <button>showModal</button>
    <dialog close-on-click-modal>
        <div class="content">
            <p>hello world</p>
        </div>
    </dialog>

    <script>
        window.onload = () = > {
            var btn = document.querySelector('button')
            var dialog = document.querySelector('dialog')

            btn.addEventListener('click'.() = > {
                dialog.showModal()
            })
        }
    </script>
</body>
Copy the code

Transition animations

Since the display property is None when the modal box is hidden, and transition cannot transition to it, use visibility instead.

dialog:not([open]) {
    opacity: 0;
    visibility: hidden;
    display: block;
}

dialog {
    opacity: 1;
    transition: opacity 2s ease;
}
Copy the code

Polyfill

Dialog browsers are less supported, and dialog-polyfill can be considered for compatibility.

Note that when you use polyfill, you need to specify Settings like dialog+.backdrop.

<head>
    <link rel="stylesheet" href="node_modules/dialog-polyfill/dialog-polyfill.css">
    <style>
        dialog::backdrop {
            background: rgba(0.0.0.0.5);
        }

        dialog+.backdrop {
            background: rgba(0.0.0.0.5);
        }

        dialog {
            padding: 0;
            border: none;
        }

        dialog .content {
            padding: 1em;
        }

        dialog:not([open]) {
            opacity: 0;
            visibility: hidden;
            display: block;
        }

        dialog {
            opacity: 1;
            transition: opacity 2s ease;
        }
    </style>
</head>

<body>
    <button>showModal</button>
    <dialog>
        <div class="content">
            <p>hello world</p>
        </div>
    </dialog>

    <script src="node_modules/dialog-polyfill/dist/dialog-polyfill.js"></script>
    <script>
        var btn = document.querySelector('button')
        var dialog = document.querySelector('dialog');
        dialogPolyfill.registerDialog(dialog);
        btn.addEventListener('click'.() = > {
            dialog.showModal();
        })
    </script>
</body>
Copy the code