Skip to content

Commit 9a2e123

Browse files
committed
完成原生的模态框组件的开发
1 parent 3f55a7f commit 9a2e123

File tree

3 files changed

+202
-0
lines changed

3 files changed

+202
-0
lines changed

examples/app.vue

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
<div id="app">
33
<!-- <img class="avatar" src="../src/assets/images/cache_user_icon.jpg" alt=""> -->
44
<router-view></router-view>
5+
<lai-button @click.native="openModal">Modal</lai-button>
56
</div>
67
</template>
78

89
<script>
10+
import './components/Modal'
911
export default {
1012
naem: 'App',
1113
mounted () {
@@ -17,6 +19,14 @@ export default {
1719
content: '122334',
1820
duration: 2000
1921
})
22+
},
23+
methods: {
24+
openModal () {
25+
let modal = new Modal({
26+
content: '12344444'
27+
})
28+
modal.open()
29+
}
2030
}
2131
}
2232
</script>

examples/components/Modal.js

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import "./Modal.less"
2+
;(function(window) {
3+
function extendDefaults(source, properties) {
4+
var property
5+
for (property in properties) {
6+
if (properties.hasOwnProperty(property)) {
7+
source[property] = properties[property]
8+
}
9+
}
10+
return source
11+
}
12+
13+
function getTransitionEnd() {
14+
var el = document.createElement("div")
15+
if (el.style.WebkitTransition) {
16+
return "webkitTransitionEnd"
17+
}
18+
return "transitionEnd"
19+
}
20+
21+
function buildOut() {
22+
var content, contetnHolder, docFrag
23+
if (typeof this.options.content === "string") {
24+
content = this.options.content
25+
} else {
26+
content = this.options.content.innerHTML
27+
}
28+
29+
docFrag = document.createDocumentFragment()
30+
31+
this.modal = document.createElement("div")
32+
this.modal.className = "modal " + this.options.className
33+
this.modal.style.minWidth = this.options.minWidth + "px"
34+
this.modal.style.minHeight = this.options.minHeight + "px"
35+
36+
if (this.options.closeButton) {
37+
this.closeButton = document.createElement("button")
38+
this.closeButton.className = "modal-close close-button"
39+
this.closeButton.innerHTML = "x"
40+
this.modal.appendChild(this.closeButton)
41+
}
42+
43+
if (this.options.overlay) {
44+
this.overlay = document.createElement("div")
45+
this.overlay.className = "modal-overlay " + this.options.className
46+
docFrag.appendChild(this.overlay)
47+
}
48+
49+
contetnHolder = document.createElement("div")
50+
contetnHolder.className = "modal-content"
51+
contetnHolder.innerHTML = content
52+
this.modal.appendChild(contetnHolder)
53+
54+
docFrag.appendChild(this.modal)
55+
56+
document.body.appendChild(docFrag)
57+
}
58+
59+
function initializeEvents() {
60+
if (this.closeButton) {
61+
this.closeButton.addEventListener("click", this.close.bind(this))
62+
}
63+
64+
if (this.overlay) {
65+
this.overlay.addEventListener("click", this.close.bind(this))
66+
}
67+
}
68+
window.Modal = function() {
69+
var defaults = {
70+
content: "",
71+
overlay: true,
72+
minWidth: 560,
73+
minHeight: 280,
74+
closeButton: true,
75+
className: "fade-and-drop"
76+
}
77+
78+
this.closeButton = null
79+
this.modal = null
80+
this.overlay = null
81+
if (arguments[0] && typeof arguments[0] === "object") {
82+
this.options = extendDefaults(defaults, arguments[0])
83+
}
84+
}
85+
86+
window.Modal.prototype.open = function() {
87+
buildOut.call(this)
88+
initializeEvents.call(this)
89+
90+
window.getComputedStyle(this.modal)
91+
92+
this.modal.className =
93+
this.modal.className +
94+
(this.modal.offsetHeight > window.innerHeight
95+
? " modal-open modal-anchored"
96+
: " modal-open")
97+
this.overlay.className = this.overlay.className + " modal-open"
98+
}
99+
100+
window.Modal.prototype.close = function() {
101+
var $this = this
102+
this.modal.className = this.modal.className.replace(" modal-open", "")
103+
this.overlay.className = this.overlay.className.replace(" modal-open", "")
104+
105+
this.modal.addEventListener("webkitTransitionEnd", function() {
106+
$this.modal.parentNode.removeChild($this.modal)
107+
})
108+
109+
this.overlay.addEventListener("webkitTransitionEnd", function() {
110+
$this.overlay.parentNode.removeChild($this.overlay)
111+
})
112+
}
113+
})(window)

examples/components/Modal.less

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
.modal-overlay {
2+
position: fixed;
3+
will-change: transform;
4+
z-index: 9999;
5+
top: 0;
6+
right: 0;
7+
bottom: 0;
8+
left: 0;
9+
opacity: 0;
10+
background-color: rgba(0, 0, 0, 0.65);
11+
transition: 1ms opacity ease;
12+
&.modal-open {
13+
opacity: 1;
14+
}
15+
}
16+
17+
.modal {
18+
position: absolute;
19+
z-index: 10000;
20+
top: 50%;
21+
left: 50%;
22+
transform: translate(-50%, -50%);
23+
max-width: 80vw;
24+
padding: 30px 20px;
25+
transition: 1ms opacity ease;
26+
opacity: 0;
27+
border-radius: 4px;
28+
background-color: #fff;
29+
&.modal-anchored {
30+
top: 2vh;
31+
transform: translate(-50%, 0);
32+
}
33+
&.modal-open {
34+
opacity: 1;
35+
}
36+
}
37+
.modal-close {
38+
font-family: Helvetica, Arial, sans-serif;
39+
font-size: 24px;
40+
font-weight: 700;
41+
line-height: 12px;
42+
position: absolute;
43+
top: 5px;
44+
right: 5px;
45+
padding: 5px 7px 7px;
46+
cursor: pointer;
47+
color: #fff;
48+
border: 0;
49+
outline: none;
50+
background: #e74c3c;
51+
&:hover {
52+
background: #c0392b;
53+
}
54+
}
55+
56+
// 默认动画效果
57+
.modal-overlay.fade-and-drop {
58+
display: block;
59+
opacity: 0;
60+
transition: 500ms opacity 500ms ease;
61+
&.modal-open {
62+
top: 0;
63+
transition: 500ms opacity ease;
64+
opacity: 1;
65+
}
66+
}
67+
.modal.fade-and-drop {
68+
top: -300vh;
69+
opacity: 1;
70+
display: block;
71+
transition: 500ms top ease;
72+
&.modal-open {
73+
top: 50%;
74+
transition: 500ms top 500ms ease;
75+
&.modal-anchored {
76+
transition: 500ms top 500ms ease;
77+
}
78+
}
79+
}

0 commit comments

Comments
 (0)