Делаем свой планировщик задач
vk f t

Делаем свой планировщик задач

Bootstrap + TodoList = Trello

Трел­ло — удоб­ная шту­ка для веде­ния про­ек­тов. Там все зада­чи пред­став­ле­ны в виде коло­нок, а каж­дая колон­ка отве­ча­ет за что-то своё. Давай­те сде­ла­ем нечто подоб­ное, тем более что всё для это­го у нас уже есть:

Если это объ­еди­нить, полу­чит­ся что-то похо­жее на Trello. Логи­ка такая:

Мы сде­ла­ем 4 колон­ки, но вы для себя може­те сде­лать их столь­ко, сколь­ко нуж­но. Един­ствен­ное огра­ни­че­ние — Bootstrap не поз­во­ля­ет делать боль­ше 12 коло­нок. Наде­ем­ся, вам это­го хва­тит.

Готовим колонки и настраиваем стили

За осно­ву возь­мём стра­ни­цу из ста­тьи про коти­ков и сде­ла­ем с ней сле­ду­ю­щее:

Если мы всё сде­ла­ем пра­виль­но, то полу­чит­ся сле­ду­ю­щее:

    
language: HTML
<html>

<!-- служебная часть -->

<head>

  <!-- заголовок страницы -->

  <title>Управление проектами</title>

  <!-- настраиваем служебную информацию для браузеров -->

  <meta charset="utf-8">

  <meta http-equiv="X-UA-Compatible" content="IE=edge">

  <meta name="viewport" content="width=device-width, initial-scale=1">

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

  <!-- задаём CSS-стили прямо здесь же, чтобы всё было в одном файле -->

  <style type="text/css">

    /*Задаём общие параметры для всей страницы: шрифт и отступы*/

    body{

      text-align: center;

      margin: 10;

      font-family: Verdana, Arial, sans-serif;

      font-size: 16px;

    }

    /* Внешний вид заголовка первого уровня*/

    h1{

      margin-bottom: 50px;

      font-weight: bold;

    }

    /* Внешний вид заголовка второго уровня*/

    h2{

      font-size: 22px;

    }

    /* Настраиваем внешний вид поля ввода*/

    input{

      display: inline-block;

      margin: 20px auto;

      border: 2px solid #eee;

      padding: 10px 20px;

      font-family: Verdana, Arial, sans-serif;

      font-size: 16px;

    }

    /*Как будет выглядеть каждый элемент нашего списка*/

    .tdItem{

      text-align: left;

      padding: 10px;

      cursor: default;

      border-radius: 7px;

    }

    /*Что произойдёт, когда мы наведём курсор на любую задачу из списка*/

    .tdItem:hover{

      background-color: lightblue;

    }

  /*Закончили со стилями*/

  </style>

<!-- закрываем служебную часть страницы -->

</head>

<body>

  <div class="container" >

    <div class="row">

 

      <div class="col-12">

        <h1>Управление проектами, делами и собой</h1>

      </div>

 

    </div>

  </div>

 

  <div class="container" >

    <div class="row">

      

      <div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3">

        <!-- содержимое первой колонки -->

      </div>

 

     <div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3">

        <!-- содержимое второй колонки -->

      </div>

 

      <div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3">

        <!-- содержимое третьей колонки -->

      </div>

 

      <div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3">

        <!-- содержимое четвёртой колонки -->

      </div>

 

    </div>

  </div>

 

</body>

<!-- конец всей страницы -->

</html>


Ско­пи­ро­вать код
Код ско­пи­ро­ван

Наполняем колонки

У каж­дой колон­ки долж­но быть своё назва­ние, поэто­му назо­вём их «Сде­лать», «Позво­нить», «Напи­сать» и «Идеи».

Мы пом­ним, что в каж­дой колон­ке дол­жен быть отдель­ный спи­сок задач, поэто­му возь­мём кусок кода из про­шло­го мате­ри­а­ла. Глав­ное, что нам нуж­но учесть, — что у каж­до­го спис­ка долж­но быть своё уни­каль­ное имя, что­бы мы их не пере­пу­та­ли в про­цес­се. Для это­го мы про­сто доба­вим циф­ры от одно­го до четы­рёх к назва­нию каж­до­го спис­ка. Напри­мер, было «tldDiv», а ста­ло «tld1Div, «tld2Div» и так далее.

