互動視窗 - Modals

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<div class="modal static"
     tabindex="-1"
     role="dialog" aria-labelledby="modalLabel">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="modalLabel">
          視窗標題
          <small class="txt-muted">這是附註文字</small>
        </h5>
        <button type="button" class="btn-close" data-close aria-label="Close">
          <i class="icon icon-cross"></i>
        </button>
      </div>
      <div class="modal-body bg-content">
        <div>
          視窗內文
        </div>
        <button type="button" class="btn btn-primary" data-modal-opener="example-sub-modal">裡面再開</button>
      </div>
      <div class="modal-footer d-flex justify-content-between align-items-center">
        <span>總費用: 0</span>
        <div>
          <button data-cancel class="btn">取消</button>
          <button data-confirm class="btn btn-primary">確認</button>
        </div>
      </div>
    </div>
  </div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
<button type="button" class="btn btn-primary" data-modal-opener="example-modal">打開視窗</button>

<div class="modal" data-modal="example-modal"
     tabindex="-1" role="dialog" aria-labelledby="modalLabel">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="modalLabel">
          視窗標題
          <small class="txt-muted">這是附註文字</small>
        </h5>
        <button type="button" class="btn-close" data-close aria-label="Close">
          <i class="icon icon-cross"></i>
        </button>
      </div>
      <div class="modal-body bg-content">
        <div>
          視窗內文
        </div>
        <button type="button" class="btn btn-primary" data-modal-opener="example-sub-modal">裡面再開</button>
      </div>
      <div class="modal-footer d-flex justify-content-between align-items-center">
        <span>總費用: 0</span>
        <div>
          <button data-cancel class="btn">取消</button>
          <button data-confirm class="btn btn-primary">確認</button>
        </div>
      </div>
    </div>
  </div>
</div>

<div class="modal" data-modal="example-sub-modal"
     tabindex="-1" role="dialog" aria-labelledby="modalLabel">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="modalLabel">子視窗標題</h5>
        <button type="button" class="btn-close" data-close aria-label="Close">
          <i class="icon icon-cross"></i>
        </button>
      </div>
      <div class="modal-body bg-content">
        <div>
          子視窗內文
        </div>
      </div>
      <div class="modal-footer">
        <button data-cancel class="btn">取消</button>
        <button data-confirm class="btn btn-primary">確認</button>
      </div>
    </div>
  </div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
export default function bindModals() {

  const { Modal } = window.beyond

  const modals = Array.from(document.querySelectorAll('[data-modal-opener]'))
    .map(dom => new Modal(dom, {
      confirm() {
        console.log('confirmed')
      },
      cancel(type) {
        console.log('cancelled', type)
      }
    }))

  return function unbindModals() {
    modals.forEach(m => m.destroy())
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<div style="display: none;" class="modal jquery-modal">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title">jquery-modal 視窗標題</h5>
        <button type="button" class="btn-close" data-close aria-label="Close">
          <i class="icon icon-cross"></i>
        </button>
      </div>
      <div class="modal-body bg-content">
        jquery-modal 視窗內文
      </div>
      <div class="modal-footer">
        <button data-cancel class="btn">取消</button>
        <button data-confirm class="btn btn-primary">確認</button>
      </div>
    </div>
  </div>
</div>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
export default function bindJqueryModal() {

  const btn = document.getElementById('jq-modal-btn')
  const replaceBtn = document.getElementById('jq-modal-replace-btn')
  const uniqBtn = document.getElementById('jq-uniq-modal-btn')

  const html = `
    <div class="modal jquery-modal">
      <div class="modal-dialog">
        <div class="modal-content">
          <div class="modal-header">
            <h5 class="modal-title">視窗標題</h5>
            <button type="button" class="btn-close" data-close aria-label="Close">
              <i class="icon icon-cross"></i>
            </button>
          </div>
          <div class="modal-body bg-content">
            換掉了...
          </div>
          <div class="modal-footer">
            <button data-cancel class="btn">取消</button>
            <button data-confirm class="btn btn-primary">確認</button>
          </div>
        </div>
      </div>
    </div>
  `

  const onBtnClick = () => {
    $('.jquery-modal').modal('show')
    setTimeout(() => {
      console.log('open?', $('.jquery-modal').modal('open?'))
    }, 1000)
  }

  const onReplaceBtnClick = () => {
    $('.jquery-modal').modal('show', html)
  }

  const onUniqBtnClick = () => {
    $.uniqModal().modal('show')
  }

  if (btn) {
    btn.addEventListener('click', onBtnClick)
  }
  if (replaceBtn) {
    replaceBtn.addEventListener('click', onReplaceBtnClick)
  }
  if (uniqBtn) {
    uniqBtn.addEventListener('click', onUniqBtnClick)
  }

  return function unbindJqueryModal() {

    if (btn) {
      btn.removeEventListener('click', onBtnClick)
    }
    if (replaceBtn) {
      replaceBtn.removeEventListener('click', onReplaceBtnClick)
    }
    if (uniqBtn) {
      uniqBtn.removeEventListener('click', onUniqBtnClick)
    }
  }
}

Modal HTML

<button type="button" class="btn btn-primary"
        data-modal-opener="example-modal">打開視窗</button>

<div class="modal" data-modal="example-modal" tabindex="-1"
     role="dialog" aria-labelledby="modalLabel">
  <div class="modal-dialog" role="document">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="modalLabel">視窗標題</h5>
        <button type="button" class="btn-close" data-close aria-label="Close">
          <i class="icon icon-cross"></i>
        </button>
      </div>
      <div class="modal-body bg-content">
        <div>
          視窗內文
        </div>
      </div>
      <div class="modal-footer">
        <button data-cancel class="btn btn-outline">取消</button>
        <button data-confirm class="btn btn-primary">確認</button>
      </div>
    </div>
  </div>
</div>
屬性名稱 用途
data-modal-opener 指定 DOM 元素為打開 modal 的按鈕,並且設定要打開的 modal ID,例如 data-modal-opener="modal-id"
data-modal 指定 DOM 元素為 modal,並且設定 ID,例如data-modal="modal-id"
data-close 指定 DOM 元素為 modal 的關閉按鈕
data-cancel 指定 DOM 元素為 modal 的取消按鈕
data-confirm 指定 DOM 元素為 modal 的確認按鈕

Modal JS

constructor

const modal = new Modal(dom, options)
名稱 型別 說明
dom HTMLElement 要被初始化的按鈕元素
options object 選填參數
options.cancel function modal 被取消時的 callback,callback 第一個參數為取消類型,
有關閉 ( close )、取消 ( cancel ) 與按下背景取消 ( backdrop )
options.confirm function modal 被確認時的 callback

show

顯示 modal

modal.show()

hide

隱藏 modal

modal.hide()

destroy

移除 Modal 產生的 dom 元素與 event listeners

modal.destroy()