• 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>
    todo程序的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();
    todo程序对应的js文件
      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              100%;
     37             height: 100%;
     38         }
     39         .modal-mask{
     40             position: fixed;
     41             top: 0;
     42             left: 0;
     43              100%;
     44             height: 100%;
     45             background: black;
     46             opacity: 0.5;
     47         }
     48         .modal-alert {
     49              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              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              100%;
    118             height: 100%;
    119         }
    120         .modal-mask{
    121             position: fixed;
    122             top: 0;
    123             left: 0;
    124              100%;
    125             height: 100%;
    126             background: black;
    127             opacity: 0.5;
    128         }
    129         .modal-alert {
    130              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              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              100%;
    216             height: 100%;
    217         }
    218         .modal-mask{
    219             position: fixed;
    220             top: 0;
    221             left: 0;
    222              100%;
    223             height: 100%;
    224             background: black;
    225             opacity: 0.5;
    226         }
    227         .modal-alert {
    228              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              100%;
    243             height: 100%;
    244         }
    245         .modal-control{
    246             font-size: 0;
    247         }
    248         .modal-button{
    249              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              100%;
    330             height: 100%;
    331         }
    332         .modal-mask{
    333             position: fixed;
    334             top: 0;
    335             left: 0;
    336              100%;
    337             height: 100%;
    338             background: black;
    339             opacity: 0.5;
    340         }
    341         .modal-alert {
    342              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              100%;
    358             font-size: 15px;
    359         }
    360         .modal-control{
    361             font-size: 0;
    362         }
    363         .modal-button-cancel{
    364              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 }
    自定义弹窗的js文件

    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              30%;
     16             margin: 0 auto;
     17         }
     18         .slide{
     19              300px;
     20             height: 200px;
     21             margin-top: 166px;
     22         }
     23         .slide-imgs{
     24             position: relative;
     25              100%;
     26             height: 100%;
     27         }
     28         .slide-img{
     29             display: none;
     30              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>&lt;</strong></span>
     89                 </button>
     90                 <button class="slider-button slider-button-right vertical-center" type="button">
     91                     <span><strong>&gt;</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>
  • 相关阅读:
    Windows phone开发 网络编程之HttpWebRequest
    ASP.NET AJAX应用
    Web程序安全机制
    SQLCE本地数据库
    Web服务
    LINQ数据库技术
    windows phone媒体应用开发
    ASP.NET文件操作
    ASP.NET XML文件
    centos6.5安装配置fastdfs+nginx实现分布式图片服务器
  • 原文地址:https://www.cnblogs.com/wyb666/p/9438434.html
Copyright © 2020-2023  润新知