В ито­ге колон­ки будут выгля­деть так:

    
language: HTML
<div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3">

        <h2 class="todo__caption">Позвонить</h2>

        <!-- Поле ввода, куда пишем новые задачи «Позвонить» -->

        <div id="tdl2App">

          <input type="text" class="form-control" placeholder="Новая задача">

         <!-- Создаём пока ещё пустой список «Позвонить» -->

          <div class="tdl2Div">

            <ul class="List list-unstyled">

              <!-- Тут появятся наши задачи, когда мы их добавим -->

            </ul>

          </div>

        </div>

      </div>

 

      <div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3">

        <h2 class="todo__caption">Написать</h2>

        <!-- Поле ввода, куда пишем новые задачи «Написать»-->

        <div id="tdl3App">

          <input type="text" class="form-control" placeholder="Новая задача">

         <!-- Создаём пока ещё пустой список «Написать» -->

          <div class="tdl3Div">

            <ul class="List list-unstyled">

              <!-- Тут появятся наши задачи, когда мы их добавим -->

            </ul>

          </div>

        </div>

      </div>

 

      <div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3">

        <h2 class="todo__caption">Идеи</h2>

        <!-- Поле ввода, куда пишем новые задачи «Идеи» -->

        <div id="tdl4App">

          <input type="text" class="form-control" placeholder="Новая задача">

         <!-- Создаём пока ещё пустой список «Идеи» -->

          <div class="tdl4Div">

            <ul class="List list-unstyled">

              <!-- Тут появятся наши задачи, когда мы их добавим -->

            </ul>

          </div>

        </div>

      </div>


Ско­пи­ро­вать код
Код ско­пи­ро­ван
Выгля­дит инте­рес­но, но пока ниче­го не рабо­та­ет.

Переносим и расширяем скрипт

Теперь наша зада­ча — взять про­шлый скрипт и адап­ти­ро­вать его под наши цели. Нам нуж­но, что­бы каж­дая колон­ка с зада­ча­ми рабо­та­ла авто­ном­но и не зави­се­ла от дру­гих, поэто­му сей­час скрипт уве­ли­чит­ся в 4 раза — для каж­до­го спис­ка будет свой код.

Сра­зу ска­жем: это пло­хое реше­ние. Копи­паст кода для рас­ши­ре­ния функ­ци­о­наль­но­сти — это путь к дол­гой мучи­тель­ной смер­ти под зава­ла­ми спагетти-кода. По-хорошему нуж­но заво­ра­чи­вать это при­ло­же­ние в клас­сы, делать объ­ек­ты и рабо­тать с ними.

Мы всё это пони­ма­ем.

Но копи­па­с­та быст­рее.

Если собрать все изме­не­ния, кото­рые нам пона­до­бят­ся, то полу­чит­ся такой спи­сок:

Един­ствен­ное, что оста­лось преж­ним, — обра­бот­ка уда­ле­ния зада­чи. В обра­бот­чи­ке всё уже изна­чаль­но орга­ни­зо­ва­но так, что скрипт сра­зу полу­ча­ет все дан­ные, кото­рые ему нуж­ны, неза­ви­си­мо от колон­ки и поряд­ко­во­го номе­ра зада­чи.

Сам скрипт полу­ча­ет­ся таким:

    
language: JavaScript
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js">

</script>

<!-- Пишем скрипт, который будет обрабатывать наши задачи и хранить их на нашем устройстве -->

