jQuery实现todo及轮播图
内容:
1.todo程序
2.轮播图
1.todo程序
需求:
实现一个todo程序,可以添加数据,可以删除数据,可以修改数据,可以查看所有数据
另外实现自己的一系列弹窗:用于提示用户的提示框、用于警告的提示框、用于输入信息的输入框、用于选择多个选项中的一个选择框
实现效果:
页面:
添加 - 在输入框输入后点击添加如下所示:
删除 - 点击每一条todo的删除如下所示:
编辑 - 点击每一条todo的编辑如下所示:
完成 - 点击每一条todo的完成如下所示:
代码:
HTML:
1 <!-- author: wyb --> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <meta charset="UTF-8"> 6 <title>jQuery实现todo程序</title> 7 <style> 8 .container{ 9 width: 80%; 10 margin: 0 auto; 11 } 12 .complete{ 13 text-decoration: line-through; 14 color: red; 15 } 16 .todo-cell{ 17 margin: 5px 0; 18 } 19 .todo-content{ 20 display: inline-block; 21 padding: 3px 5px; 22 border: 1px solid lightblue; 23 } 24 .todo-ct{ 25 display: inline-block; 26 padding: 3px 5px; 27 border: 1px solid lightblue; 28 } 29 button.indent{ 30 margin-right: 12px; 31 } 32 33 </style> 34 35 </head> 36 <body> 37 38 <div class="container"> 39 <div class="input-form"> 40 <input type="text" id="id-todo-input"> 41 <button type="button" id="id-button-add">添加</button> 42 </div> 43 <div id="todo-list"></div> 44 </div> 45 46 47 48 49 <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> 50 <script src="myAlert.js"></script> 51 <script src="jQuery_todo.js"></script> 52 53 54 </body> 55 </html>
js:
1 // 封装输出 2 var log = function() { 3 console.log.apply(this, arguments) 4 }; 5 6 7 var todoTemplate = function (todo) { 8 var t = ` 9 <div class="todo-item"> 10 <div class="todo-cell ${todo.complete}"> 11 <span class="todo-content">todo内容: ${todo.task}</span> 12 <span class="todo-ct">发布时间: ${todo.time}</span> 13 </div> 14 <button class="button-delete indent">delete</button> 15 <button class="button-edit indent">edit</button> 16 <button class="button-complete indent">complete</button> 17 </div> 18 ` 19 return t; 20 } 21 22 23 // 插入新元素 24 var insertTodo = function (todo) { 25 // 获得todo-cell的HTML字符串: 26 var todoItem = todoTemplate(todo); 27 28 var todoList = $("#todo-list"); 29 todoList.append(todoItem); 30 }; 31 32 33 // 得到当前时间 34 var currentTime = function () { 35 var d = new Date(); 36 var year = d.getFullYear(); 37 var month = d.getMonth() + 1; 38 var day = d.getDate(); 39 var hour = d.getHours(); 40 var minute = d.getMinutes(); 41 var second = d.getSeconds(); 42 // 时间格式处理 43 if(minute <= 9){ 44 minute = "0" +minute 45 } 46 if(second <= 9){ 47 second = "0" +second 48 } 49 50 var timeString = `${year}/${month}/${day} ${hour}:${minute}:${second}`; 51 log("now time is: ", timeString); 52 return timeString 53 }; 54 55 // 返回元素在父元素中的位置 56 var indexOfElement = function($element) { 57 var element = $element[0] 58 var parent = element.parentElement; 59 for (var i = 0; i < parent.children.length; i++) { 60 var e = parent.children[i]; 61 if (e === element) { 62 return i 63 } 64 } 65 }; 66 67 // 保存 todoArray 68 var saveTodos = function() { 69 var s = JSON.stringify(todoArray); 70 localStorage.todoArray = s; 71 }; 72 73 // 导出 todoArray 74 var loadTodos = function() { 75 var s = localStorage.todoArray; 76 return JSON.parse(s); 77 }; 78 79 // 获得当前页面的todo对应的数据 80 var getTodo = function ($divEle) { 81 // divEle是todo所在的div元素 82 var index = indexOfElement($divEle); 83 todoArray = loadTodos(); 84 return todoArray[index]; 85 }; 86 87 // 删除某个todo 88 var deleteTodo = function ($divEle) { 89 // divEle是todo所在的div元素 90 var index = indexOfElement($divEle) - 1; 91 $divEle.remove(); 92 todoArray = loadTodos(); 93 todoArray.splice(index, 1); 94 saveTodos(); 95 }; 96 97 // 事件处理相关: 98 // 响应事件函数: 99 var bindEventAdd = function () { 100 $("#id-button-add").on('click', function () { 101 log("button-add click"); 102 103 myAlert2("确认", "是否添加", function (b) { 104 if(b){ 105 var task = $("#id-todo-input").val(); 106 var todo = { 107 "task": task, 108 "time": currentTime(), 109 "complete": false 110 }; 111 // 将数据存入数组中 112 todoArray = loadTodos(); 113 todoArray.push(todo); 114 saveTodos(); 115 // 插入todo-list: 116 insertTodo(todo) 117 } 118 }) 119 }); 120 }; 121 122 123 var bindEventButton = function () { 124 // bindEventButton -> 复制todo所在div中的3个按钮的响应 125 $("#todo-list").on('click', function (event) { 126 log('click: ', event, event.target); 127 // 获得点击对象和其父元素(todo的div) 128 var $target = $(event.target); 129 var $todoDiv = $(event.target.parentElement); 130 131 // complete 132 if($target.hasClass('button-complete')) { 133 log('complete') 134 myAlert2("确认", "是否完成", function (b) { 135 if(b){ 136 $todoDiv.find(".todo-cell").toggleClass("complete") 137 item = getTodo($todoDiv); 138 item.complete = !item.complete; 139 saveTodos(); 140 } 141 }) 142 } 143 // delete 144 else if ($target.hasClass('button-delete')) { 145 log('delete') 146 myAlert2("确认", "是否删除", function (b) { 147 if(b){ 148 deleteTodo($todoDiv) 149 } 150 }) 151 152 } 153 // edit 154 else if ($target.hasClass('button-edit')) { 155 log('edit'); 156 myAlert3("请输入todo内容:", function (clickOk, input) { 157 if(clickOk){ 158 log(clickOk, input) 159 var index = indexOfElement($todoDiv) 160 log(index) 161 todoArray = loadTodos(); 162 todoArray[index].task = input 163 saveTodos() 164 log(($target.parent().find(".todo-content"))[0]) 165 $target.parent().find(".todo-content").html("todo内容: "+input) 166 } 167 }) 168 } 169 }); 170 }; 171 172 173 // 绑定事件: 174 var bindEvents = function () { 175 // 添加todo 176 bindEventAdd(); 177 // 完成按钮和删除按钮和编辑按钮 178 bindEventButton(); 179 180 }; 181 182 todoComplete = { 183 true: "complete", 184 false: "" 185 }; 186 187 // 初始化todo: 188 var initTodos = function () { 189 var todoArray = loadTodos(); 190 for (var i = 0; i < todoArray.length; i++) { 191 var todo = todoArray[i]; 192 todo.complete = todoComplete[todo.complete]; 193 insertTodo(todo); 194 } 195 }; 196 197 // 存储数据 198 var todoArray = []; 199 // 程序主入口 200 var __main = function (){ 201 // 绑定事件: 202 bindEvents(); 203 204 // 程序加载后, 加载 todoArray 并且添加到页面中 205 initTodos(); 206 207 }; 208 209 __main();
1 var log = function () { 2 console.log.apply(this, arguments); 3 }; 4 5 // 自定义弹窗系列 6 // 用于提示用户的提示框 7 var myAlert = function (title, message) { 8 /* 9 title 是 string 10 message 是 string 11 12 这个函数生成一个弹窗插入页面 13 弹窗包含 title 作为标题 和 message 作为信息 14 还包含一个 OK 按钮 点击 OK 按钮关闭弹窗 15 */ 16 // 插入弹窗 17 var t = ` 18 <div class="modal-container modal-remove"> 19 <div class="modal-mask"></div> 20 <div class="modal-alert vertical-center"> 21 <div class="modal-title">${title}</div> 22 <div class="modal-message">${message}</div> 23 <div class="modal-control"> 24 <button class="modal-button" type="button" name="button">OK</button> 25 </div> 26 </div> 27 </div>` 28 $('body').append(t) 29 // 插入CSS 30 var css = ` 31 <style class="modal-remove"> 32 .modal-container{ 33 position: fixed; 34 top: 0; 35 left: 0; 36 width: 100%; 37 height: 100%; 38 } 39 .modal-mask{ 40 position: fixed; 41 top: 0; 42 left: 0; 43 width: 100%; 44 height: 100%; 45 background: black; 46 opacity: 0.5; 47 } 48 .modal-alert { 49 width: 200px; 50 margin: 0 auto; 51 opacity: 1; 52 background: #eeeeee; 53 } 54 .modal-title{ 55 text-align: center; 56 font-size: 18px; 57 background: lightblue; 58 } 59 .modal-message{ 60 padding: 15px 5px; 61 } 62 .modal-button{ 63 width: 100%; 64 height: 100%; 65 font-size: 22px; 66 border: 0; 67 } 68 .vertical-center { 69 top: 50%; 70 position: relative; 71 transform: translateY(-50%); 72 } 73 </style> 74 ` 75 $('head').append(css) 76 77 $('.modal-button').on('click', function () { 78 log("click ok") 79 $(".modal-remove").remove() 80 }) 81 }; 82 83 84 // 用于警告的提示框 85 var myAlert2 = function (title, message, callback) { 86 /* 87 title 是 string 88 message 是 string 89 callback 是一个接受一个 bool 类型参数的函数 90 91 这个函数生成一个上课所说的弹窗插入页面 92 弹窗包含 title 作为标题 和 message 作为信息 93 还包含一个 OK 按钮 和一个 Cancel 按钮 94 点击 OK 按钮关闭弹窗, 调用 callback(true) 95 点击 Cancel 按钮关闭弹窗, 调用 callback(false) 96 */ 97 // 插入弹窗 98 var t = ` 99 <div class="modal-container modal-remove"> 100 <div class="modal-mask"></div> 101 <div class="modal-alert vertical-center"> 102 <div class="modal-title">${title}</div> 103 <div class="modal-message">${message}</div> 104 <div class="modal-control"> 105 <button class="modal-button" type="button" name="button" data-type="cancel">Cancel</button><button class="modal-button" type="button" name="button" data-type="ok">OK</button> 106 </div> 107 </div> 108 </div>` 109 $('body').append(t) 110 // 插入CSS 111 var css = ` 112 <style class="modal-remove"> 113 .modal-container{ 114 position: fixed; 115 top: 0; 116 left: 0; 117 width: 100%; 118 height: 100%; 119 } 120 .modal-mask{ 121 position: fixed; 122 top: 0; 123 left: 0; 124 width: 100%; 125 height: 100%; 126 background: black; 127 opacity: 0.5; 128 } 129 .modal-alert { 130 width: 200px; 131 margin: 0 auto; 132 opacity: 1; 133 background: #eeeeee; 134 } 135 .modal-title{ 136 text-align: center; 137 font-size: 18px; 138 background: lightblue; 139 } 140 .modal-message{ 141 padding: 15px 5px; 142 } 143 .modal-control{ 144 font-size: 0; 145 } 146 .modal-button{ 147 width: 50%; 148 height: 100%; 149 font-size: 22px; 150 border: 1px solid #fe78ff; 151 } 152 .vertical-center { 153 top: 50%; 154 position: relative; 155 transform: translateY(-50%); 156 } 157 </style> 158 ` 159 $('head').append(css) 160 161 $('.modal-button').on('click', function (event) { 162 log("click button") 163 var type = $(event.target).data('type') 164 if (type === 'cancel'){ 165 callback(false) 166 } else{ 167 callback(true) 168 } 169 $(".modal-remove").remove() 170 }) 171 172 } 173 174 175 // 用于输入信息的输入框 176 var myAlert3 = function (title, callback) { 177 /* 178 title 是 string 179 callback 是一个如下的函数: 180 function(clickOk, input) { 181 // clickOk 是一个 bool 表明点击的是 OK 还是 Cancel 182 // input 是 string 183 } 184 185 这个函数生成一个上课所说的弹窗插入页面 186 弹窗包含 title 作为标题 187 包含一个 input 让用户输入信息 188 还包含一个 OK 按钮 和一个 Cancel 按钮 189 点击 OK 按钮关闭弹窗, 调用 callback(true, 输入的内容) 190 点击 Cancel 按钮关闭弹窗, 调用 callback(false) 191 */ 192 // 插入弹窗 193 var t = ` 194 <div class="modal-container modal-remove"> 195 <div class="modal-mask"></div> 196 <div class="modal-alert vertical-center"> 197 <div class="modal-title">${title}</div> 198 <div class="modal-message"> 199 <input type="text" class="modal-input"> 200 </div> 201 <div class="modal-control"> 202 <button class="modal-button" type="button" name="button" data-type="cancel">Cancel</button> 203 <button class="modal-button" type="button" name="button" data-type="ok">OK</button> 204 </div> 205 </div> 206 </div>` 207 $('body').append(t) 208 // 插入CSS 209 var css = ` 210 <style class="modal-remove"> 211 .modal-container{ 212 position: fixed; 213 top: 0; 214 left: 0; 215 width: 100%; 216 height: 100%; 217 } 218 .modal-mask{ 219 position: fixed; 220 top: 0; 221 left: 0; 222 width: 100%; 223 height: 100%; 224 background: black; 225 opacity: 0.5; 226 } 227 .modal-alert { 228 width: 200px; 229 margin: 0 auto; 230 opacity: 1; 231 background: #eeeeee; 232 } 233 .modal-title{ 234 text-align: center; 235 font-size: 18px; 236 background: lightblue; 237 } 238 .modal-message{ 239 padding: 15px 5px; 240 } 241 .modal-input{ 242 width: 100%; 243 height: 100%; 244 } 245 .modal-control{ 246 font-size: 0; 247 } 248 .modal-button{ 249 width: 50%; 250 height: 100%; 251 font-size: 22px; 252 border: 1px solid #fe78ff; 253 } 254 .vertical-center { 255 top: 50%; 256 position: relative; 257 transform: translateY(-50%); 258 } 259 </style> 260 ` 261 $('head').append(css) 262 263 $('.modal-button').on('click', function (event) { 264 log("click button") 265 var type = $(event.target).data('type') 266 if (type === 'cancel'){ 267 callback(false) 268 } else{ 269 var value = $('.modal-input').val() 270 callback(true, value) 271 } 272 $(".modal-remove").remove() 273 }) 274 275 } 276 277 278 // 用于选择多个选项中的一个选择框 279 var buttonTemplate = function(title, index) { 280 var t = ` 281 <button class='modal-action-button' data-index="${index}">${title}</button> 282 ` 283 return t 284 } 285 286 var myAlert4 = function (title, actions, callback) { 287 /* 288 title 是 string 289 actions 是一个包含 string 的数组 290 callback 是一个如下的函数: 291 function(index) { 292 // index 是下标, 具体如下 293 // index 如果是 -1 表明用户点击了 cancel 294 } 295 296 这个函数生成一个弹窗页面 297 弹窗包含 title 作为标题 298 actions 里面的 string 作为标题生成按钮 299 弹窗还包含一个 Cancel 按钮 300 点击按钮的时候, 调用 callback(index) 301 */ 302 var buttons = [] 303 for(var i=0; i<actions.length; i++){ 304 buttons.push(buttonTemplate(actions[i], i)) 305 } 306 var actionButtons = buttons.join('') 307 // 插入弹窗 308 var t = ` 309 <div class="modal-container modal-remove"> 310 <div class="modal-mask"></div> 311 <div class="modal-alert vertical-center"> 312 <div class="modal-title">${title}</div> 313 <div class="modal-message"> 314 ${actionButtons} 315 </div> 316 <div class="modal-control"> 317 <button class="modal-button-cancel" type="button" name="button">Cancel</button> 318 </div> 319 </div> 320 </div>` 321 $('body').append(t) 322 // 插入CSS 323 var css = ` 324 <style class="modal-remove"> 325 .modal-container{ 326 position: fixed; 327 top: 0; 328 left: 0; 329 width: 100%; 330 height: 100%; 331 } 332 .modal-mask{ 333 position: fixed; 334 top: 0; 335 left: 0; 336 width: 100%; 337 height: 100%; 338 background: black; 339 opacity: 0.5; 340 } 341 .modal-alert { 342 width: 200px; 343 margin: 0 auto; 344 opacity: 1; 345 background: #eeeeee; 346 } 347 .modal-title{ 348 text-align: center; 349 font-size: 18px; 350 background: lightblue; 351 } 352 .modal-message{ 353 text-align: center; 354 padding: 15px 5px; 355 } 356 .modal-action-button{ 357 width: 100%; 358 font-size: 15px; 359 } 360 .modal-control{ 361 font-size: 0; 362 } 363 .modal-button-cancel{ 364 width: 100%; 365 height: 100%; 366 font-size: 22px; 367 border: 1px solid #fe78ff; 368 } 369 .vertical-center { 370 top: 50%; 371 position: relative; 372 transform: translateY(-50%); 373 } 374 </style> 375 ` 376 $('head').append(css) 377 378 $('.modal-button-cancel').on('click', function(event){ 379 console.log('click cancel button') 380 $('.modal-remove').remove() 381 }) 382 $('.modal-action-button').on('click', function(event){ 383 console.log('click action button') 384 var index = $(event.target).data('index') 385 callback(index, actions[index]) 386 $('.modal-remove').remove() 387 }) 388 389 390 }
2.轮播图
需求:做一个轮播图,和京东首页的轮播图差不多
代码如下:
1 <!-- author: wyb --> 2 <!DOCTYPE html> 3 <html lang="en"> 4 <head> 5 <meta charset="UTF-8"> 6 <meta name="viewport" content="width=device-width, initial-scale=1"> 7 <title>jQuery实现轮播</title> 8 <style> 9 .vertical-center{ 10 position: relative; 11 top: 50%; 12 transform: translateY(-50%); 13 } 14 .container{ 15 width: 30%; 16 margin: 0 auto; 17 } 18 .slide{ 19 width: 300px; 20 height: 200px; 21 margin-top: 166px; 22 } 23 .slide-imgs{ 24 position: relative; 25 width: 100%; 26 height: 100%; 27 } 28 .slide-img{ 29 display: none; 30 width: 100%; 31 height: 100%; 32 } 33 .slider-img-active{ 34 display: block; 35 } 36 /* 轮播图按钮 */ 37 .slider-button{ 38 position: absolute; 39 border: 0; 40 background: rgba(156, 156, 156, 0.78); 41 color: white; 42 padding: 15px 5px; 43 } 44 .slider-button:hover{ 45 background: rgba(53, 53, 53, 0.76); 46 } 47 .slider-button-left{ 48 float: left; 49 left: 0; 50 } 51 .slider-button-right{ 52 float: right; 53 right: 0; 54 } 55 /* 轮播图指示器 */ 56 .slide-indicators{ 57 position: relative; 58 height: 22px; 59 line-height: 22px; 60 bottom: 27px; 61 /*background: gray;*/ 62 text-align: center; 63 } 64 .slide-i{ 65 color: white; 66 display: inline-block; 67 background: gray; 68 border-radius: 50%; 69 padding: 0 6px; 70 margin: 0 3px; 71 } 72 .slide-i-active{ 73 background: red; 74 } 75 76 </style> 77 </head> 78 <body> 79 80 <div class="container"> 81 <div class="slide"> 82 <div class="slide-imgs" data-active="0" data-imgs="4"> 83 <img src="img/1.jpg" alt="1" class="slide-img slider-img-active"> 84 <img src="img/2.jpg" alt="2" class="slide-img"> 85 <img src="img/3.jpg" alt="3" class="slide-img"> 86 <img src="img/4.jpg" alt="4" class="slide-img"> 87 <button class="slider-button slider-button-left vertical-center" type="button"> 88 <span><strong><</strong></span> 89 </button> 90 <button class="slider-button slider-button-right vertical-center" type="button"> 91 <span><strong>></strong></span> 92 </button> 93 </div> 94 <div class="slide-indicators"> 95 <div class="slide-i slide-i-active">1</div> 96 <div class="slide-i">2</div> 97 <div class="slide-i">3</div> 98 <div class="slide-i">4</div> 99 </div> 100 </div> 101 </div> 102 103 104 105 <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script> 106 107 <script> 108 // 改变下方的指示器 109 var changeIndicator = function (index) { 110 $(".slide-i-active").removeClass("slide-i-active") 111 $($(".slide-i")[index]).addClass("slide-i-active") 112 } 113 114 // 轮播 115 var play = function (offset) { 116 var activeIndex = $(".slide-imgs").data("active") 117 var imgNumber = $(".slide-imgs").data("imgs") 118 var index = (activeIndex + imgNumber + offset) % imgNumber 119 $(".slide-imgs").data("active", index) 120 // 121 $(".slider-img-active").removeClass("slider-img-active") 122 // 123 var avtive = $($(".slide-img")[index]) 124 avtive.addClass("slider-img-active") 125 return index 126 } 127 128 // 向前轮播 129 var playPrev = function () { 130 var i = play(-1) 131 changeIndicator(i) 132 } 133 134 // 向后轮播 135 var playNext = function () { 136 var j = play(1) 137 changeIndicator(j) 138 } 139 140 // Next和Before按钮 141 $(".slider-button").on("click", function (event) { 142 var $button = $(event.target); 143 if($button.hasClass('slider-button-left')){ 144 playPrev() 145 } else{ 146 playNext() 147 } 148 149 }) 150 151 // 指示器点击效果 152 $(".slide-indicators").on("click", function (event) { 153 var $target = $(event.target) 154 if($target.hasClass("slide-i")){ 155 var v = $target.text() 156 // 157 $(".slider-img-active").removeClass("slider-img-active") 158 $($(".slide-img")[v-1]).addClass("slider-img-active") 159 $(".slide-imgs").data("active", v-1) 160 // 161 changeIndicator(v-1) 162 } 163 164 165 }) 166 167 // 定时自动轮播 3s换一次 168 setInterval(function () { 169 var j = play(1) 170 changeIndicator(j) 171 }, 3000) 172 173 </script> 174 175 </body> 176 </html>
too young too simple sometimes native!