Глобальное переопределение курсора мыши с помощью JavaScript

в моем веб-приложении я пытаюсь реализовать некоторые функции перетаскивания. У меня есть глобальный компонент JavaScript, который делает основные вещи. Этот объект также отвечает за изменение курсора мыши, в зависимости от текущей операции перетаскивания (перемещение, копирование, ссылка). На моей веб-странице есть различные элементы HTML, которые определяют собственный стиль курсора, встроенный или через файл CSS.

Итак, есть ли способ для моего центрального компонента перетаскивания изменить курсор мыши глобально, независимо от стиля элемента, над которым находится курсор мыши?

пробовал:

document.body.style.cursor = "move"

и

document.body.style.cursor = "move !important"

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

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

5 ответов


пожалуйста: не убивайте свой CSS!

чтобы реализовать функцию перетаскивания, вы должны использовать очень важный API:элемент.setCapture(). Это имеет следующие последствия:

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

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

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

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

возможно, вы также можете использовать jQuery UI draggable если это возможно в ваших условиях.


document.body.style.cursor = "move"

должно работать нормально.

тем не менее, я рекомендую сделать глобальный стиль через CSS.

определить следующим образом:

body{
   cursor:move;
}

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

вы могли бы сделать что-то вроде этого:

your-element.style.cursor = "inherit"; // (or "default")

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

body *{
   cursor:inherit;
}

обратите внимание, однако, что * обычно считается плохой селектор выбора.


к сожалению element.setCapture() не работает для IE

Я использую подход грубой силы-откройте прозрачный div поверх всей страницы на время перетаскивания.

.tbFiller {
   position:absolute;
   z-index:5000; 
   left:0;
   top:0;
   width:100%;
   height:100%; 
   background-color:transparent;
   cursor:move;
}

...

function dragStart(event) {
    // other code...
    document.tbFiller=document.createElement("div");
    document.tbFiller.className="tbFiller"
}

function dragStop(event) {
    // other code...
    document.tbFiller.parentNode.removeChild(document.tbFiller);
}

Если вы делаете объявление css:

* {cursor:move;}

это должно работать.


это то, что я делаю, и он работает в Firefox, Chrome, Edge и IE с 2017 года.

добавьте это правило CSS на свою страницу:

html.reset-all-cursors *
{
    cursor: inherit !important;
}

когда <html> элемент имеет класс "reset-all-cursors", это переопределяет все курсоры, которые установлены для элементов индивидуально в их style атрибут - без фактического манипулирования самими элементами. Нет необходимости убирать повсюду.

затем, когда вы хотите переопределить курсор на всю страницу с element, e. г. элемент перетаскивается, сделайте это в JavaScript:

element.setCapture && element.setCapture();
$("html").addClass("reset-all-cursors");
document.documentElement.style.setProperty("cursor", $(element).css("cursor"), "important");

использует setCapture функция где она доступна. В настоящее время это просто Firefox, хотя они говорят, что это API Microsoft. Затем специальный класс добавляется ко всему документу, который отключает все пользовательские курсоры. Наконец, установите курсор, который вы хотите на документе, чтобы он должен отображаться везде.

в сочетании с захватом событий это может даже расширить перетаскивание курсор за пределами страницы и окна браузера. setCapture это надежно в Firefox. Но в других местах он не работает каждый раз, в зависимости от браузера, его макета пользовательского интерфейса и пути, по которому курсор мыши покидает окно. ;-)

когда вы закончите, очистить:

element.releaseCapture && element.releaseCapture();
$("html").removeClass("reset-all-cursors");
document.documentElement.style.setProperty("cursor", "");

это включает jQuery для addClass и removeClass. В простых сценариях вы можете просто сравнить и установить на document.documentElement. Это сломает другие библиотеки как Modernizr, хотя. Вы можете избавиться от css функция, если вы уже знаете желаемый курсор элемента или попробуйте что-то вроде element.style.cursor.