Подтвердить что ты не робот

HTML5 Перетаскивание - нет прозрачности?

Когда я перетаскиваю элемент на моей странице, элемент становится "призрачным". В основном он получает некоторое значение прозрачности.

Есть ли способ сделать это opacity: 1;?

4b9b3361

Ответ 1

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

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

Ответ 2

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

  • Скрыть элемент, который перетаскивается.
  • Создайте клон элемента, который перетаскивается.
  • Поместите клон вместо элемента, который перетаскивается.
  • Прослушайте событие drag, чтобы поместить элемент clone.

На практике выглядит следующим образом:

function Drag (subject) {
    var dative = this,
        handle,
        dragClickOffsetX,
        dragClickOffsetY,
        lastDragX,
        lastDragY;

    subject.draggable = true;

    dative.styleHandle(subject);

    subject.addEventListener('dragstart', function (e) {    
        handle = dative.makeHandle(subject);

        dragClickOffsetX = e.layerX;
        dragClickOffsetY = e.layerY;

        this.style.opacity = 0;
    });

    subject.addEventListener('drag', function (e) {
        var useX = e.x,
            useY = e.y;

        // Odd glitch
        if (useX === 0 && useY === 0) {
            useX = lastDragX;
            useY = lastDragY;
        }

        if (useX === lastDragX && useY === lastDragY) {
            return;
        }

        dative.translate(useX - dragClickOffsetX, useY - dragClickOffsetY, handle, subject);

        lastDragX = useX;
        lastDragY = useY;
    });

    subject.addEventListener('dragend', function (e) {
        this.style.opacity = 1;

        handle.parentNode.removeChild(handle);
    });
};

/**
 * Prevent the text contents of the handle element from being selected.
 */
Drag.prototype.styleHandle = function (node) {
    node.style['userSelect'] = 'none';
};

/**
 * @param {HTMLElement} subject
 * @return {HTMLElement}
 */
Drag.prototype.makeHandle = function (subject) {
    return this.makeClone(subject);
};

/**
 * Clone node.
 * 
 * @param {HTMLElement} node
 * @return {HTMLElement}
 */
Drag.prototype.makeClone = function (node) {
    var clone;

    clone = node.cloneNode(true);

    this.styleClone(clone, node.offsetWidth, node.offsetHeight);

    node.parentNode.insertBefore(clone, node);

    return clone;
};

/**
 * Make clone width and height static.
 * Take clone out of the element flow.
 *
 * @param {HTMLElement} node
 * @param {Number} width
 * @param {Nubmer} height
 */
Drag.prototype.styleClone = function (node, width, height) {
    node.style.position = 'fixed';
    node.style.zIndex = 9999;
    node.style.width = width + 'px';
    node.style.height = height + 'px';
    node.style.left = '-9999px';

    node.style.margin = 0;
    node.style.padding = 0;
};

/**
 * Used to position the handle element.
 * 
 * @param {Number} x
 * @param {Number} y
 * @param {HTMLElement} handle
 * @parma {HTMLElement} subject
 */
Drag.prototype.translate = function (x, y, handle, subject) {
    handle.style.left = x + 'px';
    handle.style.top = y + 'px';
};

Начните с присоединения элемента:

new Drag(document.querySelector('.element'));

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

Прежде чем вы будете слишком взволнованы, вам нужно рассмотреть несколько вещей:

Update:

Я написал библиотеку для сенсорной реализации механизма WHATWG drag & drop, https://github.com/gajus/pan.

Ответ 3

См. эту работу fiddle

У меня есть решение для создания непрозрачного изображения вместо призрак, и он отлично работает в chrome. Но он не работает в FF. Мне нужно тело, чтобы помочь мне заставить его работать в Firefox и других браузерах. меры 1. Мы сделаем наше собственное изображение-призрак и установим его как изображение перетаскивания.

document.addEventListener("dragstart", function(e) {
var img = document.createElement("img");
img.src = "img/hackergotchi-simpler.png";
e.dataTransfer.setDragImage(img, 5000, 5000);//5000 will be out of the window
}, false);

2. Мы клонируем изображение и добавим его в DOM ondrag

var crt,dragX,dragY;
function drag(ev) {
    crt = ev.target.cloneNode(true);
    crt.style.position = "absolute"; 
    document.body.appendChild(crt);
    ev.dataTransfer.setData("text", ev.target.id);
}

3. Затем мы сделаем клон перемещаться с помощью курсора

    document.addEventListener("dragover", function(ev){
ev = ev || window.event;
dragX = ev.pageX; dragY = ev.pageY;
crt.style.left=dragX+"px";crt.style.top=  dragY+"px";
console.log("X: "+dragX+" Y: "+dragY);
}, false);

4.At В последний раз мы сделаем видимость клонирования

   document.addEventListener("dragend", function( event ) {crt.style.display='none';});

Ответ 4

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

ответ: (используйте старый путь)

Ответ 5