<script>

  // Заводим переменные под наши задачи

  var List1 = $('#tdl1App ul');

  var Mask1 = 'tdl1_';

 

  var List2 = $('#tdl2App ul');

  var Mask2 = 'tdl2_';

 

  var List3 = $('#tdl3App ul');

  var Mask3 = 'tdl3_';

 

  var List4 = $('#tdl4App ul');

  var Mask4 = 'tdl4_';

 

  // Функция, которая берёт из памяти наши задачи и делает из них список

  function showTasks(){

    // Узнаём размер хранилища

    var Storage_size = localStorage.length;

    // Если в хранилище что-то есть…

    if (Storage_size > 0){

      // то берём и добавляем это в задачи  

      for (var i = 0; i < Storage_size; i++){

        var key = localStorage.key(i);

 

        // обрабатываем первый список

        if(key.indexOf(Mask1) == 0){

          // и делаем это элементами списка

          $('<li></li>').addClass('tdItem')

            .attr('data-itemid', key)

            .text(localStorage.getItem(key))

            .appendTo(List1);

        }

 

        // обрабатываем второй список

        if(key.indexOf(Mask2) == 0){

          // и делаем это элементами списка

          $('<li></li>').addClass('tdItem')

            .attr('data-itemid', key)

            .text(localStorage.getItem(key))

            .appendTo(List2);

        }

 

        // обрабатываем третий список

        if(key.indexOf(Mask3) == 0){

          // и делаем это элементами списка

          $('<li></li>').addClass('tdItem')

            .attr('data-itemid', key)

            .text(localStorage.getItem(key))

            .appendTo(List3);

        }

 

        // обрабатываем четвёртый список

        if(key.indexOf(Mask4) == 0){

          // и делаем это элементами списка

          $('<li></li>').addClass('tdItem')

            .attr('data-itemid', key)

            .text(localStorage.getItem(key))

            .appendTo(List4);

        }

      }

    }

  }

  // Сразу вызываем эту функцию, вдруг в памяти уже остались задачи с прошлого раза

  showTasks();

  // Следим, когда пользователь напишет новую задачу в первое поле ввода и нажмёт Enter

  $('#tdl1App input').on('keydown',function(e){

    if(e.keyCode != 13) return;

    var str = e.target.value;

    e.target.value = "";

    // Если в поле ввода было что-то написано — начинаем обрабатывать

    if(str.length > 0){

      var number_Id_1 = 0;

      List1.children().each(function(index, el){

        var element_Id_1 = $(el).attr('data-itemid').slice(5);

        if(element_Id_1 > number_Id_1)

          number_Id_1 = element_Id_1;

      })

      number_Id_1++;

      // Отправляем новую задачу сразу в память

      localStorage.setItem(Mask1+number_Id_1,str);

      // и добавляем её в конец списка

      $('<li></li>').addClass('tdItem')

        .attr('data-itemid', Mask1+number_Id_1)

        .text(str).appendTo(List1);

    }

  });

 

  // Следим, когда пользователь напишет новую задачу во второе поле ввода и нажмёт Enter

  $('#tdl2App input').on('keydown',function(e){

    if(e.keyCode != 13) return;

    var str = e.target.value;

    e.target.value = "";

    // Если в поле ввода было что-то написано — начинаем обрабатывать

    if(str.length > 0){

      var number_Id_2 = 0;

      List2.children().each(function(index, el){

        var element_Id_2 = $(el).attr('data-itemid').slice(5);

        if(element_Id_2 > number_Id_2)

          number_Id_2 = element_Id_2;

      })

      number_Id_2++;

      // Отправляем новую задачу сразу в память

      localStorage.setItem(Mask2+number_Id_2,str);

      // и добавляем её в конец списка

      $('<li></li>').addClass('tdItem')

        .attr('data-itemid', Mask2+number_Id_2)

        .text(str).appendTo(List2);

    }

  });

 

  // Следим, когда пользователь напишет новую задачу в третье поле ввода и нажмёт Enter

  $('#tdl3App input').on('keydown',function(e){

    if(e.keyCode != 13) return;

    var str = e.target.value;

    e.target.value = "";

    // Если в поле ввода было что-то написано — начинаем обрабатывать

    if(str.length > 0){

      var number_Id_3 = 0;

      List3.children().each(function(index, el){

        var element_Id_3 = $(el).attr('data-itemid').slice(5);

        if(element_Id_3 > number_Id_3)

          number_Id_3 = element_Id_3;

      })

      number_Id_3++;

      // Отправляем новую задачу сразу в память

      localStorage.setItem(Mask3+number_Id_3,str);

      // и добавляем её в конец списка

      $('<li></li>').addClass('tdItem')

        .attr('data-itemid', Mask3+number_Id_3)

        .text(str).appendTo(List3);

    }

  });

 

  // Следим, когда пользователь напишет новую задачу в четвёртое поле ввода и нажмёт Enter

  $('#tdl4App input').on('keydown',function(e){

    if(e.keyCode != 13) return;

    var str = e.target.value;

    e.target.value = "";

    // Если в поле ввода было что-то написано — начинаем обрабатывать

    if(str.length > 0){

      var number_Id_4 = 0;

      List4.children().each(function(index, el){

        var element_Id_4 = $(el).attr('data-itemid').slice(5);

        if(element_Id_4 > number_Id_4)

          number_Id_4 = element_Id_4;

      })

      number_Id_4++;

      // Отправляем новую задачу сразу в память

      localStorage.setItem(Mask4+number_Id_4,str);

      // и добавляем её в конец списка

      $('<li></li>').addClass('tdItem')

        .attr('data-itemid', Mask4+number_Id_4)

        .text(str).appendTo(List4);

    }

  });

 

  // По клику на задаче — убираем её из списка

  $(document).on('click','.tdItem', function(e){

    // Находим задачу, по которой кликнули

    var jet = $(e.target);

    // Убираем её из памяти

    localStorage.removeItem(jet.attr('data-itemid'));

 

    // и убираем её из списка

    jet.remove();

  })

