Как сделать собственную программу-тудушку за 10 минут
vk f t

Как сделать собственную программу-тудушку за 10 минут

Поша­го­вое руко­вод­ство

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

Для напи­са­ния про­грам­мы пона­до­бит­ся про­стой тек­сто­вый редак­тор. Мы реко­мен­ду­ем уста­но­вить Sublime Text, у него есть вер­сии для всех ком­пью­те­ров.

Наш спи­сок дел будет рабо­тать так: мы созда­дим спе­ци­аль­ную стра­ни­цу для бра­у­зе­ра. В неё будет вши­та про­грам­ма, кото­рая и ста­нет нашим таск-менеджером. Сна­ча­ла сде­ла­ем кар­кас стра­ни­цы, затем настро­им внеш­ний вид, а потом под­клю­чим код, кото­рый будет запо­ми­нать наши дела и управ­лять ими. Дан­ные будут хра­нить­ся во внут­рен­ней памя­ти бра­у­зе­ра, то есть про­грам­мой пред­по­ла­га­ет­ся поль­зо­вать­ся на ком­пью­те­ре или теле­фоне, и он будет всё пом­нить. Мож­но будет пере­за­гру­жать стра­ни­цу, выклю­чать и сно­ва вклю­чать устрой­ство — инфор­ма­ция сохра­нит­ся.

Создаём макет страницы

Сде­ла­ем пустую HTML-страницу, кото­рая будет отве­чать за наш спи­сок задач. В самом мини­маль­ном виде она выгля­дит так:

    
language: HTML
<!DOCTYPE html>
<html>
    <head>
    </head>
    <body>
    </body>
</html>

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

Над­пи­си внут­ри угло­вых ско­бок — напри­мер, <body> — это спе­ци­аль­ные коман­ды HTML. Они гово­рят бра­у­зе­ру, как вести себя с раз­ны­ми эле­мен­та­ми стра­ни­цы. Пока что на этой стра­ни­це нет эле­мен­тов, есть лишь слу­жеб­ная часть <head>...</head> и часть стра­ни­цы, в кото­рой поз­же будет наша про­грам­ма — <body>...</body>. Это наш чистый лист.

Обра­ти­те вни­ма­ние: в самом нача­ле есть коман­да <!DOCTYPE html>. Она сооб­ща­ет бра­у­зе­ру, что содер­жи­мое фай­ла нуж­но пока­зы­вать как веб-страницу. Если это­го не сде­лать, то ком­пью­тер может не понять неко­то­рые коман­ды и стра­ни­ца будет выгля­деть пло­хо.

Сохра­ним этот текст как файл task.html. Обра­ти­те вни­ма­ние, что рас­ши­ре­ние здесь (то, что идёт после точ­ки) имен­но .html, а не .doc или .txt! Когда мы откро­ем этот файл в бра­у­зе­ре, то уви­дим белую стра­ни­цу, на кото­рой ниче­го нет.

Доба­вим в раз­дел <head> слу­жеб­ную инфор­ма­цию, кото­рая рас­ска­жет ком­пью­те­ру, как рабо­тать с этой стра­ни­цей. С помо­щью над­пи­сей <!--...--> мы остав­ля­ем ком­мен­та­рии — что­бы было понят­но, что про­ис­хо­дит в коде. Бра­у­зер на эти помет­ки не смот­рит, это всё для нас:

    
language: HTML
<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">
<!-- Это служебная информация для браузера, пока можно не вникать -->


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

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

Теперь напол­ним стра­ни­цу смыс­лом: напи­шем заго­ло­вок, поста­вим поле для вво­да задач и преду­смот­рим место для спис­ка. Вста­вим этот кусок кода после тега <body>:

    
language: HTML
<div class="container" style="width: 400px; margin: auto;">

<!-- Ограничиваем ширину списка задач и ставим его по центру -->

   <h2 class="todo__caption">Список задач</h2>
   <!-- Заголовок списка -->

   <!-- Дальше будет поле ввода, куда пишем новые задачи -->
   <div id="tdlApp">
     <input type="text" class="form-control" placeholder="Новая задача">
     <!-- Создаём пока ещё пустой список -->
    <div class="tdlDiv">
       <ul class="tdList list-unstyled">
         <!-- Тут появятся наши задачи, когда мы их добавим -->
       </ul>
     </div>
   </div>
 <!-- Закончили с оформлением списка -->
</div>


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

Сохра­ня­ем файл и обнов­ля­ем стра­ни­цу:


Настраиваем внешний вид

У нас уже есть стра­ни­ца для веде­ния дел, но она пока неопрят­но выгля­дит и ниче­го не уме­ет. Раз­бе­рём­ся сна­ча­ла с внеш­ним видом.

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

