Бывают случаи, когда вам может понадобиться создать перетаскиваемый элемент внутри вашего веб-приложения. Это отличная функциональность, однако, возможно вы хотите, чтобы элемент оставался на новом месте, после перетаскивания. В сегодняшней статье вы узнаете, как можно легко перетаскивать и закреплять в новом месте нужный элемент даже после перезагрузки страницы, с помощью захвата и хранения его X и Y координат.
Сценарий
Итак, у вас есть элемент на странице. Вы можете перетаскивать его туда-сюда. Но, когда страница перезагружается, элемент возвращается на исходную позицию. И хотя нам нужно, чтобы элемент был перетаскиваемый, при этом нужно, чтобы наш элемент достаточно было перетащить один раз. Давайте рассмотрим простое решение, реализующее данную функциональность.
Начало
Для этого примера нам понадобится библиотека jQuery, jQuery UI и плагин JQuery-JSON. Кроме этого, мы также будем использовать PHP и базу данных MySQL для разбора и хранения наших данных. Если вы новичок в jQuery, не беспокойтесь. JQuery — это расширяемая, быстрая и легковесная JavaScript-библиотека, которую легко и весело использовать. Библиотека имеет хорошо структурированную документацию и огромное сообщество.
HTML и CSS
Начнем с HTML-разметки и стилей для нашего примера. Сначала CSS:
html, body { background:#151515; margin:0 0 0 0; padding:0 0 0 0; } #glassbox { background:#333; border:1px solid #000; height:400px; margin:30px auto auto auto; position:relative; width:960px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } #element { background:#666; border:1px #000 solid; cursor:move; height:143px; padding:10px 10px 10px 10px; width:202px; -moz-border-radius: 10px; -webkit-border-radius: 10px; } #respond{ color:#fff; margin:0 auto 0 auto; width:960px; }
CSS – очень простой. Мы назначаем html и body нулевые свойства, для чистки внешних и внутренних отступов, далее устанавливаем значения высоты, ширины и другие свойства для наших элементов. —moz-border-radius
и -webkit-border-radius
– это два свойства, позволяющие нам создать закругленные углы (работает пока только в Mozilla Firefox и Safari 3) для наших элементов. Теперь, давайте взглянем на HTML:
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Simple Draggable Element Persistence with jQuery</title> <link rel="stylesheet" href="style.css" type="text/css" /> <script type="text/javascript" src="js/jquery-1.3.2.min.js"></script> <script type="text/javascript" src="js/jquery-ui-1.7.2.custom.min.js"></script> <script type="text/javascript" src="js/jquery.json-2.2.min.js"></script> </head> <body> <div id="glassbox"> <div id="element"><img src="nettuts.jpg" alt="Nettuts+" />Move the Box<p></p></div> </div> <div id="respond"></div>
Как видите, мы создали очень простую страницу, в которую подключили наш CSS, библиотеку JavaScript и плагины, кроме того, страница содержит элементы, к которым мы будем применять некоторые эффекты и события. Обратите внимание, что файл jquery-ui представляет собой специальную сборку, включающую в себя только ядро и функции перетаскивания элементов.
JavaScript
Теперь самое интересное! Сначала давайте рассмотрим базовые функции, которые мы будем использовать для применения некоторых эффектов к нашим элементам. Разберем все до основания.
<script type="text/javascript"> $(document).ready(function() { $("#element").draggable({ containment: '#glassbox', scroll: false })
Сначала мы говорим браузеру: «Эй, это код, который мы хотим запустить; это не HTML, это JavaScript». Затем, мы ждем пока документ полностью загрузится, после того как это случилось, вызываем функцию для получения нашего блока #element
, и добавляем к нему обработчик перетаскивания с базовыми настройками. Опция containment
содержит наш элемент внутри родительского блока, и мы устанавливаем значение scroll
в false
, потому что, нам не нужен скролл.
Двигаемся дальше:
.mousemove(function(){ var coord = $(this).position(); $("p:last").text( "left: " + coord.left + ", top: " + coord.top ); })
Внутри этого фрагмента, мы вызываем, обработчик события mousemove и говорим ему: «Когда мышь передвигается, установить переменную coord
равной значению текущей позиции нашего блока #element» Затем мы получаем последний параграф в блоке #(“p: last”)
и печатаем текст, выводящий значения свойств left(x)
и top(y)
нашего элемента, относительно родительского объекта (которым является блок #glassbox
).
.mouseup(function(){ var coords=[]; var coord = $(this).position(); var item={ coordTop: coord.left, coordLeft: coord.top }; coords.push(item); var order = { coords: coords }; $.post('updatecoords.php', 'data='+$.toJSON(order), function(response){ if(response=="success") $("#respond").html('<div class="success">X and Y Coordinates Saved!</div>').hide().fadeIn(1000); setTimeout(function(){ $('#respond').fadeOut(1000); }, 2000); }); }); }); lt;/script>
Ну да, здесь уже сложнее. В этом фрагменте мы собираемся сделать кучу вещей. Сначала, мы устанавливаем пустой массив, а затем получаем некоторые значения для его наполнения. С помощью вызова обработчика событий .mouseup()
мы велим браузеру отслеживать событие, когда вы отпускаете кнопку мыши. Мы указываем, что переменная coords
– это пустой массив и снова устанавливаем ее значение равной позиции нашего блока #element
.
Затем, нам нужно создать список из двух строчек, которыми будут coordTop:
и coordLeft:
, соответствующие позициям left
и top
, нашего блока. С помощью строки coords.push(item)
, мы заполним наш список массивом из координат. Затем задаем переменную order
как новый список, в котором ключ coords
будет соответствовать нашему массиву coords
. Теперь немного аякса.
$.post
– это обработчик запроса AJAX, который загружает удаленную страницу, с помощью метода HTTP POST
. Эта функция принимает следующие параметры: url, дата, ответ и тип данных для возврата. В этом примере, мы укажем файле updatecoords.php в качестве нашего URL, потому что, именно этому файлы мы хотим отправить наши данные. Затем, мы опишем тип данных, с помощью включения функции $.toJSON
, определенной в плагине JSON и назначим переменную order
, в качестве данных, которые должен вернуть .toJSON
.
Далее, мы создаем ответ, который проверяет возвращение успешного ответа от нашего PHP-файла. В случае получения успешного ответа, мы отображаем сообщение об успешном сохранении координат, используя метод .fadeIn()
и скорость 1000 миллисекунд, затем задаем таймер на 2000 миллисекунд, и снова медленно прячем это сообщение, с помощью метода .fadeOut()
. Вот так будет выглядеть наш JavaScript в целом виде:
<script type="text/javascript"> $(document).ready(function() { $("#element").draggable({ containment: '#glassbox', scroll: false }).mousemove(function(){ var coord = $(this).position(); $("p:last").text( "left: " + coord.left + ", top: " + coord.top ); }).mouseup(function(){ var coords=[]; var coord = $(this).position(); var item={ coordTop: coord.left, coordLeft: coord.top }; coords.push(item); var order = { coords: coords }; $.post('updatecoords.php', 'data='+$.toJSON(order), function(response){ if(response=="success") $("#respond").html('<div class="success">X and Y Coordinates Saved!</div>').hide().fadeIn(1000); setTimeout(function(){ $('#respond').fadeOut(1000); }, 2000); }); }); }); </script>
Поместите этот код ниже HTML, сразу после закрывающего тега body.
PHP
Хорошо, давайте сделаем что-нибудь с данными, которые приходят от нашего JQuery. Сначала нужно создать простую базу данных, для хранения наших координат, которые мы впоследствии будем использовать для определения позиции нашего элемента. Затем, нам понадобится файл config.php, в котором будут записаны параметры подключения к базе данных, а затем мы перейдем к updatecords.php.
SQL
Database: 'xycoords' CREATE TABLE IF NOT EXISTS `coords` ( `id` int(11) NOT NULL AUTO_INCREMENT, `x_pos` int(4) NOT NULL, `y_pos` int(4) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Config.php
<?php /*Database Settings*/ $db_host ="localhost"; //this will likely stay the same $db_name = "xycoords"; //name of the database we will be using $db_usr = "database_username"; //db username $db_pass = "database_password"; //db password //Connect to the database $link = mysqli_connect($db_host, $db_usr, $db_pass) or die("MySQL Error: " . mysqli_error()); //Select our database mysqli_select_db($link, $db_name) or die("MySQL Error: " . mysqli_error()); ?>
updatecoords.php
<?php if(!$_POST["data"]){ echo "Nothing Sent"; exit; } include ('config.php'); //decode JSON data received from AJAX POST request $data = json_decode($_POST["data"]); foreach($data->coords as $item) { //Extract X number for panel $coord_X = preg_replace('/[^\d\s]/', '', $item->coordTop); //Extract Y number for panel $coord_Y = preg_replace('/[^\d\s]/', '', $item->coordLeft); //escape our values - as good practice $x_coord = mysqli_real_escape_string($link, $coord_X); $y_coord = mysqli_real_escape_string($link, $coord_Y); //Setup our Query $sql = "UPDATE coords SET x_pos = '$x_coord', y_pos = '$y_coord'"; //Execute our Query mysqli_query($link, $sql) or die("Error updating Coords :".mysqli_error()); } //Return Success echo "success"; ?>
Здесь все довольно просто. Первое, что мы делаем – это проверяем, были ли переданы данные в файл. Если это произошло, мы включаем наш файл с настройками config.php и назначаем переменной $data
значение json_decode(passed post variable);
json_decode – это PHP-функция, представленная в PHP 5.2.0, которая позволяет декодировать строку JSON.
Поскольку наша переменная $data
содержит массив данных, нам нужно разобрать его на части, чтобы получить нужные значения. Для этого мы пройдемся по массиву $data->coords ()
(который был получен из переменной order
в JavaScript) и обработаем каждый элемент. В результате, из каждой пары ключ – значение будет создан объект списка, который мы в дальнейшем укажем и создадим переменную для его вывода. При этом мы будем использовать функцию preg_replace
, для исключения ненужных символов. Кроме того, мы подготовим наши значения для вставки в базу данных, путем экранирования кавычек, и апострофов, с помощью функции mysqli_real_escape_string
. Если все прошло хорошо, нам нужно будет вернуть успешный результат JavaScript.
В заключение
Теперь, когда у нас уже все готово, для того чтобы получить координаты элемента и передать их в PHP для записи, нам понадобится изменить нашу HTML-разметку для отображения позиции элемента. Для этого, мы удалим простую HTML-разметку и создадим ее с помощью PHP:
<div id="glassbox"> <?php //Create a query to fetch our values from the database $get_coords = mysqli_query($link, "SELECT * FROM coords"); //We then set variables from the * array that is fetched from the database while($row = mysqli_fetch_array($get_coords)) { $x = $row['x_pos']; $y = $row['y_pos']; //then echo our div element with CSS properties to set the left(x) and top(y) values of the element echo '<div id="element" style="left:'.$x.'px; top:'.$y.'px;"><img src="nettuts.jpg" alt="Nettuts+" />Move the Box<p></p></div>'; } ?> </div> <div id="respond"></div>
Здесь мы исполняем простой запрос к базе данных для выбора всех строк из таблицы coords. Затем мы вызываем цикл while, который определяет каждую выбранную нами строчку как $row
. Теперь, мы можем назначить переменные равными каждой, индивидуальной строке, полученной из базы данных, и выводим их в соответствующем месте.
Перевод статьи «Simple Draggable Element Persistence with jQuery», автор Dustin Blake
По-моему логичней было бы использовать куки для сохранения положения, а не базу данных. ;)
Можно, почему нет. Это один из примеров
Полезная статья. Черпнул немного неведанной мне информации, спасибо. Вот только с первым комментатором я не соглашусь. Тут уже кому как нравиться. Например мне удобней использоть базу чем куки…
да Базу наверное правильней будет использовать чтоб пользователь не расставлял все каждый раз так как ему нра. А если просто для прикола то можно и куки))))
Люблю jquery!
спасибо автору. Искал как раз именно это. А то достали со своими дурацкими куками.
Очень нужна помощь!
Подскажите как можно произвести тоже,но с несколькими картинками.
Если несколько картинок,то можно перемещать только последнюю,у меня получается только так.
У кого будет желание помочь вышлю код,может поможет разобраться!
Буду оочень рада!
Все зависит для каких целях пользуйтесь от этого и будет ваш выбор использовать куки или базу данных.