// Закончился основной скрипт 

</script>


Ско­пи­ро­вать код
Код ско­пи­ро­ван

Собираем готовую страницу

Нам оста­лось собрать всё вме­сте и про­ве­рить, как это рабо­та­ет. Если буде­те добав­лять колон­ки — не забудь­те про новые назва­ния для пере­мен­ных и про име­на эле­мен­тов в самих колон­ках. На теку­щем эта­пе мы добав­ля­ем всё вруч­ную, но в буду­щей вер­сии сде­ла­ем гене­ра­тор нуж­но­го чис­ла коло­нок.

    
language: HTML
<html>

<!-- служебная часть -->

<head>

  <!-- заголовок страницы -->

  <title>Управление проектами</title>

  <!-- настраиваем служебную информацию для браузеров -->

  <meta charset="utf-8">

  <meta http-equiv="X-UA-Compatible" content="IE=edge">

  <meta name="viewport" content="width=device-width, initial-scale=1">

  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

  <!-- задаём CSS-стили прямо здесь же, чтобы всё было в одном файле -->

  <style type="text/css">

    /*Задаём общие параметры для всей страницы: шрифт и отступы*/

    body{

      text-align: center;

      margin: 10;

      font-family: Verdana, Arial, sans-serif;

      font-size: 16px;

    }

    /* Внешний вид заголовка первого уровня*/

    h1{

      margin-bottom: 50px;

      font-weight: bold;

    }

    /* Внешний вид заголовка второго уровня*/

    h2{

      font-size: 22px;

    }

    /* Настраиваем внешний вид поля ввода*/

    input{

      display: inline-block;

      margin: 20px auto;

      border: 2px solid #eee;

      padding: 10px 20px;

      font-family: Verdana, Arial, sans-serif;

      font-size: 16px;

    }

    /*Как будет выглядеть каждый элемент нашего списка*/

    .tdItem{

      text-align: left;

      padding: 10px;

      cursor: default;

      border-radius: 7px;

    }

    /*Что произойдёт, когда мы наведём курсор на любую задачу из списка*/

    .tdItem:hover{

      background-color: lightblue;

    }

  /*Закончили со стилями*/

  </style>

<!-- закрываем служебную часть страницы -->

</head>

