设计思路:

**HTML:**
1. <html>
2. <head>
3. <meta charset="utf-8">
4. <title>回调函数</title>
5. <link rel="stylesheet" href="css/alert.css">
6. <link rel="stylesheet" href="css/conform.css">
7. <script src="js/alert.js"></script>
8. <script src="js/confirm.js"></script>
9. <style>
10.
11. </style>
12. </head>
13. <body>
14. <div>这个段落可以删除1</div>
15. <div>这个段落可以删除2</div>
16. <div>这个段落可以删除3</div>
17. <div>这个段落可以删除4</div>
18. <div>这个段落可以删除5</div>
19. <div>这个段落可以删除6</div>
20. <div>这个段落可以删除7</div>
21. <div>这个段落可以删除8</div>
22. <div>这个段落可以删除9</div>
23. <div>这个段落可以删除10</div>
24. <div>这个段落可以删除1</div>
25. <div>这个段落可以删除2</div>
26. <div>这个段落可以删除3</div>
27. <div>这个段落可以删除4</div>
28. <div>这个段落可以删除5</div>
29. <div>这个段落可以删除6</div>
30. <div>这个段落可以删除7</div>
31. <div>这个段落可以删除8</div>
32. <div>这个段落可以删除9</div>
33. <div>这个段落可以删除10</div>
34. <div>这个段落可以删除1</div>
35. <div>这个段落可以删除2</div>
36. <div>这个段落可以删除3</div>
37. <div>这个段落可以删除4</div>
38. <div>这个段落可以删除5</div>
39. <div>这个段落可以删除6</div>
40. <div>这个段落可以删除7</div>
41. <div>这个段落可以删除8</div>
42. <div>这个段落可以删除9</div>
43. <div>这个段落可以删除10</div>
44. <div>这个段落可以删除1</div>
45. <div>这个段落可以删除2</div>
46. <div>这个段落可以删除3</div>
47. <div>这个段落可以删除4</div>
48. <div>这个段落可以删除5</div>
49. <div>这个段落可以删除6</div>
50. <div>这个段落可以删除7</div>
51. <div>这个段落可以删除8</div>
52. <div>这个段落可以删除9</div>
53. <div>这个段落可以删除10</div>
54. <div>这个段落可以删除1</div>
55. <div>这个段落可以删除2</div>
56. <div>这个段落可以删除3</div>
57. <div>这个段落可以删除4</div>
58. <div>这个段落可以删除5</div>
59. <div>这个段落可以删除6</div>
60. <div>这个段落可以删除7</div>
61. <div>这个段落可以删除8</div>
62. <div>这个段落可以删除9</div>
63. <div>这个段落可以删除10</div>
64. <div>这个段落可以删除1</div>
65. <div>这个段落可以删除2</div>
66. <div>这个段落可以删除3</div>
67. <div>这个段落可以删除4</div>
68. <div>这个段落可以删除5</div>
69. <div>这个段落可以删除6</div>
70. <div>这个段落可以删除7</div>
71. <div>这个段落可以删除8</div>
72. <div>这个段落可以删除9</div>
73. <div>这个段落可以删除10</div>
74. <div>这个段落可以删除1</div>
75. <div>这个段落可以删除2</div>
76. <div>这个段落可以删除3</div>
77. <div>这个段落可以删除4</div>
78. <div>这个段落可以删除5</div>
79. <div>这个段落可以删除6</div>
80. <div>这个段落可以删除7</div>
81. <div>这个段落可以删除8</div>
82. <div>这个段落可以删除9</div>
83. <div>这个段落可以删除10</div>
84. <div>这个段落可以删除1</div>
85. <div>这个段落可以删除2</div>
86. <div>这个段落可以删除3</div>
87. <div>这个段落可以删除4</div>
88. <div>这个段落可以删除5</div>
89. <div>这个段落可以删除6</div>
90. <div>这个段落可以删除7</div>
91. <div>这个段落可以删除8</div>
92. <div>这个段落可以删除9</div>
93. <div>这个段落可以删除10</div><div>这个段落可以删除1</div>
94. <div>这个段落可以删除2</div>
95. <div>这个段落可以删除3</div>
96. <div>这个段落可以删除4</div>
97. <div>这个段落可以删除5</div>
98. <div>这个段落可以删除6</div>
99. <div>这个段落可以删除7</div>
100. <div>这个段落可以删除8</div>
101. <div>这个段落可以删除9</div>
102. <div>这个段落可以删除10</div>
103. <div>这个段落可以删除1</div>
104. <div>这个段落可以删除2</div>
105. <div>这个段落可以删除3</div>
106. <div>这个段落可以删除4</div>
107. <div>这个段落可以删除5</div>
108. <div>这个段落可以删除6</div>
109. <div>这个段落可以删除7</div>
110. <div>这个段落可以删除8</div>
111. <div>这个段落可以删除9</div>
112. <div>这个段落可以删除10</div>
113.
114.
115. <script>
116. var ps = document.querySelectorAll('div')
117. Array.prototype.slice.call(ps).forEach(function(p){
118. p.onclick = function(){
119.
120. new Confirm('确定要删除此段落吗?',function(){
121. p.remove()
122. new Alert('已删除').show()
123. },function(){
124. new Alert('已取消删除').show()
125. }).show()
126. }
127. })
128.
129. </script>
130. </body>
131. </html>
**alert.css:**
1. html{
2. height: 100%;
3. /* overflow: hidden; */
4.
5. }
6. body{
7. height: 100%;
8. }
9. div.modal-mask{
10. width:100%;
11. height: 100%;
12. background-color: black;
13. opacity: 0.5;
14. position:absolute;
15. top:0;
16. left: 0;
17. z-index: 9999;
18. }
19. div.modal-box{
20.
21. width:300px;
22. height: 150px;
23. border: 1px solid #9c9c9c;
24. border-radius: 10px;
25. position: absolute;
26. top:calc((100% - 150px) / 2);
27. left:calc((100% - 300px) / 2);
28. background-color: #e9e9e9;
29. box-shadow: 0 0 2px #444;
30. z-index: 10000;
31. }
32. div.modal-box .modal-message{
33. text-align: center;
34. margin-top: 35px;
35. font-size: 18px;
36. color: #444;
37. }
38. div.modal-box .modal-button-box{
39. height: 50px;
40. position: absolute;
41. bottombottom:0;
42. width: 100%;
43. border-top: 1px solid silver;
44. border-bottom-left-radius: 10px;
45. border-bottom-rightright-radius: 10px;
46. }
47. .modal-button-box div{
48. height: 49px;
49. width:98%;
50. text-align: center;
51. line-height: 50px;
52. cursor: pointer;
53. border-radius: 10px;
54. }
**conform.css:**
1. .modal-separator{
2. border-left: 1px solid silver;
3. height: 50px;
4. position: absolute;
5. bottombottom: 0;
6. left: calc(50%);
7. display: block;
8. }
9. .modal-left-button,.modal-rightright-button{
10. display: block;
11. width: 49%;
12. height: 48px;
13. position: absolute;
14. bottombottom: 0;
15. left: 0;
16. text-align: center;
17. line-height: 50px;
18.
19. }
20. .modal-rightright-button{
21. left: auto;
22. rightright: 0;
23. }
**alert.js**
1. function Alert(message,action){
2. this.message = message
3. this.action = action
4. // 首先传入一个函数 而不执行它
5. // 在内部保留这个函数 当内部处理完成之后再回过头来调用这个函数
6. // 通知外部已经完成处理 这种函数通常为回调函数 callBack
7. // document.documentElement.style.overflow = 'hidden'
8. }
9. Alert.prototype.showMask = function(){
10. // 将样式分离到单独的样式表中可以随时修改样式而不需要修改代码
11. // 即使不懂代码也可以修改样式 js代码量也减小了
12. var mask = document.createElement('div')
13. mask.className = 'modal-mask'
14. document.body.appendChild(mask)
15. }
16. Alert.prototype.showBody = function(){
17. var box = document.createElement('div')
18. box.className = 'modal-box'
19. document.body.appendChild(box)
20.
21. var mes = document.createElement('div')
22. mes.className = 'modal-message'
23. mes.innerText = this.message
24. box.appendChild(mes)
25.
26. var btnBox = document.createElement('div')
27. btnBox.className = 'modal-button-box'
28. box.appendChild(btnBox)
29. }
30.
31. Alert.prototype.showButton = function(){
32. var btn = document.createElement('div')
33. btn.innerText = '确定'
34. document.querySelector('.modal-button-box').appendChild(btn)
35. var self = this
36. btn.onclick = function(ev){
37. self.close()
38. // 因为事件处理程序中的this指向当前监听事件的标签
39. // 所以在这个函数中无法使用this来表示Alert对象
40. // 但是我们可以使用一个变量来代替this
41. // 这个变量就是self
42. // 判断self.action 是否有值 并是否是一个函数
43. if(typeof self.action === 'function'){
44. self.action()
45. }
46. }
47.
48. }
49. Alert.prototype.close = function(){
50. var mas = document.querySelector('.modal-mask')
51. var box = document.querySelector('.modal-box')
52. document.body.removeChild(mas)
53. document.body.removeChild(box)
54. // document.documentElement.style.overflow = 'hidden'
55.
56. }
57. Alert.prototype.show = function(){
58. this.showMask()
59. this.showBody()
60. this.showButton()
61. }
**confirm.js**
1. function Confirm(message,action1,action2){
2. Alert.call(this,message,action1)
3. this.canceAction = action2
4. }
5. Confirm.prototype = Object.create(Alert.prototype)
6. Confirm.prototype.constructor = Confirm
7.
8. // 重写showButton方法 在按钮中生成'确定'和'取消'按钮
9. Confirm.prototype.showButton = function(){
10. var btnBox = document.querySelector('.modal-button-box')
11. var separator = document.createElement('span')
12. separator.className = 'modal-separator'
13. btnBox.appendChild(separator)
14.
15. var action1 = document.createElement('span')
16. action1.innerText = '确定'
17. action1.className = 'modal-left-button'
18. btnBox.appendChild(action1)
19.
20. var action2 = document.createElement('span')
21. action2.innerText = '取消'
22. action2.className = 'modal-right-button'
23. btnBox.appendChild(action2)
24. var me = this
25. action1.onclick = function(){
26. me.close()
27. if(typeof me.action === 'function'){
28. me.action()
29. }
30. }
31.
32. action2.onclick = function(){
33. me.close()
34. if(typeof me.canceAction === 'function'){
35. me.canceAction()
36. }
37. }
38.
39. }
演示效果:
弹出框