Что­бы исполь­зо­вать CSS-элементы внут­ри стра­ни­цы, их поме­ща­ют в слу­жеб­ный раз­дел <head>. Ком­пью­тер дол­жен знать, что это имен­но сти­ли для внеш­не­го вида, а не коман­ды что-то пока­зать, поэто­му они пишут­ся внут­ри тега <style type="text/css"> ... </style>:

    
language: css
<style type="text/css">

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

   body{

     text-align: center;

     margin: 10;

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

     font-size: 16px;

   }

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

   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>, сохра­ня­ем файл и обнов­ля­ем стра­ни­цу:


Теперь наш спи­сок задач выгля­дит акку­рат­нее, но по-прежнему ниче­го не уме­ет. Начи­на­ем про­грам­ми­ро­вать на JavaScript.

Пишем скрипт для работы с задачами

Всю скрип­то­вую часть мы будем писать в кон­це стра­ни­цы, что­бы сна­ча­ла у нас в фай­ле шёл CSS, затем HTML-код самой стра­ни­цы, а после него — JavaScript. Поэто­му все бло­ки поме­ща­ем после послед­не­го тега </div>, когда у нас закон­чи­лась вся визу­аль­ная часть.

Нам пона­до­бит­ся биб­лио­те­ка jQuery, что­бы код мог быст­ро рабо­тать с полем вво­да и спис­ком задач.

jQuery — это отдель­ная биб­лио­те­ка, напи­сан­ная на язы­ке JavaScript. Про­ще гово­ря, это некий набор гото­вых функ­ций, кото­рые упро­ща­ют жизнь раз­ра­бот­чи­ка и напи­са­ние кода. Осо­бен­ность jQuery в том, что она поз­во­ля­ет напря­мую рабо­тать с любым эле­мен­том на стра­ни­це. Это нам при­го­дит­ся для обра­бот­ки кон­крет­ных дел из наше­го спис­ка.

Стро­го гово­ря, всю рабо­ту в этой зада­че мож­но было про­де­лать и без jQuery, на чистом JavaScript, но это зай­мёт немно­го боль­ше вре­ме­ни и будет не так удоб­но и кра­си­во.

    
language: javascript
<!-- Подключаем jQuery -->

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

</script>


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

А теперь пишем сам скрипт, кото­рый будет делать сле­ду­ю­щее: ждать, пока поль­зо­ва­тель не вне­сёт текст в поле вво­да и не нажмёт кла­ви­шу вво­да. После это­го скрипт поме­ща­ет новую зада­чу в память ком­пью­те­ра, а потом добав­ля­ет её в конец спис­ка. Когда зада­ча выпол­не­на и на неё щёлк­ну­ли мыш­кой, скрипт уда­лит соот­вет­ству­ю­щую стро­ку из спис­ка и из памя­ти устрой­ства.

Доба­вим раз­дел с нашим скрип­том после раз­де­ла с jQuery:

    
language: HTML
<script>
  // Тут будет наш скрипт
</script>

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

Заве­дём пере­мен­ные для наших задач, кото­рые отве­ча­ют за спи­сок:

    
language: javascript
var List = $('#tdlApp ul');

var Mask = 'tdl_';


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

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

У каж­до­го бра­у­зе­ра есть своё внут­рен­нее хра­ни­ли­ще дан­ных, где он запо­ми­на­ет инфор­ма­цию с раз­ных сай­тов. Хра­ни­ли­ще назы­ва­ет­ся localStorage. Любой сайт может туда что-то запи­сать, а потом, когда пона­до­бит­ся, извлечь из памя­ти свои дан­ные и рабо­тать с ними даль­ше

LocalStorage хорош тем, что не обну­ля­ет дан­ные, когда вы пере­за­гру­жа­е­те стра­ни­цу. То есть сохра­нён­ная тут инфор­ма­ция будет жить в бра­у­зе­ре, пока вы спе­ци­аль­но её не уда­ли­те. Но есть и мину­сы: если вы откро­е­те стра­ни­цу в дру­гом бра­у­зе­ре или с дру­го­го ком­пью­те­ра, там будет свой localStorage и посмот­реть свои зада­чи с дру­го­го устрой­ства не удаст­ся.

Что­бы хра­нить еди­ный спи­сок задач на раз­ных ком­пью­те­рах и полу­чать к нему доступ по паро­лю, потре­бу­ет­ся боль­шое хозяй­ство с сер­ве­ром, базой дан­ных, авто­ри­за­ци­ей и кучей все­го. Мы в такие дебри пока не поле­зем.

    
language: javascript

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(Mask) == 0){

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

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

             .attr('data-itemid', key)

             .text(localStorage.getItem(key))

             .appendTo(List);

         }

       }

     }

   }



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

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

    
language: javascript
// Если в хранилище уже есть какие-то задачи, то показываем их

