Drag & Drop на AJAX


Оглавление (нажмите, чтобы открыть):

Загрузка файла на сервер перетаскиванием Drag and Drop с использованием AJAX + PHP + JavaScript

Загрузка объекта(картинки, документа) на сервер без использования внешних библиотек, фреймворков и прочих обвесов. Голый, чистый PHP + JavaScript. Работает в большинстве браузеров.

В этом примере собраны все возможные способы передачи изображения на сервер:

  • Загрузка с локального диска
  • Загрузка из сети по переданному URL-у
  • Загрузка перетаскиванием

Упрощенный пример скрипта приема файла отправленного перетаксиванием:

Функция SaveFile — сохраняет файл с url или переданный через post. Описана в примере Передача изображения на сервер через форму.

Всего за 150 рублей (

2$) Вы можете приобрести представленный здесь пример загрузки файлов на сервер. Код также содержит все функции работы с изображениями. Код скрипта реализован на PHP, полностью открытый и не использует никаких дополнительных библиотек.

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

РегистрацияВойтиВойти через VKВойти через FBВойти через Google

Загрузка изображения на сервер с предварительным просмотром при помощи HTML5 Drag and Drop

Здравствуйте, уважаемые читатели XoZbloga! За последнее время я получил несколько предложений сделать урок, на тему загрузки изображений на сервер с предварительным просмотром. В этом уроке я попытаюсь разобрать данную тему, чтобы у Вас не осталось вопросов. Загрузка будет осуществляться с помощью HTML5 Drag and Drop (перетащил и бросил).

Для создания данного загрузчика будем использовать следующие:

  • HTML5 File API (FileReader);
  • Drag and Drop API;
  • PHP сценарий для загрузки на сервер.

Сразу напомню, что исходники работают только на сервере.

HTML разметка

Страница состоит из области для перетаскивания, а также области предварительного просмотра. Идея заключается в том, чтобы захватить изображения на рабочем столе (или в папке) и перетащить в область указанную пунктиром на странице, или если удобно нажать на кнопку «Выбрать файлы» по «старинке». После чего выбранные картинки отобразятся в области предварительного просмотра.

Для работы загрузчика нам понадобится библиотека jQuery, а также созданный нами скрипт и стили:

Как всегда начинаем с HTML разметки, здесь ничего сложного нет:

В самом верху страницы находится область для перетаскивания изображений, отмеченная пунктирной линией. А также кнопка выбора файлов, кому как удобнее. Событие ondragover работает пока перемещаемый файл над областью для перетаскивая.

Далее формируется область для предварительного просмотра изображений, а также кнопки для манипуляции и прогресс бар загрузки:

div id = «uploaded-holder» >
div id = «dropped-files» >

div id = «upload-button» >
center >
span > 0 Файлов / span >
a href = «#» class = «upload» >Загрузить / a >
a href = «#» class = «delete» >Удалить / a >

div id = «loading» >
div id = «loading-bar» >
div class = «loading-color» > / div >
/ div >
div id = «loading-content» > / div >
/ div >
/ center >
/ div >
/ div >
/ div >

После того как выбранные изображения будут загружены появляется список-оповещение о выполненных загрузках:

Вот так выглядит HTML разметка. Переходим к обработке событий загрузчика изображений.

Обработка событий

Начинается все с функции $(document).ready() . Каждая функция внутри нее будет выполняться как только DOM дерево документа будет готово:

Начнем с объявления глобальных переменных нашего обработчика:

// В dataTransfer помещаются изображения которые перетащили в область div
jQuery. event . props . push ( ‘dataTransfer’ ) ;

// Максимальное количество загружаемых изображений за одни раз
var maxFiles = 6 ;

// Оповещение по умолчанию
var errMessage = 0 ;

