Start sharing components as a team!Share components as a team!Join Bit to build your applications faster.Get Started Free

popup

v1.1.32arrow_drop_down
v1.1.32
STATUS
Passing
DOWNLOADS
33
LICENSE
MIT
VISIBILITY
Public
PUBLISHED
A year ago
SIZE
1 KB
1 contributor
Install popup as a package?
Copied
npm i @bit/myliang.fish-ui.utils.popup
Set Bit as a scoped registryLearn more
npm config set '@bit:registry' https://node.bit.dev
Files
popup.js
111 Lines(92 sloc)
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
let createElement = (tag, className = null, html = null, onclick = null) => {
  let ele = document.createElement(tag)
  if (className !== null) ele.setAttribute('class', className)
  if (html !== null) ele.innerHTML = html
  if (onclick !== null) ele.onclick = onclick
  return ele
}

// 计算绝对的偏移量(相对于html)
let absoluteOffset = (el) => {
  let { offsetLeft, offsetTop, offsetParent } = el
  if (offsetParent) {
    let pOffset = absoluteOffset(offsetParent)
    offsetLeft += pOffset.left
    offsetTop += pOffset.top
  }
  return {left: offsetLeft, top: offsetTop}
}

let setPositionStyle = (el) => {
  let client = {w: document.body.scrollWidth, h: document.body.scrollHeight}
  let offset = absoluteOffset(el)
  // console.log('offset: ', offset, el)
  let arrowPosition = ''
  let style = 'display: block;'

  console.log(client.h, ':::', offset.top)

  if (client.h / 2 > offset.top) {
    arrowPosition += 'bottom'
    style += `top: ${offset.top + el.offsetHeight}px;`
  } else {
    arrowPosition += 'top'
    style += `bottom: -${offset.top}px; top: auto;`
  }

  if (client.w / 2 > offset.left) {
    arrowPosition += ' left'
    style += `left: ${offset.left}px; right: auto;`
  } else {
    arrowPosition += ' right'
    style += `right: ${client.w - offset.left - el.offsetWidth}px;`
  }

  return {arrowPosition, style}
}

const targetQueue = []

let createPopup = (event, html, width = null, appendChildrenCallback) => {
  // console.log('event: ', event)
  let el = event.target
  targetQueue.push(el)
  if (el['_popup'] !== undefined) {
    return this
  }

  let root = document.createElement('div')
  // root.style = 'display: block; visibility: hidden;'
  root.innerHTML = html

  let rootWrapper = el['_popup'] = createElement('div')
  rootWrapper.style = `position: absolute; top: 0; left: 0; width:100%;`
  rootWrapper.append(root)
  document.body.appendChild(rootWrapper)
  if (appendChildrenCallback !== undefined) {
    appendChildrenCallback.call(this, root, el)
  }

  let {arrowPosition, style} = setPositionStyle(el)
  console.log(arrowPosition, ':::', style)
  root.setAttribute('class', 'fish popup ' + arrowPosition)
  root.style = style
  if (width !== null) root.style.width = `${width}`
  root.onclick = (e) => {
    e.stopPropagation()
  }
  addAwayListener(el)
  return root
}

let awayFunc = (event) => {
  let el = targetQueue.shift()
  if (event.target !== el['_popup']) {
    removePopup(el)
  }
}

let removePopup = (el) => {
  document.body.removeChild(el['_popup'])
  delete el['_popup']
  document.removeEventListener('click', awayFunc, false)
}

let addAwayListener = (el) => {
  setTimeout(() => {
    document.addEventListener('click', awayFunc, false)
  }, 0)
}

export default {
  confirm: (event, html, okFunc, okText = 'Yes', cancelText = 'No') => {
    html = `<div class="content"><i class="fa fa-exclamation-circle"></i>${html}</div>`
    createPopup(event, html, null, (root, el) => {
      let children = createElement('div', 'footer', '')
      children.appendChild(createElement('div', 'fish small button', cancelText, (e) => { removePopup(el); e.stopPropagation() }))
      children.appendChild(createElement('div', 'fish small primary button', okText, (e) => { okFunc && okFunc(); removePopup(el); e.stopPropagation() }))
      root.appendChild(children)
    })
  }
}