showTasks();


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

Теперь при запус­ке скрип­та он про­ве­ря­ет, нет ли чего-то ста­ро­го в памя­ти, и как бы «вспо­ми­на­ет» ваши зада­чи.

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

    
language: javascript
$('#tdlApp 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 = 0;

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

         var element_Id = $(el).attr('data-itemid').slice(4);

         if(element_Id > number_Id)

           number_Id = element_Id;

       })

       number_Id++;

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

       localStorage.setItem(Mask+number_Id,str);

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

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

         .attr('data-itemid', Mask+number_Id)

         .text(str).appendTo(List);

     }

   });


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

Теперь наша про­грам­ма уме­ет запо­ми­нать зада­чи, кото­рые вы вве­ли в поле вво­да. Это про­ис­хо­дит по нажа­тию кла­ви­ши Enter. Оста­лось сде­лать так, что­бы по кли­ку на любой стро­ке в перечне задач она исче­за­ла из памя­ти и уби­ра­лась из спис­ка:

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

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

     var jet = $(e.target);

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

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

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

     jet.remove();

   })


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

Всё, пла­ни­ров­щик готов. Копи­ру­ем эти части кода в наш раз­дел со скрип­том и про­ве­ря­ем рабо­ту:


Если мы закро­ем эту стра­ни­цу или пере­за­гру­зим ком­пью­тер, то дан­ные всё рав­но оста­нут­ся в памя­ти. Зна­чит, про­грам­ма рабо­та­ет как нуж­но и у нас всё полу­чи­лось.
Пол­ный текст стра­ни­цы (мож­но ско­пи­ро­вать цели­ком и вста­вить в тек­сто­вый редак­тор):

    
language: HTML
<!DOCTYPE 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">

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

 <style type="text/css">

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

   body{

     text-align: center;

     margin: 10;

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

     font-size: 16px;

   }

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

   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"  style="width: 400px; margin: auto;">

   <!-- Заголовок списка -->

   <h2 class="todo__caption">Список задач</h2>

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

   <div id="tdlApp">

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

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

     <div class="tdlDiv">

       <ul class="List list-unstyled">

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

       </ul>

     </div>

   </div>

 <!-- Закончили с оформлением списка -->

 </div>

<!-- Закончилась видимая часть -->

 <!-- Подключаем JQuery -->

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

 </script>

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

 <script>

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

   var List = $('#tdlApp ul');

   var Mask = 'tdl_';

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

   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(Mask) == 0){

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

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

             .attr('data-itemid', key)

             .text(localStorage.getItem(key))

             .appendTo(List);

         }

       }

     }

   }

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

   showTasks();

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

   $('#tdlApp 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 = 0;

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

         var element_Id = $(el).attr('data-itemid').slice(4);

         if(element_Id > number_Id)

           number_Id = element_Id;

       })

       number_Id++;

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

       localStorage.setItem(Mask+number_Id,str);

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

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

         .attr('data-itemid', Mask+number_Id)

         .text(str).appendTo(List);

     }

   });

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

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

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

     var jet = $(e.target);

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

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

 

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

     jet.remove();

   })

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

 </script>

<!-- Закончилось содержимое страницы-->

</body>

</html>


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

Что можно ещё сделать

Мож­но пере­кра­сить любой эле­мент на стра­ни­це: для это­го в таб­ли­це сти­лей CSS нуж­но про­пи­сать свой­ства нуж­ных вам объ­ек­тов. Набе­ри­те в Яндек­се «CSS сме­нить фон стра­ни­цы», и интер­нет вам под­ска­жет реше­ние.

Мож­но попро­бо­вать вста­вить в нача­ло каж­дой зада­чи эмод­зи, что­бы спи­сок стал нагляд­нее. Что­бы это сде­лать, после про­вер­ки дли­ны стро­ки (если она нену­ле­вая и поль­зо­ва­тель ввёл какой-то текст) добавь­те опе­ра­цию сло­же­ния сим­во­ла и стро­ки. Пер­вое сла­га­е­мое (сим­вол) — код эмод­зи, напри­мер #128522, а вто­рое сла­га­е­мое — та стро­ка с зада­чей, кото­рую ввёл поль­зо­ва­тель. Резуль­тат поло­жи­те сно­ва в эту же строч­ку. Теперь у вас вна­ча­ле будет идти кра­си­вый смай­лик, а затем — текст зада­чи.

Мож­но доба­вить звук на закры­тие зада­чи. Для это­го исполь­зуй­те тег <audio> и добавь­те в конец функ­ции кли­ка по зада­че коман­ду audio.play с помо­щью jQuery.

Ещё по теме