Для тех (как и я), разочарованных реализацией drag & drop html5, вот базовое, ванильное, кросс-браузерное, без ошибок и полностью настраиваемое решение:

HTML:

<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="draggable"></div>

ЯШ:

var currentElement, currentDropzone, offsetX, offsetY;
function findZoneUnderPoint(x, y) {
  var dropzones = preview.querySelectorAll(".dropzone");
  for (var i = 0; i < dropzones.length; i++) {
    var box = dropzones[i].getBoundingClientRect();
    if (x > box.left && x < box.right && y > box.top && y < box.bottom) {
      return dropzones[i];
    }
  }
}
function onMouseDown(event) {
  currentElement = event.target.closest(".draggable");
  if (currentElement) {
    var box = currentElement.getBoundingClientRect();
    offsetX = event.clientX - box.x;
    offsetY = event.clientY - box.y;
    currentElement.classList.add("drag");           
    currentElement.style.width = box.width.toFixed()+"px";
    currentElement.style.height = box.height.toFixed()+"px";    
    currentElement.style.left = (event.clientX - offsetX) + "px";
    currentElement.style.top = (event.clientY - offsetY) + "px";
    currentElement.style.position = "fixed";
    currentElement.style.zIndex = "999";
    this.addEventListener("mousemove", onMouseMove);
    this.addEventListener("mouseup", onMouseUp);
  }
}
function onMouseMove(event) {
  currentElement.style.left = (event.clientX - offsetX) + "px";
  currentElement.style.top = (event.clientY - offsetY) + "px";
  var dropzone = findZoneUnderPoint(event.clientX, event.clientY);
  if (dropzone !== currentDropzone) {
    if (dropzone) {
      // -> drag enter zone
    }
    if (currentDropzone) {
      // -> drag leave zone
    }
    currentDropzone = dropzone;
  }
}
function onMouseUp(event) {
  var dropzone = findZoneUnderPoint(event.clientX, event.clientY);
  if (dropzone) {
    // -> drag complete
  } else {
    // -> drag canceled
  }
  currentElement = null;
  document.removeEventListener("mouseup", onMouseUp);
  document.removeEventListener("mousemove", onMouseMove);
}
document.addEventListener("mousedown", onMouseDown);

Примечание: для поддержки требуется polyfill Element.closest().

Ответ 6

как уже упоминалось, это обрабатывается браузером → вы не можете изменить это поведение, но если вам действительно нужен этот эффект, попробуйте искать движение мыши, когда мышь выключена (короткая: перетаскивание), проверьте, какой элемент выбран и создайте копию на лету, которая следует за курсором мыши. выглядит как идеальная работа для jQuery;)

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

Ответ 7

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

  • Вместо использования функции перетаскивания создайте новый элемент, который равен элементу, который должен быть перетаскиванием в исходное положение элемента, который нужно перетащить. Оригинальный элемент, который нужно перетащить, теперь должен быть невидимым. Реализуйте логику, которая восстанавливает элемент orignal и удаляет клон, как только мышь больше не будет нажата.

  • Сделайте клон Element stick в положение мыши. Событие, удаляющее клон, также должно проверить, освобождена ли мышь, пока элемент для перетаскивания расположен над областью, в которую можно перетащить исходное ement.

  • Если true, удалите клон и переместите исходный элемент в целевой контейнер.

В CSS и JS определенно много работы по настройке, но это может быть трюк, чтобы подавить стандарт JS.

Ответ 8

Я думаю, что прозрачность не получается из веб-содержимого, а из браузера и ОС. Если вы хотите изменить непрозрачность, вы должны настроить или взломать браузер и ОС

Ответ 9

Рабочий пример 2012 года можно посмотреть на Chrome (вы должны использовать Chrome) в "chrome://apps/". Если вы хотите точно знать, как они это делали, откройте инструменты разработки (strg + shift + i поскольку левый щелчок используется для пользовательского контекстного меню) и начните обратный инжиниринг (строка 7241 в index.html - хорошая отправная точка),

Вот краткое резюме:

Они клонировали перетаскиваемый элемент в dragstart, добавили его в некоторый контейнер верхнего уровня и поместили его в курсор при drag. Чтобы не блокировать события для реальных элементов, они стилизовали клон с помощью pointer-events: none;

Ответ 10

Если вы используете JavaScript, то в функции, которая обрабатывает событие dragStart, включите непрозрачность стиля в 1 пример:

function dragStartHandler(e) {
   this.style.opacity = '1.0';
}

Ответ 11

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

function dragStartHandler(e) { 
   $("span.{CLASS}")addClass('overdrag'); 
} 

тогда вам нужно придумать, чтобы сказать, что он остановился на драпировке и упал на место, а затем в RemoveClass ('overdrag');

Это не сложно сделать, поэтому я думаю, что вы сможете это сделать. Я хочу поблагодарить @DonaldHuckle, поскольку это действительно его решение не мое.