Gmail обрабатывает загрузку вложенных файлов с помощью перетаскивания несколькими хитрыми способами:
1) При перетаскивании файла в браузер появляется раскрывающаяся зона.Курсор отображает обратную связь, указывающую, находитесь ли вы в рабочей зоне или нет (в окнах красный крестообразный круг используется, если он находится вне рабочей зоны).Если вы перетаскиваете внутри окна, но за пределами зоны перетаскивания, отбрасывание перехватывается таким образом, что поведение браузера по умолчанию предотвращается (обычно переход на другое место для отображения перетаскиваемого файла).
Наиболее очевидный способ сделать это -установите обработчик dragover на BODY, чтобы вызвать появление dropzone и предотвращать дефолт, но как насчет смены курсора?Есть ли какой-нибудь способ использовать dataTransfer.effectAllowed = 'none'?
2) Перетаскивание текста из одной части окна в другую не вызывает обработку перетаскивания (т. Е. В зоне сброса нетпоявляются) - и предотвращение защиты, упомянутое в # 1, не срабатывает.
Если я фиксирую событие перетаскивания в ТЕЛЕ (из # 1), то перетаскивание текста внутри окна предотвращается.Как они выполняют обе эти функции одновременно?Кажется, что это сложнее, чем может показаться на первый взгляд.
ОБНОВЛЕНИЕ:
Я узнал две взаимосвязанные вещи, пытаясь полностью решить эту проблему:
1) Похожечто IE даже не будет запускать обработчик события drop, если dropEffect = 'none' ... поэтому я решил установить его равным none, если существует e.dataTransfer.types (что он делает в Chrome & FF, но не в IE).Недостатком является то, что курсор не имеет красного перекрестия, но, по крайней мере, я могу перехватить падение, чтобы предотвратить навигацию.Лучше всего определить, было ли это удаление файла в IE, если e.dataTransfer.getData ('Text') == null.(В моем случае я хотел иметь возможность получать капли или файлов или текста, поэтому я могу определить разницу в IE.)
2) Это было неПонятно, как Gmail скрывает эту зону при выходе из браузера.Если вы используете чистое событие dragleave на странице, то перетаскивание в любой дочерний элемент вызовет обработчик dragleave, даже если вы действительно не покинули страницу.Затем я заметил, что в Gmail есть задержка, прежде чем исчезнет дропзона, поэтому я предполагаю, что они используют таймер, чтобы скрыть дропзону (которая сбрасывается на что-то вроде dragover).Но я нашел альтернативное решение, которое пока работает:
function areXYInside(e){
var w=e.target.offsetWidth;
var h=e.target.offsetHeight;
var x=e.offsetX;
var y=e.offsetY;
return !(x<0 || x>=w || y<0 || y>=h);
}
А затем:
$("#page").bind('dragleave', function(e){
if(this!=e.target) return false;
if(!areXYInside(e)){
hideBox();
}
return false;
});