Глобальное переопределение курсора мыши с помощью JavaScript
В моем веб-приложении я пытаюсь реализовать некоторые функции перетаскивания. У меня есть глобальный компонент JavaScript, который делает основной материал. Этот объект также отвечает за изменение указателя мыши в зависимости от текущей операции перетаскивания (перемещение, копирование, ссылка). На моей веб-странице есть различные HTML-элементы, которые определяют собственный стиль курсора, как встроенный, так и через CSS файл.
Итак, есть ли способ, чтобы мой центральный компонент перетаскивания менял курсор мыши глобально, независимо от стиля элемента, над которым курсор мыши закончился?
Я пробовал:
document.body.style.cursor = "move"
и
document.body.style.cursor = "move !important"
Но это не сработает. Каждый раз, когда я перетаскиваю элемент, определяющий стиль курсора, курсор меняется на этот стиль.
Конечно, я мог бы изменить стиль элемента, который я сейчас перетаскиваю, но тогда я должен reset его, когда я убираю элемент. Это кажется немного сложным. Я ищу глобальное решение.
Ответы
Ответ 1
Пожалуйста, не убивайте CSS!
Чтобы реализовать операцию перетаскивания, вам нужно использовать очень важный API: element.setCapture(). Это имеет следующие последствия:
- Все события мыши перенаправляются на целевой элемент захвата, независимо от того, где они происходили (даже вне окна браузера).
- Курсор будет курсором целевого элемента захвата, независимо от того, где находится указатель мыши.
Вы должны вызвать element.releaseCapture() или document.releaseCapture(), чтобы вернуться в нормальный режим в конце операции.
Остерегайтесь наивной реализации перетаскивания: у вас может быть много болезненных проблем, например, например (что-то еще): что произойдет, если мышь вывешивается за пределами окна браузера или над элементом, который имеет обработчик, который останавливает распространение. Использование setCapture() решает все эти проблемы и стиль курсора.
Вы можете прочитать этот отличный учебник, который подробно объясняет это, если вы хотите реализовать перетаскивание самостоятельно.
Возможно, вы также можете использовать jQuery UI draggable, если это возможно в вашем контексте.
Ответ 2
document.body.style.cursor = "move"
должен работать нормально.
Однако я рекомендую сделать глобальный стиль с помощью CSS.
определяют следующее:
body{
cursor:move;
}
Проблема заключается в том, что определенные курсоры на других элементах переопределяют стиль тела.
Вы можете сделать следующее:
your-element.style.cursor = "inherit"; // (or "default")
до reset до унаследованного стиля из тела или с помощью CSS:
body *{
cursor:inherit;
}
Обратите внимание, что *
обычно считается неправильным выбором выбора.
Ответ 3
К сожалению, 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);
}
Ответ 4
Если вы выполните объявление css:
* {cursor:move;}
Он должен работать.
Ответ 5
Это то, что я делаю, и работает в 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, хотя они говорят, что это Microsoft API. Затем специальный класс добавляется ко всему документу, который отключает все пользовательские курсоры. Наконец, установите курсор, который вы хотите в документе, чтобы он отображался повсюду.
В сочетании с захватом событий это может даже расширить курсор перетаскивания за пределы страницы и окна браузера. setCapture
делает это надежно в Firefox. Но в другом месте он не работает каждый раз, в зависимости от браузера, его макета пользовательского интерфейса и пути, по которому курсор мыши покидает окно.; -)
Когда вы закончите, очистите:
element.releaseCapture && element.releaseCapture();
$("html").removeClass("reset-all-cursors");
document.documentElement.style.setProperty("cursor", "");
Это включает jQuery для addClass
и removeClass
. В простых сценариях вы можете просто сравнить и установить атрибут class
document.documentElement
. Однако это сломает другие библиотеки, такие как Modernizr. Вы можете избавиться от функции css
, если вы уже знаете элемент, который уже нужен, или попробуйте что-то вроде element.style.cursor
.