<body>

  <div class="container" >

    <div class="row">

 

      <div class="col-12">

        <h1>Управление проектами, делами и собой</h1>

      </div>

 

    </div>

  </div>

 

  <div class="container" >

    <div class="row">

      

      <div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3">

        <h2 class="todo__caption">Сделать</h2>

        <!-- Поле ввода, куда пишем новые задачи «Сделать»-->

        <div id="tdl1App">

          <input type="text" class="form-control" placeholder="Новая задача">

         <!-- Создаём пока ещё пустой список «Сделать» -->

          <div class="tdl1Div">

            <ul class="List list-unstyled">

              <!-- Тут появятся наши задачи, когда мы их добавим -->

            </ul>

          </div>

        </div>

      </div>

 

      <div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3">

        <h2 class="todo__caption">Позвонить</h2>

        <!-- Поле ввода, куда пишем новые задачи «Позвонить» -->

        <div id="tdl2App">

          <input type="text" class="form-control" placeholder="Новая задача">

         <!-- Создаём пока ещё пустой список «Позвонить» -->

          <div class="tdl2Div">

            <ul class="List list-unstyled">

              <!-- Тут появятся наши задачи, когда мы их добавим -->

            </ul>

          </div>

        </div>

      </div>

 

      <div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3">

        <h2 class="todo__caption">Написать</h2>

        <!-- Поле ввода, куда пишем новые задачи «Написать»-->

        <div id="tdl3App">

          <input type="text" class="form-control" placeholder="Новая задача">

         <!-- Создаём пока ещё пустой список «Написать» -->

          <div class="tdl3Div">

            <ul class="List list-unstyled">

              <!-- Тут появятся наши задачи, когда мы их добавим -->

            </ul>

          </div>

        </div>

      </div>

 

      <div class="col-12 col-sm-6 col-md-3 col-lg-3 col-xl-3">

        <h2 class="todo__caption">Идеи</h2>

        <!-- Поле ввода, куда пишем новые задачи «Идеи» -->

        <div id="tdl4App">

          <input type="text" class="form-control" placeholder="Новая задача">

         <!-- Создаём пока ещё пустой список «Идеи» -->

          <div class="tdl4Div">

            <ul class="List list-unstyled">

              <!-- Тут появятся наши задачи, когда мы их добавим -->

            </ul>

          </div>

        </div>

      </div>

 

    </div>

  </div>

 

  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js">

  </script>

  <!-- Пишем скрипт, который будет обрабатывать наши задачи и хранить их на нашем устройстве -->

  <script>

    // Заводим переменные под наши задачи

    var List1 = $('#tdl1App ul');

    var Mask1 = 'tdl1_';

 

    var List2 = $('#tdl2App ul');

    var Mask2 = 'tdl2_';

 

    var List3 = $('#tdl3App ul');

    var Mask3 = 'tdl3_';

 

    var List4 = $('#tdl4App ul');

    var Mask4 = 'tdl4_';

 

    // Функция, которая берёт из памяти наши задачи и делает из них список

    function showTasks(){

      // Узнаём размер хранилища

      var Storage_size = localStorage.length;

      // Если в хранилище что-то есть…

      if (Storage_size > 0){

        // то берём и добавляем это в задачи  

        for (var i = 0; i < Storage_size; i++){

          var key = localStorage.key(i);

 

          // обрабатываем первый список

          if(key.indexOf(Mask1) == 0){

            // и делаем это элементами списка

            $('<li></li>').addClass('tdItem')

              .attr('data-itemid', key)

              .text(localStorage.getItem(key))

              .appendTo(List1);

          }

 

          // обрабатываем второй список

          if(key.indexOf(Mask2) == 0){

            // и делаем это элементами списка

            $('<li></li>').addClass('tdItem')

              .attr('data-itemid', key)

              .text(localStorage.getItem(key))

              .appendTo(List2);

          }

 

          // обрабатываем третий список

          if(key.indexOf(Mask3) == 0){

            // и делаем это элементами списка

            $('<li></li>').addClass('tdItem')

              .attr('data-itemid', key)

              .text(localStorage.getItem(key))

              .appendTo(List3);

          }

 

          // обрабатываем четвёртый список

          if(key.indexOf(Mask4) == 0){

            // и делаем это элементами списка

            $('<li></li>').addClass('tdItem')

              .attr('data-itemid', key)

              .text(localStorage.getItem(key))

              .appendTo(List4);

          }

        }

      }

    }

    // Сразу вызываем эту функцию, вдруг в памяти уже остались задачи с прошлого раза

    showTasks();

    // Следим, когда пользователь напишет новую задачу в первое поле ввода и нажмёт Enter

    $('#tdl1App input').on('keydown',function(e){

      if(e.keyCode != 13) return;

      var str = e.target.value;

      e.target.value = "";

      // Если в поле ввода было что-то написано — начинаем обрабатывать

      if(str.length > 0){

        var number_Id_1 = 0;

        List1.children().each(function(index, el){

          var element_Id_1 = $(el).attr('data-itemid').slice(5);

          if(element_Id_1 > number_Id_1)

            number_Id_1 = element_Id_1;

        })

        number_Id_1++;

        // Отправляем новую задачу сразу в память

        localStorage.setItem(Mask1+number_Id_1,str);

        // и добавляем её в конец списка

        $('<li></li>').addClass('tdItem')

          .attr('data-itemid', Mask1+number_Id_1)

          .text(str).appendTo(List1);

      }

    });

 

    // Следим, когда пользователь напишет новую задачу во второе поле ввода и нажмёт Enter

    $('#tdl2App input').on('keydown',function(e){

      if(e.keyCode != 13) return;

      var str = e.target.value;

      e.target.value = "";

      // Если в поле ввода было что-то написано — начинаем обрабатывать

      if(str.length > 0){

        var number_Id_2 = 0;

        List2.children().each(function(index, el){

          var element_Id_2 = $(el).attr('data-itemid').slice(5);

          if(element_Id_2 > number_Id_2)

            number_Id_2 = element_Id_2;

        })

        number_Id_2++;

        // Отправляем новую задачу сразу в память

        localStorage.setItem(Mask2+number_Id_2,str);

        // и добавляем её в конец списка

        $('<li></li>').addClass('tdItem')

          .attr('data-itemid', Mask2+number_Id_2)

          .text(str).appendTo(List2);

      }

    });

 

    // Следим, когда пользователь напишет новую задачу в третье поле ввода и нажмёт Enter

    $('#tdl3App input').on('keydown',function(e){

      if(e.keyCode != 13) return;

      var str = e.target.value;

      e.target.value = "";

      // Если в поле ввода было что-то написано — начинаем обрабатывать

      if(str.length > 0){

        var number_Id_3 = 0;

        List3.children().each(function(index, el){

          var element_Id_3 = $(el).attr('data-itemid').slice(5);

          if(element_Id_3 > number_Id_3)

            number_Id_3 = element_Id_3;

        })

        number_Id_3++;

        // Отправляем новую задачу сразу в память

        localStorage.setItem(Mask3+number_Id_3,str);

        // и добавляем её в конец списка

        $('<li></li>').addClass('tdItem')

          .attr('data-itemid', Mask3+number_Id_3)

          .text(str).appendTo(List3);

      }

    });

 

    // Следим, когда пользователь напишет новую задачу в четвёртое поле ввода и нажмёт Enter

    $('#tdl4App input').on('keydown',function(e){

      if(e.keyCode != 13) return;

      var str = e.target.value;

      e.target.value = "";

      // Если в поле ввода было что-то написано — начинаем обрабатывать

      if(str.length > 0){

        var number_Id_4 = 0;

        List4.children().each(function(index, el){

          var element_Id_4 = $(el).attr('data-itemid').slice(5);

          if(element_Id_4 > number_Id_4)

            number_Id_4 = element_Id_4;

        })

        number_Id_4++;

        // Отправляем новую задачу сразу в память

        localStorage.setItem(Mask4+number_Id_4,str);

        // и добавляем её в конец списка

        $('<li></li>').addClass('tdItem')

          .attr('data-itemid', Mask4+number_Id_4)

          .text(str).appendTo(List4);

      }

    });

 

    // По клику на задаче — убираем её из списка

    $(document).on('click','.tdItem', function(e){

      // Находим задачу, по которой кликнули

      var jet = $(e.target);

      // Убираем её из памяти

      localStorage.removeItem(jet.attr('data-itemid'));

  

      // и убираем её из списка

      jet.remove();

    })

  // Закончился основной скрипт 

  </script> 

</body>

<!-- конец всей страницы -->

</html>


Ско­пи­ро­вать код
Код ско­пи­ро­ван


Что дальше

Что­бы этот про­дукт стал бли­же к иде­а­лу, мож­но сде­лать так:

Ско­ро добе­рём­ся и до это­го!

Ещё по теме