// Кнопка выбора файлов
var defaultUploadBtn = $ ( ‘#uploadbtn’ ) ;

// Массив для всех изображений
var dataArray = [ ] ;

// Область информер о загруженных изображениях — скрыта
$ ( ‘#uploaded-files’ ) . hide ( ) ;

Когда необходимые переменный объявлены, можно переходить к обработке происходящих событий на странице. А именно когда пользователь перетаскивает или выбирает изображение. Сначала разберем перетаскивание файла:

Метод .on присоединяет обработчик события drop — перетаскивания, к блоку div ( #drop-files ). Что касается функции loadInView(files) , о ней чуть ниже. Если количество выбранных файлов больше максимально установленного, появляется предупреждение и массив с изображениями очищается.

Теперь событие при выборе файлов с помощью кнопки:

// При нажатии на кнопку выбора файлов
defaultUploadBtn. on ( ‘change’ , function ( ) <
// Заполняем массив выбранными изображениями
var files = $ ( this ) [ 0 ] . files ;
// Проверяем на максимальное количество файлов
if ( files. length maxFiles ) <
// Передаем массив с файлами в функцию загрузки на предпросмотр
loadInView ( files ) ;
// Очищаем инпут файл путем сброса формы
// Или вот так $(«#uploadbtn»).replaceWith( $(«#uploadbtn»).val(»).clone( true ) );
$ ( ‘#frm’ ) . each ( function ( ) <
this . reset ( ) ;
> ) ;

> else <
alert ( ‘Вы не можете загружать больше ‘ + maxFiles + ‘ изображений!’ ) ;
files. length = 0 ;
>
> ) ;

Он практически идентичен вышеописанному, но событие change .

Теперь можно перейти к описанию функции loadInView(files) . Формирование области предварительного просмотра изображений:

// Функция загрузки изображений на предпросмотр
function loadInView ( files ) <
// Показываем обасть предпросмотра
$ ( ‘#uploaded-holder’ ) . show ( ) ;

// Для каждого файла
$. each ( files , function ( index , file ) <

// Несколько оповещений при попытке загрузить не изображение
if ( ! files [ index ] . type . match ( ‘image.*’ ) ) <

if ( errMessage == 0 ) <
$ ( ‘#drop-files p’ ) . html ( ‘Эй! только изображения!’ ) ;
++ errMessage
>
else if ( errMessage == 1 ) <
$ ( ‘#drop-files p’ ) . html ( ‘Стоп! Загружаются только изображения!’ ) ;
++ errMessage
>
else if ( errMessage == 2 ) <
$ ( ‘#drop-files p’ ) . html ( «Не умеешь читать? Только изображения!» ) ;
++ errMessage
>
else if ( errMessage == 3 ) <
$ ( ‘#drop-files p’ ) . html ( «Хорошо! Продолжай в том же духе» ) ;
errMessage = 0 ;
>

// Проверяем количество загружаемых элементов
if ( ( dataArray. length + files. length ) maxFiles ) <
// показываем область с кнопками
$ ( ‘#upload-button’ ) . css ( < 'display' : 'block' >) ;
>
else

// Создаем новый экземпляра FileReader
var fileReader = new FileReader ( ) ;
// Инициируем функцию FileReader
fileReader. onload = ( function ( file ) <

return function ( e ) <
// Помещаем URI изображения в массив
dataArray. push ( < name : file. name , value : this . result >) ;
addImage ( ( dataArray. length — 1 ) ) ;
> ;

> ) ( files [ index ] ) ;
// Производим чтение картинки по URI
fileReader. readAsDataURL ( file ) ;
>
> ) ;
return false ;
>

С каждым файлом в переданном массиве files выполняем следующие действия. Сначала проверяем изображение это или нет. Если нет то выводим предупреждение. Если полученный файл является изображением, то снова проверяем не является ли загружаемый файл лишним. Для это уже к существующему количеству изображений в массиве прибавляем этот файл и проверяем. Если все удачно, то в дело вступает HTML5 file API. С помощью интерфейса FileReader производим асинхронное чтение файла. Который в последствии помещается в массив dataArray .

Для отображения изображений которые уже помещены в массив, используем функцию addImage() с параметром текущий индекс изображения в массиве.

Ключевым здесь является метод .append , который позволяет вставить указанное содержимое в соответствующий элемент. В нашем случае вставляем эскиз загруженного изображения в div ( dropped-files ). Эскиз это блок div, где id равен img-индекс изображения в массиве и в качестве фона используется загруженное изображение. А также ссылка на удаление только этого изображения из массива, ее id равен drop-индекс изображения в массиве.

Раз уж дошли до удаления определенного изображения из массива, стоит разобрать соответствующую функцию:

C помощью селектора выбираем все элементы >drop . После чего получаем значение >split ) на две части от символа тире. Вторая (т.е. правая от тире) часть является индексом изображения в массиве. Далее методом splice очищаем элемент (изображение) в массиве по указанному индексу, и методом remove удаляем все элементы эскизы в div ( dropped-files ). После чего, вызываем функцию addImage(-1) с отрицательным числом, это сделано для того чтобы из массива в область эскизов были снова выведены все оставшиеся изображения.

Теперь функция restartFiles , удаляет сразу все изображения.

// Функция удаления всех изображений
function restartFiles ( ) <

// Установим бар загрузки в значение по умолчанию
$ ( ‘#loading-bar .loading-color’ ) . css ( < 'width' : '0%' >) ;
$ ( ‘#loading’ ) . css ( < 'display' : 'none' >) ;
$ ( ‘#loading-content’ ) . html ( ‘ ‘ ) ;

// Удаляем все изображения на странице и скрываем кнопки
$ ( ‘#upload-button’ ) . hide ( ) ;
$ ( ‘#dropped-files > .image’ ) . remove ( ) ;
$ ( ‘#uploaded-holder’ ) . hide ( ) ;

// Очищаем массив
dataArray. length = 0 ;

Здесь все просто длину массива dataArray приравниваем к 0, тем самым очищая его.

А вызывается она дважды один раз по нажатию на кнопку Удалить, а второй раз после загрузки изображений на сервер. Первый вариант:

И последнее событие это загрузка изображений на сервер.

// Загрузка изображений на сервер
$ ( ‘#upload-button .upload’ ) . click ( function ( ) <

// Показываем прогресс бар
$ ( «#loading» ) . show ( ) ;
// переменные для работы прогресс бара
var totalPercent = 100 / dataArray. length ;
var x = 0 ;

$ ( ‘#loading-content’ ) . html ( ‘Загружен ‘ + dataArray [ 0 ] . name ) ;
// Для каждого файла
$. each ( dataArray , function ( index , file ) <
// загружаем страницу и передаем значения, используя HTTP POST запрос
$. post ( ‘upload.php’ , dataArray [ index ] , function ( data ) <

var fileName = dataArray [ index ] . name ;
++ x ;

// Изменение бара загрузки
$ ( ‘#loading-bar .loading-color’ ) . css ( < 'width' : totalPercent * ( x ) + '%' >) ;
// Если загрузка закончилась
if ( totalPercent * ( x ) == 100 ) <
// Загрузка завершена
$ ( ‘#loading-content’ ) . html ( ‘Загрузка завершена!’ ) ;

// Вызываем функцию удаления всех изображений после задержки 1 секунда
setTimeout ( restartFiles , 1000 ) ;
// если еще продолжается загрузка
> else if ( totalPercent * ( x ) 100 ) <
// Какой файл загружается
$ ( ‘#loading-content’ ) . html ( ‘Загружается ‘ + fileName ) ;
>


// Формируем в виде списка все загруженные изображения
// data формируется в upload.php
var dataSplit = data. split ( ‘:’ ) ;
if ( dataSplit [ 1 ] == ‘загружен успешно’ ) <
$ ( ‘#uploaded-files’ ) . append ( ‘
+ dataSplit [ 0 ] + ‘»>’ + fileName + ‘ загружен успешно ‘ ) ;

> ) ;
> ) ;
// Показываем список загруженных файлов
$ ( ‘#uploaded-files’ ) . show ( ) ;
return false ;
> ) ;

По нажатию на кнопку Загрузить отображается прогресс бар, чтобы следить за ходом загрузки изображений. Данные по каждому изображению из массива dataArray передаются в PHP сценарий (файл upload.php), который загружается с помощью HTTP POST запроса ( $.post ). Это упрощенная версия HTTP (Ajax) запроса $.ajax . Данный файл после выполнения возвращает некоторые данные. C помощью уже известного метода split , разбиваем полученную строку на части. И если во второй части нам встречается строка «загружен успешно», значит формируем элемент списка загруженных файлов (имя файла в виде ссылки на него). После того как массив закончился и элементы списка готовы показываем весь список.

PHP сценарий загрузки

Последним шагом является загрузка изображения в папку на сервере. Приведенный PHP сценарий достаточно простой, при желании к нему можно «прикрутить» еще что-нибудь.

// Все загруженные файлы помещаются в эту папку
$uploaddir = ‘images/’ ;

// Вытаскиваем необходимые данные
$file = $_POST [ ‘value’ ] ;
$name = $_POST [ ‘name’ ] ;

// Получаем расширение файла
$getMime = explode ( ‘.’ , $name ) ;
$mime = end ( $getMime ) ;

// Выделим данные
$data = explode ( ‘,’ , $file ) ;

// Декодируем данные, закодированные алгоритмом MIME base64
$encodedData = str_replace ( ‘ ‘ , ‘+’ , $data [ 1 ] ) ;
$decodedData = base64_decode ( $encodedData ) ;

// Вы можете использовать данное имя файла, или создать произвольное имя.
// Мы будем создавать произвольное имя!
$randomName = substr_replace ( sha1 ( microtime ( true ) ) , » , 12 ) . ‘.’ . $mime ;

// Создаем изображение на сервере
if ( file_put_contents ( $uploaddir . $randomName , $decodedData ) ) <
echo $randomName . «:загружен успешно» ;
>
else <
// Показать сообщение об ошибке, если что-то пойдет не так.
echo «Что-то пошло не так. Убедитесь, что файл не поврежден!» ;
>
?>

Из массива POST извлекаются URI данные по изображению (имя и символьная строка идентифицирующая изображение). После чего получаем из имени изображения его расширении и формируем произвольное имя для создаваемого на сервере изображения. А символьную строка идентифицирующую изображение декодируем. Далее функцией file_put_contents (она последовательна успешным вызовам функций fopen() , fwrite() и fclose() ) создаем изображение на сервере в указанной папке.

Этот сценарий возвращает строку с новым именем изображения и пояснением «загружен успешно» при успешном выполнении. Как раз над этой строкой (переменная data ) мы и производили манипуляции в последнем событии.

Не стоит забывать, что папку куда помещаются изображения нужно создать вручную.

Стили CSS разбирать не будем, так как они особой роли не играют, но без них все равно нельзя �� Поэтому лучше скачать ИСХОДНИКИ и разобраться со стилями самостоятельно (файл style.css ).

На этом все. Загрузчик изображений на сервер с предпросмотром готов. Если у Вас остались какие-либо вопросы, оставляйте комментарии.

Дополнение

В этом дополнение напишу о том как можно реализовать хранение картинок в БД MySQL , точнее хранить будем только название каталога и имя файла. Это наверно самый распространенный метод, т.к. в любой момент можно изменить расположение картинок. Для хранения в БД следует создать отдельную таблицу, назовем ее images и добавим 4 поля:

И обеспечим следующую структуру таблицы, где id первичный ключ с автозаполнением:

Решил также добавить дату загрузки файла, может понадобится при сортировке и тд.

Таблица готова, подготовим сценарий занесения данных по картинкам. Разместим его в том же файле, что и загрузка на сервер upload.php . В начало файла добавим строку подключения к серверу и выбор БД:

C подключением думаю сложностей не должно возникнуть ��

Теперь осталось произвести запись данных в таблицу images :

А добавляем эту строку сразу после загрузки файла на сервер. после этих небольших манипуляций файл upload.php примет вот такой вид:

// Создаем подключение к серверу
$db = mysql_connect ( «servername» , «user» , «password» ) ;
// Выбираем БД
mysql_select_db ( «dbname» , $db ) ;

// Все загруженные файлы помещаются в эту папку
$uploaddir = ‘images/’ ;

// Вытаскиваем необходимые данные
$file = $_POST [ ‘value’ ] ;
$name = $_POST [ ‘name’ ] ;

// Получаем расширение файла
$getMime = explode ( ‘.’ , $name ) ;
$mime = end ( $getMime ) ;

// Выделим данные
$data = explode ( ‘,’ , $file ) ;

// Декодируем данные, закодированные алгоритмом MIME base64
$encodedData = str_replace ( ‘ ‘ , ‘+’ , $data [ 1 ] ) ;
$decodedData = base64_decode ( $encodedData ) ;

// Вы можете использовать данное имя файла, или создать произвольное имя.
// Мы будем создавать произвольное имя!
$randomName = substr_replace ( sha1 ( microtime ( true ) ) , » , 12 ) . ‘.’ . $mime ;

// Создаем изображение на сервере
if ( file_put_contents ( $uploaddir . $randomName , $decodedData ) ) <
// Записываем данные изображения в БД
mysql_query ( «INSERT INTO images (date,catalog,filename) VALUES (NOW(),’ $uploaddir ‘,’ $randomName ‘)» ) ;
echo $randomName . «:загружен успешно» ;
>
else <
// Показать сообщение об ошибке, если что-то пойдет не так.
echo «Что-то пошло не так. Убедитесь, что файл не поврежден!» ;
>

А теперь то, ради чего затевалась БД. Страница показа изображений, так сказать наипростейшая галерея. Создадим файлик gallery.php и расположим его там же где и upload.php . В начале файла также производим подключение к серверу и выбор БД, а в теле документа добавляем следующий код:

Информация по запросу не может быть извлечена, в таблице нет записей.

Чтобы изображения выводились в строку по три штуки, цикл вывода расположим в блоке div с шириной 900px , а изображениям присвоим относительное позиционирование и выравнивание по левому краю:

Примечания:
1. При загрузке файлов используется передача данных методом post , поэтому стоит обратить внимание на директиву php.ini — post_max_size , отвечающий за максимальный размер передаваемых данных.
2. Примечание от Фидана Газимова: при использовании патча безопасности — Suhosin, необходимо отключить проверку длинны get, post запросов в файле suhosin.ini (в Debian файл расположен /etc/php5/conf.d/suhosin.ini):

  • suhosin.get.max_value_length = off
  • suhosin.post.max_value_length = off
  • suhosin.request.max_value_length = off

Чтобы оставаться в курсе свежих статей и уроков подписывайтесь на страницу ВКонтакте или добавляйте в круги на Google+. Спасибо!

Чтобы оставаться в курсе свежих статей и уроков подписывайтесь на еженедельную почтовую рассылку или на новостную ленту RSS. Спасибо!

Drag and Drop File Uploading

Easily manage projects with monday.com

The following is a guest post by Osvaldas Valutis. Osvaldas is going to show us not only how drag and drop file uploading works, but goes over what nice UI and UX for it can be, browser support, and how to approach it from a progressive enhancement standpoint.

I work on an RSS reader app called Readerrr (editor’s note: link removed as site seems dead). I wanted to enrich the feed import experience by making allowing for drag and drop file upload alongside the traditional file input. Sometimes drag and drop is a more comfortable way to select a file, isn’t it?

Markup

This markup doesn’t have anything specifically to do with drag and drop. It’s just a normal, functional

We’ll hide those states until we need them:

A little explanation:

  • Regarding states: .box__uploading element will be visible during the Ajax process of file upload (and the others will still be hidden). Then .box__success or .box__error will be shown depending on what happens.
  • input[type=»file»] and label are the functional parts of the form. I wrote about styling these together in my post about customizing file inputs. In that post I also described the purpose of [data-multiple-caption] attribute. The input and label also serve as an alternative for selecting files in the standard way (or the only way if drag and drop isn’t supported).
  • .box__dragndrop will be shown if a browser supports drag and drop file upload functionality.

Feature detection

We can’t 100% rely on browsers supporting drag and drop. We should provide a fallback solution. And so: feature detection. Drag & drop file upload relies on a number of different JavaScript API’s, so we’ll need to check on all of them.

First, drag & drop events themselves. Modernizr is a library you can trust all about feature detection. This test is from there:

Next we need to check the FormData interface, which is for forming a programmatic object of the selected file(s) so they can be sent to the server via Ajax:

Last, we need the DataTransfer object. This one is a bit tricky because there is no bullet-proof way to detect the availability of the object before user’s first interaction with the drag & drop interface. Not all browsers expose the object.

Ideally we’d like to avoid UX like.

— «Drag and drop files here!»
[User drags and drops files]
— «Oops just kidding drag and drop isn’t supported.»

The trick here is to check the availability of FileReader API right when the document loads. The idea behind this is that browsers that support FileReader support DataTransfer too:

Combining the code above into self-invoking anonymous function.

. will enable us to make an effective feature support detection:

With this working feature detection, now we can let the users know they can drag & drop their files into our form (or not). We can style the form by adding a class to it in the case of support:

No problems at all if drag & drop file upload is not supported. Wsers will be able to upload files via good ol’ input[type=»file»] !

Note on browser support: Microsoft Edge has a bug which stops drag and drop from working. It sounds like they are aware of it and hope to fix it.

Drag ‘n’ Drop

Here we go, here’s the good stuff.

This part deals with adding and removing classes to the form on the different states like when the user is dragging a file over the form. Then, catching those files when they are dropped.

  • e.preventDefault() and e.stopPropagation() prevent any unwanted behaviors for the assigned events across browsers.
  • e.originalEvent.dataTransfer.files returns the list of files that were dropped. Soon you will see how to use the data for sending these files to the server.


Adding and removing .is-dragover when necessary enables us to visually indicate when it is safe for a user to drop the files:

Selecting Files In a Traditional Way

Sometimes dragging & dropping files is not very comfortable way for selecting files for upload. Especially when a user is in front of a small screen size computer. Therefore it would be nice to let users choose the method they prefer. The file input and label are here to allow this. Styling them both in the way I’ve described allows us to keep the UI consistant:

Мастер Йода рекомендует:  Введение в курс по PHP

Ajax Upload

There is no cross-browser way to upload dragged & dropped files without Ajax. Some browsers (IE and Firefox) do not allow setting the value of a file input, which then could be submitted to server in a usual way.

This won’t work:

Instead, we’ll use Ajax when the form is submitted:

The .is-uploading class does double duty: it prevents the form from being submitted repeatedly ( return false ) and helps to indicate to a user that the submission is in progress:

Ajax for modern browsers

If this was a form without a file upload, we wouldn’t need to have two different Ajax techniques. Unfortunately, file uploading via XMLHttpRequest on IE 9 and below is not supported.

To distinguish which Ajax method will work, we can use our existing isAdvancedUpload test, because the browsers which support the stuff I wrote before, also support file uploading via XMLHttpRequest. Here’s code that works on IE 10+:

  • FormData($form.get(0)) collects data from all the form inputs
  • The $.each() loop runs through the dragged & dropped files. ajaxData.append() adds them to the data stack which will be submitted via Ajax
  • data.success and data.error are a JSON format answer which will be returned from the server. Here’s what that would be like in PHP:

Ajax for legacy browsers

This is essentially for IE 9-. We do not need to collect the dragged & dropped files because in this case ( isAdvancedUpload = false ), the browser does not support drag & drop file upload and the form relies only on the input[type=»file»] .

Strangely enough, targeting the form on a dynamically inserted iframe does the trick:

Automatic Submission

If you have a simple form with only a drag & drop area or file input, it may be a user convenience to avoid requiring them to press the button. Instead, you can automatically submit the form on file drop/select by triggering the submit event:

If drag & drop area is visually well-designed (it’s obvious to the user what to do), you might consider hiding the submit button (less UI can be good). But be careful when hiding a control like that. The button should be visible and functional if for some reason JavaScript is not available (progressive enhancement!). Adding a .no-js class name to and removing it with JavaScript will do the trick:

Displaying the Selected Files

If you’re not going to do auto-submission there should be an indication to the user if they have selected files successfully:

When JavaScript Is Not Available

Progressive enhancement is about the idea that a user should be able to complete the principal tasks on a website no matter what. File uploading is no exception. If for some reason JavaScript is not available, the interface will look like this:

The page will refresh on form submission. Our JavaScript for indicating the result of submission is useless. That means we have to rely on server-side solution. Here’s how it looks and works in the demo page:

And some adjustments for the markup:

That’s it! This already-long article could have been even longer, but I think this will get you going with a responsible drag and drop file upload feature on your own projects.

Check out the demo for more (view source to see the no-jQuery-dependency JavaScript):

Форма обратной связи AJAX drag/drop с предпросмотром картинок

Добрый день.
Решил сюда написать.
Подскажите, плиз, как можно реализовать форму обратной связи, чтобы пользователь загружал картинки, можно в большом количестве, путем перетаскивания (drag/drop) и последующим предпросмотром. Также добавить стандартные поля для заполнения, радиокнопки и списки.
Похожие примеры — вот тут:
http://easy-code.ru/lesson/ajax-file-upload-form
http://xozblog.ru/2012/10/html5-uploader/

Пример того, что хотелось бы получить — http://fotoek.ru/
Заранее спасибо

03.11.2020, 13:14

Форма обратной связи для сайта html + ajax
Есть html сайт на нем уже встроены верстальщиком формы но так и не доделана возможность отправки на.

Не работает Drag’n Drop в Ajax окне
Есть Drag and drop написанный на js (работает отлично) и модальные окна с подгрузкой контента при.

Форма обратной связи
Всем привет! Вставил на сайт форму обратной связи, найденную на просторах интернета. Выглядит.

Форма обратной связи
Ребят, помогите пожалуйста. Никак не могу найти проблему. вот два сайта.

Форма обратной связи
Здравствуйте. Есть подобная форма обратной связи, она появляется в виде popup окна, я, с горем.

ez code

Просто о сложном.

Красивая AJAX форма для загрузки файлов

В этом уроке мы сделаем небольшую AJAX форму для загрузки файлов, которая позволит посетителям загружать файлы с помощью технологии drag/drop или при помощи обычного выбора файлов.

Мы будем использовать плагины jQuery File Upload и jQuery Knob для отображения прогресса загрузки.

Т.к. форма будет иметь возможность загружать файлы двумя способами, она будет работать даже если drag/drop не поддерживается.

Как обычно, начнем с HTML5 разметки:

В теге нашего документа, подключаем шрифты Google Webfonts, а перед закрытием тега — JavaScript библиотеки: jQuery, jQuery Knob и jQuery File Upload.

Главный элемент страницы — форма #upload. Внутри нее элемент #drop (принимает файлы с использованием drag&drop) и список, в котором будут отображаться загружаемые файлы. Разметка, которая будет генерироваться для загруженных файлов:

Элемент input будет спрятан с помощью CSS. Он нужен для инициализации плагина jQuery Knob, который будет рисовать шкалу процесса загрузки файла. Input имеет атрибуты data-*, которые используются для обновления шкалы. Позже, когда мы будет отслеживать прогресс загрузки, мы будем обновлять эти значения для перерисовки шкалы. span будет содержать зеленую галку или красный крест.

jQuery

У посетителя будет 2 способа загрузки файла:

  • Перетащить файл в окно браузера (в IE не работает).
  • Нажатием на кнопку browse. Будет имитировано нажатие на спрятанный input и показано системное окно выбора файлов. Обратите внимание, что input имеет параметр multiple параметр, что позволит выбирать много файлов за один раз.

Когда файлы будут выбраны, они помещаются в очередь для последующей автоматической загрузки:

В jQuery File Upload есть собственный интерфейс, но мы используем базовую версию плагина для создания собственного дизайна интерфейса. И чтобы наш интерфейс работал, мы передаем плагину несколько параметров / колбэков:

  • dropZone – этот параметр содержит jQuery селектор, который будет принимать перетаскиваемые файлы. Файлы, брошенные на него, будут добавлены в очередь загрузки.
  • add – функция вызывается при добавлении файла в очередь загрузки. Она будет генерировать разметку для файлов и вызвать метод data.submit() .
  • progress – Эта функция будет вызываться каждые 100ms (можно изменить). Второй аргумент содержит размер файла и количество загруженных байт. Это позволяет отслеживать прогресс и обновлять шкалу.
  • fail – функция вызывается при возникновении ошибки.

В комплект jQuery File Upload входит также и PHP скрипт для обработки файлов на сервере, но мы напишем свой. Процесс загрузки фалов будет происходить также как и при обычной загрузке, поэтому всю информацию о них мы можем получить из глобального массива $_FILES:

Как уже говорилось, файлы будут помещаться в очередь и загружаться друг за другом, поэтому обрабатывать на PHP очень легко.

Форум

Справочник

Поиск по форуму
Расширенный поиск
К странице.

Drag and drop

В свое время приходилось реализовывать кучу drag and drop’ов под самым разным соусом.

Эта статья представляет собой учебник-выжимку о том, как организовать drag’n’drop в javascript, начиная от основ и заканчивая готовым фреймворком.

Кроме того, почти все javascript-библиотеки реализуют drag and drop так, как написано (в статье дано несколько разных вариантов, не факт что ваш фреймворк использует лучший). Зная, что и как, вы сможете поправить и адаптировать существующую библиотеку под себя.

Drag’n’drop в свое время был замечательным открытием в области интерфейсов, которое позволило упростить большое количество операций.

Одно из самых очевидных применений drag’n’drop — переупорядочение данных. Это могут быть блоки, элементы списка, и вообще — любые DOM-элементы и их наборы.

Перенос мышкой может заменить целую последовательность кликов. И, самое главное, он упрощает внешний вид интерфейса: функции, реализуемые через drag’n’drop, в ином случае потребовали бы дополнительных полей, виджетов и т.п.

Основная логика drag and drop

Организовать перенос элементов по странице — довольно просто. Для этого нужно:

  1. При помощи события mouseDown отследить клик на переносимом элементе
  2. При каждом движении мыши в обработчике события mouseMove передвигать переносимый элемент по странице.
  3. При отпускании кнопки мыши, то есть наступлении события mouseUp — остановить перенос элемента и произвести все действия, связанные с окончанием drag and drop.


Координаты и кнопка мыши

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

Для этого будем использовать свойства which и pageX/pageY , полное описание и механизмы кросс-браузерной реализации которых есть в статье по свойствам объекта событие.

which кнопка мыши — 1: левая, 2: средняя, 3: правая pageX/pageY координаты курсора относительно верхнего-левого угла документа (с учетом прокрутки)

Кроссбраузерно ставить эти свойства на объект будет функция fixEvent (по статье свойства объекта событие):

В этом коде e.which проходит кросс-браузерную обработку, чтобы корректно отражать нажатую кнопку мыши. Вы можете подробно прочитать об этом в статье Свойства объекта событие.

На демке ниже обработчик mouseMove отслеживает координаты курсора мыши относительно левого-верхнего угла страницы, используя кроссбраузерную обертку fixEvent .

Координата X:
Координата Y:

Отслеживаем клик на объекте переноса

Чтобы начать перенос элемента, мы должны отловить нажатие кнопки мыши на объекте.

Для этого нам пригодится событие mousedown . Повесим обработчик на те элементы, которые хотим сделать доступными для переноса.

Пока этот обработчик будет запоминать объект в глобальной переменной dragObject

Остановить обработку события return false очень важно — иначе браузер может запустить свои механизмы перетаскивания элементов и все нам поломать.

В случае с отпусканием кнопки мыши все проще — объект мы уже знаем, так что можно повесить один обработчик onmouseup на document .

При нажатии на элемент он запоминается и выделяется.
Выделение(запоминание) действует на все время, когда нажата кнопка мыши, в том числе при перемещении курсора.

Остается добавить визуальное перемещение элемента — и drag and drop заработает.

Иногда бывает, что объектов, которые могут быть перенесены, много. Например, это ячейка таблицы или длинный список, или дерево статей с массой узлов.

Тогда время инициализации можно сильно сократить, если назначать обработчик onmousedown не на каждый объект переноса, а на контейнер. И уже в самом обработчике по event.target определять, где произошел клик.

Drag and drop контроллер

Перед дальнейшим развитием проведем реорганизацию кода.

Используем способ описания объекта без new (описан здесь как фабрика объектов), чтобы объявить объект dragMaster , предоставляющий необходимый функционал и отслеживающий перенос.

При таком способе задания объекта dragMaster получает публичные свойства (например, makeDraggable ), которые имеют доступ к приватным переменным и методам mouse* , dragObject , так как являются вложенными функциями.

  1. Не загрязняет глобальную область видимости переменными типа dragObject .
  2. Дает единый объект-синглтон dragMaster, управляющий переносом.
  3. Приватные переменные хорошо сжимаются javascript-компрессором, что убыстряет и уменьшает код.

Последний пункт очень важен, так как обработчики mouseMove , mouseUp вызываются при каждом передвижении мыши и поднятии кнопки соответственно. Если mouseMove будет работать медленно, то передвижение курсора станет рваным, заметно тормозным.

На это натыкались многие писатели drag’n’drop приложений. Мы же будем изначально закладывать производительность во все критические участки кода.

Визуальное перемещение элемента

Для того, чтобы перенести элемент, ему нужно поставить значение CSS-свойства position в absolute . Тогда он будет позиционироваться относительно верхнего-левого угла документа (точнее говоря, относительно ближайшего родителя, у которого position — relative/absolute, но у нас таких нет), и установка CSS-свойств left и top в координаты курсора мыши поместит левый-верхний угол элемента непосредственно под указатель.

Для перемещения элемента нам достаточно всего-лишь обновлять значения left/top при каждом движении мыши mousemove !

Начало движения: сохранение позиции курсора в элементе

Посетитель обычно кликает не в левый-верхний угол, а куда угодно на элементе.

Поэтому чтобы элемент не прилипал к курсору верхним-левым углом, к позиции элемента необходимо добавить смещение мыши на момент клика.

На рисунке ниже mouseX/mouseY — координаты курсора мыши, а positionX/positionY — координаты верхнего-левого угла элемента, которые легко получить из DOM:

Отсюда легко получаем смещение курсора мыши:

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

В коде появилась новая функция getPosition(элемент) — она получает абсолютные координаты верхнего-правого угла элемента. Функция это стандартная и много где используемая.

Кроме того, при начале переноса останавливается выделение и перенос текста браузером:

Если этого не сделать, то движение курсора мыши при нажатой кнопке будет не только перемещать элемент, но и, например, выделять текст под собой (стандартная функция выделения текста на странице).

Например, переносимый объект очень сложен, и его передвижение целиком тормозит браузер и выглядит громоздко/неэстетично.

Сам элемент при этом скрывается display/visibility=’none’ или просто остается на месте, в зависимости от логики интерфейса.

Переносимый клон инициализуется в начале переноса и уничтожается в конце.

Опускаем элемент

Когда иконка опущена, нам необходимо определить, куда.
В другое хранилище — переместить. В корзину — удалить, и т.п.

Существенная техническая проблема заключается в том, что событие mouseup сработает не на корзине, а на переносимом элементе, т.к. курсор мыши находится именно над ним.

Поэтому в событии будет информация об элементе непосредственно под курсором. На картинке выше event.target = сердечко , а корзина в объекте события event не присутствует.

Определить, что иконка опущена на корзину, можно, сравнив координаты корзины с коорданатами мыши на момент события.

В момент опускания на корзину выводится сообщение, перемещаемая иконка — в переменной dragObject , цель переноса (корзина, объект-акцептор) — в переменной currentDropTarget .

Перенеси меня в корзину

В коде контроллера: функции, тело которых заменено на «. «, остались без изменения с прошлого примера.

Основных изменений всего три.

Добавлен массив dropTargets и функция addDropTarget , которая добавляет в него элементы, на которые можно дропать.

Измененный обработчик mouseUp теперь проходит в цикле по возможным таким объектам и проверяет, не находится ли курсор внутри ограничивающего объект прямоугольника.

Если да, то демка всего лишь выводит сообщение. Реально приложение, конечно, может сделать более сложные действия.

Кроме того, установка и удаление обработчиков событий для document выделены в отдельные функции — просто в целях лучшей читаемости.

Индикация переноса над объектом

В удобном интерфейсе мы, скорее всего, захотим как-то показывать посетителю, над каким объектом он сейчас находится.

Единственно место, где это можно сделать — обработчик mouseMove . Сама проверка, над чем курсор сейчас находится, полностью аналогична mouseUp .

Однако, так как mouseMove выполняется при каждом передвижении мыши, его надо максимально оптимизировать.

Функция getPosition — довольно медленная: она работает с DOM, и ей надо пройти по всей цепочке offsetParent . Выполнять ее каждый раз при движении мыши для поиска текущего акцептора — все равно что нажать на большой-большой тормоз.

Стандартным выходом в такой ситуации является кеширование координат акцепторов, а точнее — их ограничивающих прямоугольников, так чтобы код mouseMove был максимально прост.

Пронеси меня над корзиной

Код уже стал довольно длинным, поэтому в листинге ниже повторяющиеся фрагменты заменены на троеточие «. «

Полностью рабочий вариант с кешем и т.п. — здесь:

Отделяем начало drag’n’drop от простого клика

Следуя общему принципу отделения мух от котлет — лучше отделить простой клик на объекте от начала drag and drop.

Еще одна причина — дорогая инициализация drag & drop: нужно прокешировать все возможные акцепторы. Совершенно не обязательно это делать на mousedown , если имеем простой клик.

Как отделить? Очень просто:

  1. При mousedown запомнить координаты и объект, но пока не начинать перенос
  2. Если произошло событие mouseup — это был всего лишь клик, сбросить координаты
  3. В mousemove проверить: если есть запомненные координаты и курсор отошел от них хотя бы на 2 пикселя — начать перенос


В коде этой демки стоит расстояние не 2, а 25 пикселей, в целях наглядности происходящего.

До перемещения курсора на 25 пикселей вверх или вниз перенос не начнется.

Отрыв от земли — после перемещения на 25 или больше пикселей

Оптимизация

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

Визуально это проявляется как задержка от клика на объекте до его фактического переноса — потому что долго, с 100% поеданием одного ядра CPU обрабатывается mousedown .

Речь тут идет о 100 акцепторах или больше — например, при переносе между длинными списками или деревьями. Хотя какие-то тормоза могут быть заметны и от 50.

Принципиальных решений здесь два.

Смена способа вычисления координат

document.elementFromPoint(x,y)

Этот малоизвестный метод работает во всех браузерах и возвращает элемент по координатам на странице.

Firefox/IE используют для этого clientX/Y , а Opera, Chrome и Safari — pageX/Y .

Возвращенный элемент является самым глубоко вложенным на точке с координатами (x,y) . Это может быть текстовый узел в том числе.
Следуя по цепочке родителей, легко найти нужного акцептора.

На время вызова elementFromPoint необходимо спрятать переносимый элемент, чтобы он не закрывал акцептора.

Псевдокод будет выглядеть так:

Вычисление по известным размерам

Если структура объекта переноса нам известна — возможно, кешировать каждый элемент ни к чему?

Например, мы переносим объект в список акцепторов:

И мы знаем, что каждый элемент имеет фиксированную высоту и отступы:

В таком случае, можно вычислить номер LI, разделив общую высоту контейнера на высоту акцептора.

Конечно, такая оптимизация возможна не всегда и зависит от конкретной задачи.

Убрать элемент из-под курсора

В ряде задач допустимо не сохранять переносимый элемент под курсором, а передвинуть его на несколько пикселей в сторону, то mouseUp и mouseMove будут срабатывать уже на акцепторе, который станет возможным получить из event.target .

Да, получится не так красиво, но это может быть единственным выходом.

Упростить объект переноса

Можно переносить не сам объект, а его «аватар», схематическое изображение.

Это может быть полезно:

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

Рефакторинг

Код dragMaster ‘а на текущий момент сочетает весь функционал по отслеживанию переноса, отображению и опусканию на акцептор.

Целесообразно его разделить на три компоненты: переносимые объекты, цели переноса (акцепторы) и менеджер, который следит, что куда переносится.

DragObject

Объект DragObject — обобщенный переносимый объект, который привязывается к DOM-элементу. Он представлен на следующем листинге.

Достаточно одного вызова new , т.к функция DragObject добавляет конструируемый объект к element в свойство element.dragObject :

onDragStart(offset) Вызывается при начале переноса. В текущей реализации отрывает объект «от земли» и запоминает текущую позицию в rememberPosition и сдвиг курсора мыши от левого-верхнего угла объекта в mouseOffset .

В другой реализации может показывать перенос как-то по-другому, например создавать «переносимый клон» объекта.
onDragMove(x, y) Вызывается при переносе объекта в координаты (x,y). Отображает перенос. onDragFail() Обрабатывает неудачный перенос. В текущей реализации возвращает объект на старые координаты.

Вообще говоря, можно делать это с анимацией, показывая как объект «перелетает» на старое место. onDragSuccess(dropTarget) Обрабатывает успешный перенос. В текущей реализации обработка успешного переноса целиком сосредоточена у принимающего объекта DropTaget , поэтому эта функция пустая. show/hide() Показать/спрятать переносимый объект — вспомогательные методы

DropTarget

DropTarget — обобщенный объект-акцептор, потенциальная цель переноса. Может быть большим контейнером или маленьким элементом — не важно.

Как показано дальше, поддерживаются вложенные DropTarget : объект будет положен туда, куда следует, вне зависимости от степени вложенности.

Методов у DropTarget поменьше, чем у DragObject . Еще бы, акцептору ведь не нужно анимировать собственный перенос.

canAccept(dragObject) При проносе объекта над DropTarget , dragMaster спросит у акцептора, может ли он принять dragObject . Если нет — dragMaster проигнорирует этот акцептор.

В текущей реализации всегда возвращает true , то есть положить можно. Вообще говоря, может проверять класс переносимого объекта:

accept(dragObject) Принимает переносимый объект. Объект может быть перемещен(в другой каталог) или уничтожен(корзина) — зависит от вашей логики обработки переноса.

В конкретном приложении стоит посмотреть особо, какую часть логики конца переноса стоит поместить DragObject#onDragSuccess , а какую — в DropTarget#accept . Как правило, основную логику переноса удобно сосредоточить у DropTarget . onLeave/onEnter Анимация возможности положить объект на акцептор. Как правило, акцептор при этом подсвечивается. Эти методы будут вызваны только если акцептор может принять ( canAccept ) переносимый объект.

dragMaster

Ну и, наконец, похудевший и лишенный большинства обязанностей dragMaster .

mouseDown(e) Метод не изменился. Он запоминает позицию, на которой произошло нажатие кнопки мыши mouseDownAt и добавляет остальные обработчики слежения за переносом addDocumentEventHandlers() . mouseMove(e) Этот обработчик присоединяется к document в момент mouseDown .

  1. Если в момент его срабатывания есть запомненное нажатие и курсор отошел больше чем на 5 пикселей — значит начался перенос. DragObject’ у это сообщается вызовом onDragStart с передачей текущего сдвига курсора относительно левого-верхнего угла mouseOffset .
  2. Объект информируется о текущих координатах переноса.
  3. Вычисляем текущий акцептор при помощи модифицированного метода getCurrentTarget (см. выше в разделе «Оптимизация»).
  4. Обработать нового акцептора и уход со старого акцептора.
  5. Вернуть false для блокирования действий браузера и всплывания события mouseMove
Мастер Йода рекомендует:  Upload File (Загрузка файла на сервер средствами Perl)

mouseUp() Этот обработчик завершает (возможный) перенос. Обратите внимание — само событие в данном случае не нужно. Весь процесс переноса отслеживается событием mouseMove .

  1. Если объект переноса не установлен, значит перед этим было простое нажатие mouseDown , элемент не отнесли на 5 пикселей в сторону — это не drag’n’drop.
  2. При наличии акцептора — перенос успешно завершается, если акцептора нет — отменяется.
  3. В любом случае в конце все обработчики с документа снимаются

Функция определения позиции элемента getPosition заменена на более точный вариант getOffset , описанный в статье про определение координат.

Итоговый Drag’n’Drop фреймворк

Скачать пакет из итогового фреймворка и демок можно здесь.

В комплекте — пара демок. На этой странице обе подключены в iframe’ах.

Обычный перенос

Вложенные акцепторы

В этой демке акцепторами являются два вложенных DIV’а.

Некоторые дополнительные рецепты

Перемещения акцепторов в процессе переноса

В процессе переноса акцепторы объекты могут сдвигаться, освобождая место.

Если вы используете кеш координат акцепторов, то при этом производится соответствующее обновление кеша, но вместо полного перевычисления обновляются только координаты сдвинувшихся объектов.

Например, при раздвижении списка вниз — увеличиваются Y-координаты всех сдвинувшихся LI.
При этом для удобного обновления кеш делается не массивом, а объектом с доступом по ID элемента, так чтобы можно было легко обновить именно нужные координаты.

Drag and drop «между».

Иногда, например, при смене позиции элемента в списке, объект переносится не на акцептор, а между акцепторами. Как правило, «между» — имеется в виду по высоте.

Для этого логику определения currentDropTarget нужно поменять. Возможно два варианта:

Допустим перенос как между, так и над В этом случае акцептор делится на 3 части по высоте clientHeight : 25% — 50% — 25%, и определяется попадание координаты события на нужную часть. Перенос только между Акцептор делится на две части: 50% — 50%

Кроме того, в дополнение к текущему акцептору currentDropTarget добавляется флаг, обозначающий, куда относительно акцептора происходит перенос.


Индикацию «переноса между» удобнее всего делать либо раздвижением элементов, либо показом полосы-индикатора border-top/border-bottom , как показано на рисунке ниже:

Анимация отмены переноса

Обычно при переносе объекта куда-либо посетитель может просто отпустить его в любом месте.

При этом drag and drop фреймворк анимирует отмену переноса. Один из частых вариантов — скольжение объекта обратно к исходному месту, откуда его взяли.
Конечно, для этого исходное место необходимо запомнить.

Если перетаскивается аватарка(клон), то можно его и просто уничтожить.

Проверка прав

Совершенно не факт, что любой объект можно перенести на любой аксептор.
Как правило, все с точностью наоборот.

Акцептор может быть недоступен по двум причинам:

  • либо это несовпадение типов, для этого drag and drop должен предусматривать различные типы объектов/акцепторов и проверку их соответствия
  • либо у посетителя недостаточно для этого прав, в рамках наложенных CMS ограничений

При переносе над недоступным акцептором — getCurrentTarget просто возвращает null.

Иногда проверку прав и результата переноса необходимо делать на сервере. Как правило, такую проверку выполняют только при mouseUp , чтобы не нагружать сервер излишними запросами во время mouseMove .

Здесь используется два подхода

Синхронный XmlHttpRequest Запрос отправляется синхронно, чтобы не нарушать общий поток выполнения. Все хорошо, вот только браузер видимо подвисает при отпускании кнопки мыши. Да и другие недостатки у синхронного запроса есть. Отложенная отмена переноса Более продвинутый и удобный вариант. Основан на «оптимистичном» сценарии, по которому перенос, как правило, проходит успешно.

  1. Посетитель кладет объект туда, куда он хочет.
  2. Фреймворк перемещает объект, и затем «в фоне» делает асинхронный запрос к серверу. На запрос вешается callback , содержащий информацию, откуда был перенесен объект.
  3. Сервер обрабатывает перенос и возвращает ответ, все ли в порядке.
  4. Если нет — callback выводит ошибку и объект возвращается туда, откуда был перенесен.

Резюме

Вы узнали основные принципы и особенности реализации drag and drop в яваскрипт.

Рассмотрели ряд оптимизаций и различные организации переноса на уровне UI.

Все современные javascript-библиотеки используют описанную схему и какие-то (не все) из оптимизаций.

Пакет из итогового фреймворка и демок доступен здесь.

А просто использование jQuery.ui.sortable не нравится?
Или статья именно в обучающих цельях? Тогда, конечно, классно — полезно будет.

Использование jQuery.ui.sortable, а также Dojo draggable, а также других существующих библиотек есть гуд. Другое дело, что они не всегда соответствуют решаемой задаче, занимают больше места, да и вообще полезно понимать, что происходит.

Эх, много бы время мне сэкономила эта статья выйдя на пол года раньше=) Облазил я тогда всё но кроме простых примеров ни чего не нашёл. Раньше я использовал script.aculo и прототип, для проекта где было много перетаскиваемых объектов, что сказать мне не хватило ее функциональности. Не было в ней событий которые вызывались в тот момент когда перетаскиваемый объект начинал заходить и уходить в область drop объекта=) пришлось добавит только предварительно поняв как там всё это устроенно. Вот живой пример. Для простых целей он конечно же подходят.
События которые отображающие весь процесс это:
onStartDrag()
onStopDrag()
onDrag()

onStartHover()
onHover()
onStopHover()
onDrop()
И если их сделать тогда вам больше не чего не придётся дописывать

Все это легко делается..
Можно даже добавить это в нужную библиотеку, если понимать, что и как там работает.

А статья как раз это и описывает.

UPDATED: добавил в статью раздел про рефакторинг с событиями.

Да без условно это хорошая и нужная статья.

Пустую false-функцию для document.ondragstart и document.body.onselectstart тоже можно сделать одну, а не создавать каждый раз при mouseup’e:

Третий день изучаю js, для того что бы заменить формы html на «Drag and Drop» , дабы изменять переменные не перегружая страницу.

Какой метод лучше использовать для этой цели (для FF2) ваш первый или http://elouai.com/javascript-drag-and-drop.php ?
(«Демо улучшенного метода» в FF2 под Linux не работает).

Если я «перетащил» div с определенным ID в определенную область — как мне лучше запустить произвольную функцию, передав ей этот ID ?

В Firefox 2 вполне может не работать. Используйте Firefox 3, а то Firefox 4 пропустите

UPDATE: используйте Firefox 3.5

Статья очень крутая.

Больше всего в это статье мне нравится не сама описываемая в ней тема, хотя и она интересна сама по себе, а то, как автор оперирует ОО подходом применительно к JS. Использует много интересных приемов и главное не отдельно, а непосредственно решая задачу.

Т.е. если он использует обработчик событий, то это не статья об обработчиках, а статья где показано практическое его применение.

И вообще, автор талантлив. Я считаю, что это идеальный обучающий материал. Хотя некоторые моменты не совсем раскрыты, но это вполне верно, так как статья не о них.
Большое спасибо за качественный материал.

отмечаю что статья не доведена до логического конца в зугрузку необходимо добавить не только JS, но и маленький html где используется данный скирпт. тогда вопросов
«Может кто подскажет как использовать. Ну есть у меня этот котроллер.и есть объект, допустим div
возникать не будет. к сожаленю этим страдает не только эта статья здесь.

Пример, конечно, не помешал бы, но.

У меня есть мнение, что изучать программирование и его основы нужно не с этой статьи. Поэтому такие моменты как банальное не знание HTML или не понимание общих принципов программирования как такого (не говоря об ООП), это, в конечном счете, не проблема автора. Цель данной статьи объяснить и принципы, а не дать рабочий пример. Если нужен механизм, то нужно читать не статьи, а документацию библиотек, а лучше базовый курс.

А от вопросов: — «Где в javascript C++?» и — «Как добавить на страницу этот форум?», никуда не деться.

Расширил статью, добавил итоговый вариант после рефакторинга и демо.
Сделал общий скачиваемый архив.

Кода, как всегда, мало. Все чистенько, понятненько, юзабельно.

Отличная статья. Все хорошо расписано и понятно. Для определенных сайтов драг-энд-дроп сильно повысит интерактивность управления (к примеру кидать товары в магазине в тележку).

Всегда привлекала тема drag and drop — в javascript автору благодарность

Спасибо огромное! Теперь я знаю, как решить свою задачу!

Автор а почему драг и дропятся? шутка
Отличная статья огромное спасибо

Спасибо, все доступно и понятно даже для человека посредственно знающего javascript.

Статья просто отличная — на 5+.
Хотя в таких случаях стараюсь использовать готовое — тот же jQuery.

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

Да, реакция на скролл и правда не разобрана. Возможно, со временем допишу.

Автопрокрутку делают отслеживанием координат мыши — если у края окна/контейнера то вызывается прокрутка.

По самому событию скролла, чтобы все обработать ок — нужно определить, на сколько прокрутили — и апдейтнуть позицию..

Сейчас тоже мучаюсь с автоскроллом. У меня сцена больше, чем страница. Было бы хорошо это описать.

Все это очень замечательно, но для действительно полноценного drag’n’drop’а следует рассмотреть еще много-много интересного. Итак:

1. Вы совершенно не учитываете возможность наличия других обработчиков mousemove/mouseup, которые могут сделать stopPropagation/cancelBubble, и Ваш drag’n’drop никогда не кончится. Во избежание этой ситуации обработчики mousemove/mouseup следует навешивать С КАПЧУРИНГОМ на document: document.addEventListener(‘mousemove’, callback, true). В IE для тех же целей необходимо установить setCapture на таскаемый элемент.

2. Вы не учитываете возможность прерывания таскания, например, по alt+tab, одновременному нажатию нескольких кнопок мыши или выходу курсора за пределы документа.

3. Есть очень скользкий момент с тем, что после mouseup приходит событие click, которое, вообще говоря, логически вовсе не click — если по клику выполняется какое-то другое действие, то оно после драггинга очевидно выполняться не должно. Поэтому надо в определенных ситуациях слушать приходящий следом click и отменять его.

Это только верхушка айсберга на самом деле. Там еще море всевозможных тонкостей, особенно с разными странными браузерами типа Оперы 9.2 и Сафари под Мак.

И кстати, если говорить про jQuery, его стандартная таскалка про все это тоже ничего не знает.

И кстати, в FF2 Ваши примеры не работают.

В FF2 мои примеры не работают и не будут. Как и в Opera 7. Динозаврам место в музеях.

P.S. Легко можно сделать, чтоб работали, 2 строки кода поправить. Но может не надо а?

FF2 использует примерно 2% пользователей — не так уж и мало. Больше чем Сафари под Мак, например. То же касается Оперы 9.27. А эти два браузера не отслеживают выход мыши за пределы документа (т.е. в строку меню браузера, например).

Выход мыши за пределы документа особенно резкий — вообще нельзя отследить, как и отпускание кнопки там. Можно только

1) Попробовать предусмотреть такой нестандарт и не глюкануть сильно
2) Иметь в виду, что пользователь, который так делает, обычно морально готов к глюкам.

В приципе FF3 событие onmouseup ловит за пределами окна (если конечно мышь туда перемещается в нажатом состоянии. Ну и может дело в том что в своей реализации D&D я вешаю обработчики через addEventListener/attachEvent, чтобы не мешать другим).

А вот у IE с этим проблема (использую 6ую версию). Событие onmouseup ловится за пределами окна только в том случае если нет обработчиков в стиле document.body.onselectstart = funtion(e) . Т.е. если работает выделение и мы его не трогаем.


Поэтому для того чтобы, D&D корректно прекращался, а не продолжался после того как кнопка была отпущена «за пределами», необходимо ловить document.[body.]onmouseover и прекращать его если не нажать левая кнопка мыши. Кстати у вас в примерах такой эффект присутствует. D&D продолжается если отжать мышь за пределами ограничивающего контейнера.

В FF2 вполне можно отследить выход курсора за пределы окна, через relatedTarget. В IE надо делать setCapture на нужный элемент и слушать событие onlosecapture.

1) Попробовать предусмотреть такой нестандарт и не глюкануть сильно

Это довольно просто сделать, записываем состояние объекта и если up небыло, а down уже было, то сбрасываем перенос.

в статье ещё не рассмотрен случай, когда элемент перетаскивается за его часть (например окно за заголовок) и не написано про обработку вытаскивания элемента за пределы окна

Да этого очень не хватает в статье.

Хорошая статья. Наткнулся на нее когда писал свой drag’n’drop, уже почти все написал, осталось только определить над каким элементом находится курсор при onMouseUp и ответ как это сделать был найден именно тут.
На счет выхода курсора за пределы окна, контроля последующего клика, реакции на alt+tab.. Это уже похоже на попытку контроля хаоса. Ну в крайнем случае можно сделать отмену перетаскивания, если курсор мыши долго не меняет свои координаты. Впрочем даже это кажется мне излишним.

Автору большое спасибо за проделанный труд. Читал с удовольствием

Спасибо за статью.

Чтобы я мог полностью использовать все преимущества этого скрипта — подскажите, как перетаскивать не картинку, а ее копию?
Хочу на базе вашей реализации сделать драг н дроп товаров в корзину.
Надо:
1. Взять мышей картинку.
2. Перетянуть ее на корзину.
При этом изображение товара — должно статично, а перетягиваться копия изображения

Нужно модифицировать код отображения перетаскивания и код завершения drag and drop.

Об этом неоднократно упоминается в статье.

Если не трудно — подскажите.
У меня есть опыт программирования.
Но в некоторых вещах я несилен.

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

Поскольку в скрипте отсчет позиции идет от x: 0, y: 0 для body, то такой элемент, при перетаскивании, будет появляться не в месте, где мы его «схватили», а с соответствующим смещением (между «нулями» body и родительского позиционированного элемента). Поскольку «правильное» определение элемента с позиционированием может стоить ресурсов, лучше при перетаскивании делать клон элемента, подсоединяя его к контейнеру body, таким образом обходя вышеуказанную проблему и возможную проблему с вложенностью.

Можно брать offsetХ и У контейнера и прибавлять к координатам.

Уважаемый Илья Кантор! Огромное спасибо Вам за этот ресурс, по-моему, это лучшее, что есть по javascript. Все информация излагается доступно, с логикой развития, полно, с наглядными работающими красивыми примерами. Потрясающе!

Может, сделать отдельный тип комментариев «спасибо» ? Конечно, я рад, что мой труд кому-то пригодился, но такие комментарии не добавляют полезности статье..

Спасибо автору, фреймворк очень компактный.
Правда процессор грузит в среднем также как jQuery.ui Drag&Drop. Использовать не так удобно как jQuery.ui
Для повышения удобства и универсальности достаточно вынести функцию обработки дропа из фреймворка на пользовательскую страницу, как это сделано в jQuery.ui

Как это сделать догадается далеко не каждый.

Статья совсем не ставит целью заменить jquery ui, dojo dijit и прочие фреймворки. Конечно, вы можете адаптировать код под свои нужды или адаптировать поправить тот же jquery ui, используя информацию из статьи.

Здраствуйте, очень много нового для меня в этой статье! Дочитал пока до параграфа «Опускаем элемент» а уже возникло несколько вопросов:

1. не понятен синтаксис

e.which = e.button & 1 ? 1 : ( e.button & 2 ? 3 : ( e.button & 4 ? 2 : 0 ) )

это же одно и то же что и выражение ниже?

if (e.button==true & 1)
<
e.which = 1
>
else
<
( e.button & 2 ? 3 : ( e.button & 4 ? 2 : 0 ) )
>

как расшифровать ( e.button & 2 ? 3 : ( e.button & 4 ? 2 : 0 ) ) .

2. Это ошибка чи нет? Подпараграф «Начало движения: сохранение позиции курсора в элементе»

document.onmousemove = function(e) <
e = fixEvent(e)
.
element.style.left = e.pageX + mouseOffset.x + ‘px’
element.style.top = e.pageY + mouseOffset.y + ‘px’
.
>

Должно быть наверное ж

document.onmousemove = function(e) <
e = fixEvent(e)
.
element.style.left = e.pageX — mouseOffset.x + ‘px’
element.style.top = e.pageY — mouseOffset.y + ‘px’
.
>

3. Подпараграф «Демо»

для чего выделенные жирным скобки?

4. Интересна функция getPosition, понятно что все работает и этого должно быть мне достаточно:), но если не сложно можете объяснить некоторые моменты:

while (e.offsetParent) <
left += e.offsetLeft
top += e.offsetTop
e = e.offsetParent
>

Допустим есть такая конструкция

В файрбаге я смотрю по dom модели, что свойство offsetParent для дива dragElem = div.test

while (e.offsetParent) <
left += e.offsetLeft
top += e.offsetTop
e = e.offsetParent
alert(e.offsetParent)
>

и он мне выводит первый раз [object HTMLBodyElement], а второй раз null

что это за прикол? кроссбраузерные глюки?

1. Добавил комментарий об этом в статью. & — это логическое И.
2. Да, опечатка, поправил.
3. Таким образом мы объявляем и тут же создаем объект-синглтон.
4. Что непонятного? IE выводит что-то другое? Вы берете элемент, у которого нет offsetParent (родительского по offset элемента). Естественно, выходит null.

Насчет поправки к скролингу, можно примерно так:

С виду — ошибочка: (e) ? e.pageY : event.clientY — переменная e всегда задана после fixEvent.

Да, упистил там, я имел в виду, что те две строчки эквивалентны fixEvent, такое может быть? Точнее по части контроля за скролами.

Что будет если на эту страницу поместить iframe — как будут себя вести перетаскиваемые элементы при перемещении над ним?

Vladi, дата: 19 октября, 2009 — 15:27

Не указан один важный момент. Для Драг&Дропа необходимо заставлять браузер перерисовывать страницу при mouseover. Это в библиотеке просисходит, но для других целей. Заставить перерисовать страницу можно простым обращением к свойству DOM-элемента, которое заставит браузер что-то вычислить:

Не все свойства DOM-элемента подходят для этого, например style.top, т.к. это по-сути всего лишь получение уже установленного значения. В сложный интерфейсах этот момент может сыграть чуть ли не самую важную роль.

Да уж, перетаскивание клона картинки — полезная штука,
а можно ли выложить полный код? А то изменения применил,
но не работает .
то картинку вообще сдвинуть нельзя, то днд отключается,
и картинка тянется браузером, а не скриптом.

Здравствуйте!
Спасибо полезно, применяю.
Есть вопрос:
У меня перетаскиваемый объект содержит html код (текст картинки и т.д.) он в контейнере table td. (таблицей нарисовано обрамление содержания)
В js новичОк, не могу сделать так чтобы таскать только за область границы вокруг.
При этом по mousedown на контенте контейнера не таскать но выделять текст.
вот пример
http://webpokaz.ru/media/test/testgallery.html
И еще одно, после нескольких внесенных исправлений повесил ИЕ.
В этой версии, при том что локально все работает, выложил в нет и ИЕ повис.
Рассмотрите пожалуйста мой пример. Очень надеюсь на вашу помощь

Я только что столкнулся с данной проблемой — мне необходимо было иметь возможность перетаскивать всплывающее окошко:

Так вот, для того, чтобы беспроблемно таскать это всплывающее окошко, я просто подставил в вызове не его само, а его хэдер, т.е. в данном случае dTitle, а в самом скрипте сделал так:

В моем случае помогло, надеюсь, поможет и вам

я тут задумался, интересно, как можно сделать так, задать акцептеру например класс объектов, которые он может принимать

типа того, т.е. акцептер object будет принимать в себя только объекты имеющие класс items

точно так же, объектом которым мы говорим драгиться, что им можно располагаться тока в акцептеры

Всего лишь проверять перед тем или иным действием свойство className объекта.

Вот эщто действительно хорошая статья по переносу объектов.! респект!

Здесь возвращается позиция элемента относительно документа

а тут элементу назначаются координаты относительно родительского элемента

и если задать родительскому элементу position, перетаскиваемый прыгает
в исходном файле demo.html я приписал позицию для дива

так и чешутся руки скрипты украсть!

Полный JS решение проблемы с input ами

Статья действительно супер, но добавлю пару замечаний.
Во-первых, по поводу pageX/Y и clientX/Y: Chrome и Opera 10.5 уже тоже использует clientX/Y, по крайней мере с ним всё работает корректно. Для Opera a используя preventDefault.

А как отменить срабатывание onclick? C атрибутом href проблем нет, а вот onclick никак не могу побороть.

Использую эти скрипты для DnD. Очень сильно грузять процессор. Под FF и Chrome еще как-то шевелятся(95%), а под IE вначале перетаскивания проц загружается на 100% и по этой причине объект не визуализируется, ему просто некогда. Это происходит даже если после начала движения просто остановить мышку но не отпускать левую клавишу. Постоянно срабатывает событие mousemove, хотя движения мышкой нет. В чем может быть причина? Если не победю придется на другой фреймоворк переходить, а это месяц отладки.

Очень странно что событие mousemove срабатывает без движения мышкой. Не бывает такого..

Мне кажется, что к проверке прав второго типа (асинхронный запрос) надо добавить предварительную проверку прав на всех объектах, которые могут быть перетаскиваемыми, на этапе формирования страницы (PHP).

Например, если у нас есть сотня объектов трех типов, мы можем выделить эти типы. И у нас есть авторизованный (или неавторизованный, гость) пользователь, у которого есть права. Для каждого типа объектов проверяются права на перенос — да, нет. Всего лишь булевая переменная, которая добавляется в свое свойство объекту. Таким образом мы отсекаем бОльшую часть «отбракованных» переносов еще до их совершения. Кстати абсолютное большинство «отбракованных» переносов будет говорить о попытках изменить что то в коде страницы и получить доступ к запрещенным элементам: если проект — онлайн-игра, такому пользователю можно выносить предупреждение, и знать, что от него можно ждать попыток эксплоитов и багоюзерства =)

Мастер Йода рекомендует:  Восемь бесплатных альтернатив Dropbox


сдается мне что если dran-n-drop элемент будет находится в блоке с position:relative, то не правильное поведение будет при перемещениии

Safari не дропает в примерах итогового фреймворка.

Спасибо за статью!
Но вот глюк.
Взял за основу пример с 2-мя вложенными дивами.
если на странице с примером появляется полоса прокрутки вниз
То в Opera прокрутив чуть чуть и попробовав перенести, меняется позиция droptarget, а именно становится выше реального((( Подскажите?

Вопрос:
А как можно сделать сразу все объекты передвигаемыми? Т.е. сделать это до того как их в первый раз передвинут?

есть одна проблема с получением координат мыши отномительно документа: при нахождении мыши над обьектом со свойством position:fixed; в интернет эксплорере значение координат остается не определенным.. как можно это исправить?

а ни кто не встречал библиотеки драг анд дроб сразу с записью в кукис?

А с записью в кукис таких библиотек ни кто не встречал?

Мне вот интересно насчет дропа между элементами. Чтобы делить акцепторы на 2 части, для определения выше или ниже будет дропаться элемент, нужно знать его высоту, которую можно снять c помощью getComputedStyle, но подобный метод для IE (currentStyle) вернет «auto» если высота нигде не задана, и как же тогда быть, если все элементы «списка» (подразумевается некий набор блочных элементов) разной высоты, которая нигде не задана, а зависит от количества контента блока.

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

Мне самому хотелось бы кой-чего замутить (не без драг-н-дропа), но как прикину, сколько на это времени уйдёт, чтобы хотя бы в паре основных браузеров работало без нареканий, так руки и опускаются. Тут уже перечислили выход мышки за пределы окна и т.д. с комментариями «если пользователь это делает, то он морально готов к глюкам».

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

Если же вы не можете обеспечить безглючную работу задуманного — не беритесь.

«Надо там ещё додумать, надо там ещё доделать, ещё пользователь может вот так, ну это всё равно, а может ещё и так, ну и плевать, пусть развалится.»

«Вот вечно у нас так всё, на авось, авось не всплывёт, небось и так сойдёт, везде халтура. А я хочу, чтобы наша липовая печать была лучшей печатью во всей прокуратуре!»

Если бы автомат калашникова клинило в тот момент, когда пользователь «должен быть морально готов к глюкам» — был бы он брендом номер один в своей области?

Уважаемый Илья. Очень прошу уточнить как вместо alert произвести асинхронный запрос. И самое главное как после того как, dragObject будет отпушен на акцепторе
запретить ему Drag and drop.

А как быть с глюком в ie.
Последовательность:
хватаем сердечко из примера
http://javascript.ru/ui/draganddrop#demo-4

ведем его до верхней границе окна
неотпуская мыши уводим ее за границу окна и там отжимаем клавишу мыши. Сердечко при этом осталось около границы. Далее возвращаем курсор в область окна и сердечко продолжает двигаться за курсосром.

Ребят, сколько ни ковыряю, что-то не могу разобрать. Можно ли устанавливать значения ClientX/ClientY (pageX/pageY), а не просто получать их? Подскажите, для примера, функцию, автоматизирующую некоторое перетаскивание:
1. Устанавливаются заданные координаты Х,Y (150, 250)
2. Происходит нажатие левой кнопки мыши
3. Устанавливаются другие координаты (200,300)
4. Происходит отпускание кнопки
Это бы всё расставило на свои места, заранее благодарю.

цель драг-дропа можно определять onouseover целей я думаю

статейка понравилась, переделал данный фреймворк под touch-событийную модель, проверил на ipad-е и андроиде, без тормозов пашет, пальцем перемещаются элементы

Подскажите, как вы переделали событие mousemove?
И если не сложно, можно посмотреть код?

Заметил баг — если быстро перемещать элемент и отпустить кнопку мыши не над элементом, который сейчас перемещается, то dragObject у элемента становится равным null. Не могу понять из-за чего это может быть, подскажите плиз куда копать.

Разобрался, то я затупил)

А как закрепить место за объектом после перемещения?
Чтоб при последующей загрузке страницы объекты были на тех позициях, куда их переместил пользователь?

backgr.png — прозрачный фон, типа щелкаешь на див и на весь экран растягивается другой див с прозрачным фоном на котором работают онмоусмув применительно к первому элементу, двигаешь в большом а двигается маленький Х)
Одни минусы, но круто ведь )

ОГРОМНОЕ спасибо , статья тяжелая после ее прочтение 90% не понял , НО это помогло мне взглянуть с другой стороны на JS , благодаря ей поменя стиль написания кода.

А вот я работаю с формами в проекте и web-технологии плохо знаю. Можно сделать так чтобы из опшыны перетаскивались в другие поля ввода по вашей методике. т.е. заполнять поля ввода перетаскивая элементы из списка или таблицы?

Добрый вечер. А я вот заметил, что метод document.elementFromPoint(x,y) во всех браузерах сейчас ведет себя одинаково. В смысле везде принимает clientX/Y.

Пример
var x = e.clientX,//e.pageX — window.pageXOffset,
y = e.clientY//e.pageY — window.pageYOffset,
element = document.elementFromPoint(x, y);
проверял в Ie9, ff 17, chrome 23, opera 12, стандартный браузер android (версия браузера 4.0.4) , dolphin browser 9.0.1 . кто-нибудь может проверить на ios ? скорей всего там все хорошо, но хотелось бы точно знать

Илья, спасибо огромное за отличную разжёванную до мелочей статью!
Я у себя в проекте использую твой код (финал). У меня также используется для вывода тултипов маленькая библиотека qtip. Так вот после того как я перемещаю с помощью твоего решения объект, все тултипы начинают показываться с каким-то диким смещением.
Пробовал вникнуть почему может происходить, не смог. Можешь помочь куда копнуть чтобы починить это?

Здравствуйте, подскажите почему у меня в этом коде

elem для ИЕ 8 всегда null ?

За ранее спасибо

Добрый день, воспользовался Вашим скриптом, очень понравилось, большое Вам спасибо.
Но возник вопрос, как вернуть элемент туда откуда взял?

млять автор штмл чо не выложил куда что в самом начале не. не понятно.Исходники где для начальных примеров.

Учите сперва основы, раз не можете понять элементарные вещи.

Ребят, помогите, не могу понять, где нужно значение поменять или что-то подправить. Вопрос в след. Если у элементов сразу абсолютное позиционирование то при нажатие элемент от курсора очень далеко, но всё остальное работает. Где исправить это?

Добрый день.
Не могу разобраться с переносом «между». Смысл задачи в том, что у меня в одном divе рандомно генерируются какое то количество html элементов и их нужно уметь перетаскивать в другой div. C самим переносом и обычным дропом разобрался, добавляю во второй div с помощью appendChild, соответственно элементы добавляются просто в конец. Проблема в том как добавить не в конец, а в любое другое место. Может кто-нибудь помочь разобраться?

Спасибо, большое Илья за статью, но у меня никак не получается при перетаскивании объекта на принимающем заставить исчезать тект или блок с текстом. К примеру: в примере с nested.html есть блок drop — как сделать так, чтобы при перетягивании на него объекта в момент отпускания кнопки мыши он исчезал?

Подскажите как получить содержимое после окончания перемешения элемента, хочу организовать запись этих данных в BD но не могу получить индефикатор перетаскиваемой записи для дальнейшева сохранения с новыми координатами:(

Very interesting information!Perfect just what I was searching for! candy crush

I really like your site and especially this post with lots of good and informative information. Very helpful to me.

Отправить комментарий

Текущий раздел
  • Drag and drop
  • Грамотное javascript-дерево за 7 шагов
  • Интеграция AJAX в интерфейс
  • Координаты элемента на странице
  • Правильные show/hide/toggle
  • Удобное дерево с AJAX-подгрузкой
Поиск по сайту
Содержание

Учебник javascript

Основные элементы языка

Сундучок с инструментами

Интерфейсы

Все об AJAX

Оптимизация

Разное

Последние комментарии
  • Комментарий
    18 часов 47 минут назад
  • A very nice blog, I like the way you.
    2 дня 4 часа назад
  • This is a great thing, I think everyone.
    2 дня 4 часа назад
  • It is wonderful to be here with.
    2 дня 4 часа назад
  • Download and play DOM Level 0 — это.
    2 дня 9 часов назад
  • We are the children
    3 дня 10 часов назад
  • function firstUniqLiter(str) <
    3 дня 18 часов назад
  • Великие посты! Я на самом деле.
    4 дня 11 часов назад
  • artical is really informative and.
    5 дней 2 часа назад
  • Вы не можете найти себя, уходя в.
    6 дней 7 часов назад
Последние темы на форуме

Заголовок первого блока

  • Пункт #1 Пункт #1 Пункт #1 Пункт #1 Пункт #1 Пункт #1

  • Пункт #2
  • Пункт #3
  • Пункт #4 Пункт #4 Пункт #4 Пункт #4 Пункт #4 Пункт #4 Пункт #4 Пункт #4 Пункт #4
  • Пункт #5
  • Пункт #6
  • Пункт #7
    • Пункт #7.1
    • Пункт #7.2
    • Пункт #7.3 Пункт #7.3 Пункт #7.3 Пункт #7.3 Пункт #7.3 Пункт #7.3 Пункт #7.3 Пункт #7.3 Пункт #7.3
    • Пункт #7.4
    • Пункт #7.5
  • Пункт #8
    • Пункт #8.1 Пункт #8.1 Пункт #8.1 Пункт #8.1 Пункт #8.1
    • Пункт #8.2
    • Пункт #8.3
  • Пункт #9
  • Пункт #10
  • Пункт #11 Пункт #11 Пункт #11 Пункт #11 Пункт #11
    • Пункт #11.1
    • Пункт #11.2
    • Пункт #11.3
    • Пункт #11.4
    • Пункт #11.5
    • Пункт #11.6
  • Пункт #12 Пункт #12 Пункт #12 Пункт #12 Пункт #12 Пункт #12 Пункт #12 Пункт #12 Пункт #12
  • Пункт #13
  • Пункт #14
  • Пункт #15
  • Пункт #16
  • Пункт #14 Пункт #14 Пункт #14 Пункт #14 Пункт #14 Пункт #14 Пункт #14 Пункт #14 Пункт #14
  • Пункт #15
  • Пункт #16

Заголовок второго блока

Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст

Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст

Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст

Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст

Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст

Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст

Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст

Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст

Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст Текст

Drag n drop multiple AJAX images upload with progress bar

AJAX is an important part in web development. This blog post covers steps to handle AJAX images upload with progress bar in Bootstrap with drag n drop feature. Some cool features in these steps are:

  • AJAX uploading images
  • Nicely displays any error occurred in Bootstrap style alert.
  • Shows progress bar while uploading.
  • Image preview after uploading.
  • Automatic image upload on drag and drop or on image selection through file browser button.
  • Bootstrap style file input button instead of regular one.
  • No external upload handling script is used.
  • Using famous Twitter Bootstrap front-end framework.
  • Multiple images upload.
  • Easily extensible.
  • Regular File browser for outdated browsers.
  • Extreme lightweight.

Drag n drop multiple AJAX images upload with progress bar in Bootstrap

Starting with a simple image drop zone, place the following markup at desired location in your page.

Drag and Drop Reorder Images using jQuery, Ajax, PHP & MySQL

Drag and Drop feature makes web page user-friendly and provides a nice user interface for the web application. Using jQuery and jQuery UI library, the drag&drop functionality can be implemented easily. The jQuery UI provides an easy way to add draggable functionality on the DOM element. This tutorial shows you the uses of jQuery drag and drop feature to sort the list elements dynamically with the database.

If you want to control the display order of images in the list dynamically, image order needs to be stored in the database. In this tutorial, we’ll provide a more interactive way to implement the images reorder functionality using jQuery and PHP. The example script demonstrates how to add jQuery drag and drop feature to rearrange images order and save images display order in the database using PHP and MySQL. The Drag and Drop Reorder functionality are very useful for managing images gallery, users list, and other dynamic content lists.

The example code helps to implement dynamic drag and drop reorder images using jQuery, Ajax, PHP, and MySQL. This sample code also can be used to implement the drag and drop reorder list, rows or sorting elements.

Before getting started, take a look at the files structure to build drag and drop reorder images functionality using jQuery, Ajax, PHP, and MySQL.

Create Database Table

To store images and their display order, a table needs to be created in the database. The following SQL creates an images table with some basic required fields in the MySQL database.

DB Class (DB.class.php)

The DB class controls all the database related works (connect, fetch and update records). Specify the database host ( $dbHost ), username ( $dbUsername ), password ( $dbPassword ), and name ( $dbName ) as per your MySQL database credentials.
The DB class has two methods to fetch and update images data.

  • getRows() function retrieve the images data from the database.
  • updateOrder() function update list order of the images.

Reorder Images with Drag and Drop (index.php)

The index.php file displays the images on the web page and allows the user to reorder images by drag and drop.

JavaScript Code (jQuery and Ajax):
The drag&drop reorder script uses jQuery and Ajax, so, include the jQuery and jQuery UI library to use Ajax and Draggable functionality.

The following jQuery code is used to enable the jQuery UI Draggable & Sortable features and implement the drag & drop functionality.

  • When the save request is submitted, current images order send to the orderUpdate.php file via Ajax to update the images order in the database.
  • After receiving the response from Ajax request, the page will be reloaded.

PHP & HTML Code:
Initially, all the images are fetched from the database and listed as per the order specified in the img_order field of images table using PHP and DB class.

  • Once the reorder link is clicked, drag & drop feature is enabled to reorder the images.
  • The user can change the position of the images by drag&drop.
  • On clicking the Save Reorder button, the images order is sent to the server-side script ( orderUpdate.php ) using jQuery Ajax for updating list order in the database.

Update Images Order (orderUpdate.php)

The orderUpdate.php file is called by the Ajax request and receive the current images order from the list page ( index.php ) through Ajax.

  • Retrieve the images IDs using PHP $_POST method.
  • Convert the images IDs string to array format.
  • Save the images order in the database using updateOrder() method of DB class.

Stylesheet (style.css)

The following CSS code is used to define the styles for the image list, links, and other HTML elements.

Conclusion

Drag and drop images order functionality is very useful for image management section where you want to allow the user to set the order of the images. Not only the images list, but also it can be used for many other purposes. Our example script will help you to add drag and drop reorder functionality to the element list using PHP and MySQL. Also, you can easily enhance our Drag & Drop Reorder script functionality as per your needs.

Are you want to get implementation help, or modify or extend the functionality of this script? Submit paid service request

JQuery Drag and Drop на Ajax загружен Div

Я хочу, чтобы иметь возможность перетаскивать элемент на странице в элемент droppable внутри загруженного div ajax. Я могу заставить код работать, когда я размещаю элемент droppable на обычной странице, но не тогда, когда у меня есть один и тот же элемент в загруженном div ajax. Я уверен, что это связано с тем, как я называю скрипты и как они загружаются на dom, но я не могу найти решение. Примечание. Я попытался вызвать код, который загружает содержимое ajax перед вызовом jquery ui, но это тоже не сработало. Вот как я все звоню, я сократил посторонний код для краткости.

загруженный код ajax

Это добавляется, потому что вы пытаетесь вызвать droppable на несуществующий элемент в этот момент. Чтобы решить эту проблему, вы можете использовать функцию обратного вызова, которая может быть присоединена к функции load и запустить остальные после этого.

Здесь вы можете найти другую информацию о load функции здесь. Обратный вызов может принимать аргументы и может использоваться, например, чтобы проверить, не является ли оно 404 или нет.

Ну, я смог заставить его работать, добавив перетаскиваемый /droppable код в сам загруженный div ajax. Таким образом, вышеизложенное будет изменено таким образом

загруженный код ajax

И эти строки script будут удалены из главной страницы

Drag And Drop AJAX Uploader Plugin — jQuery File Uploader

File Size: 25.3 KB
Views Total:
Last Update: 01/17/2020 00:06:00 UTC
Publish Date: 12/19/2020 04:28:14 UTC
Official Website: Go to website
License: MIT

The jQuery File Uploader transforms the normal file input into a drag and drop file uploader with ajax upload, image preview and progress bar support.

How to use it:

1. The required markup for the file uploader.

2. Create an empty container to display the files.

3. Inert both jQuery library and the dmuploader.min.js script at the bottom of the document.

4. The example JavaScript to activate the file uploader.

5. The example upload.php.

6. Config the file uploader with the following options.

7. Event handlers available.

Change log:

This awesome jQuery plugin is developed by danielm. For more Advanced Usages, please check the demo page or visit the official website.

Добавить комментарий