Заметки будут сохраняться в простых текстовых файлах на сервере. В уроке демонстрируется техника чтения и записи файлов в PHP, изменение размеров области текста с помощью jQuery в зависимости от размера содержания, и простое взаимодействие AJAX.
Нам нужно создать обычный документ HTML5. Ниже представлена только важная часть, остальной код можно посмотреть в файле исходников index.php. PHP код размешен в одном файле со структурой для большей наглядности.
<div id="pad">
<h2>Заметка</h2>
<textarea id="note"><?php echo $note_content ?></textarea>
</div>
Вот и вся разметка, которая нужна для работы нашего приложения. Конечно, мы добавим стили CSS, подключим jQuery и наш скрипт script.js. Обратите внимание, что выражение PHP echo находится в textarea. Так выводится последняя сохраненная заметка пользователя.
Код PHP для нашего примера достаточно простой. Происходит чтение и вывод содержания заметки при загрузке страницы, а когда jQuery посылает запрос AJAX - записываем содержание в файл. Файл записи будет перезаписываться.
$note_name = 'note.txt';
$uniqueNotePerIP = true;
if($uniqueNotePerIP){
// Используем адрес IP пользователя для именования файла заметки.
// Данная техника полезна в случаях, когда приложение
// используют несколько пользователей одновременно.
if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
$note_name = 'notes/'.$_SERVER['HTTP_X_FORWARDED_FOR'].'.txt';
}
else{
$note_name = 'notes/'.$_SERVER['REMOTE_ADDR'].'.txt';
}
}
if(isset($_SERVER['HTTP_X_REQUESTED_WITH'])){
// Запрос AJAX
if(isset($_POST['note'])){
// Записываем файл на диск
file_put_contents($note_name, $_POST['note']);
echo '{"saved":1}';
}
exit;
}
$note_content = '';
if( file_exists($note_name) ){
$note_content = htmlspecialchars( file_get_contents($note_name) );
}
Обратите внимание на переменную $uniqueNotePerIP
. Если она имеет значение true
, каждый пользователь будет иметь уникальный файл заметки с именем на основе IP адреса. При значении false
, все будут использовать один и тот же файл. В таком случае при одновременном использовании приложения несколькими пользователями файл может быть поврежден.
Работа jQuery в нашем приложении заключается в отслеживании изменений в области ввода текста и отправке запроса AJAX post для index.php, где текст будет записан в файл.
Обычный подход в таких случаях - привязка обработчика к событию keypress
. Но иногда такого метода недостаточно, так как пользователь может просто скопировать текст в область ввода, или выбрать предложение от автоматического корректора браузера, или использовать операцию отменить/повторить. В такой ситуации нужно использовать обработчик для другого события - input
, которое поддерживается всеми современными браузерами.
$(function(){
var note = $('#note');
var saveTimer,
lineHeight = parseInt(note.css('line-height')),
minHeight = parseInt(note.css('min-height')),
lastHeight = minHeight,
newHeight = 0,
newLines = 0;
var countLinesRegex = new RegExp('\n','g');
// Событие input запускается нажатием клавиш,
// копированием и даже операциями отмены/повторения.
note.on('input',function(e){
// Очистка таймера предотвращает
// сохранение каждого нажатия клавиш
clearTimeout(saveTimer);
saveTimer = setTimeout(ajaxSaveNote, 2000);
// Подсчет количества новых строк
newLines = note.val().match(countLinesRegex);
if(!newLines){
newLines = [];
}
// Увеличиваем высоту заметки (если нужно)
newHeight = Math.max((newLines.length + 1)*lineHeight, minHeight);
// Увеличиваем/уменьшаем высоту только один раз при изменении
if(newHeight != lastHeight){
note.height(newHeight);
lastHeight = newHeight;
}
}).trigger('input'); // Данная строка будет изменять размер заметки при загрузке страницы
function ajaxSaveNote(){
// Запускаем запрос AJAX POST для сохранения записи
$.post('index.php', { 'note' : note.val() });
}
});
Еще одной полезной техникой является подсчет количества строк в тексте и увеличение области ввода текста автоматически, в зависимости от значения свойства CSS line-height
.
В данном разделе мы определяем стили для трех элементов HTML нашего урока. Для формирования фона в виде листочка для заметок используется псевдо-элемент :after
. При изменении размера области ввода текста в коде jQuery, нижняя часть автоматически сдвигается вниз.
#pad{
position:relative;
width: 374px;
margin: 180px auto 40px;
}
#note{
font: normal 15px 'Courgette', cursive;
line-height: 17px;
color:#444;
background: url('../img/mid.png') repeat-y;
display: block;
border: none;
width: 329px;
min-height: 170px;
overflow: hidden;
resize: none;
outline: 0px;
padding: 0 10px 0 35px;
}
#pad h2{
background: url('../img/header.png') no-repeat;
overflow: hidden;
text-indent: -9999px;
height: 69px;
position: relative;
}
#pad:after{
position:absolute;
content:'';
background:url('../img/footer.png') no-repeat;
width:100%;
height:40px;
}
Для блока #note
используется шрифт Courgette из коллекции Google Web Fonts.