2012-05-25 65 views
11

在我的web應用程序中,我嘗試實現一些拖放功能。我有一個全局的JavaScript組件,它完成了基本的功能。該對象還負責更改鼠標光標,具體取決於當前的拖動操作(移動,複製,鏈接)。在我的網頁上有各種HTML元素,它們定義了自己的遊標樣式,可以是內嵌的,也可以是通過CSS文件。使用JavaScript全局覆蓋鼠標光標

那麼,有沒有辦法讓我的中央拖放組件全局更改鼠標光標,獨立於鼠標光標所在元素的樣式?

我想:

document.body.style.cursor = "move" 

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

但它不工作。每次我拖動一個定義光標樣式的元素時,光標就會變成該樣式。

當然,我可以改變當前拖動的元素的樣式,但是當我將元素拉長時,必須重置它。這似乎有點複雜。我正在尋找全球解決方案。

回答

10

請不要屠殺你的CSS!

要實現拖放操作,你必須使用一個非常重要的API:element.setCapture()。這有這樣的後果:

  • 所有鼠標事件被重定向到捕獲的目標元素,無論在哪裏,他們發生(即使外面的瀏覽器窗口)
  • 光標將目標元素的光標捕獲,而不管鼠標指針在哪裏。

你必須調用element.releaseCapture()document.releaseCapture()於在操作結束時切換回正常模式。

謹防拖放的天真implemnntation的:你可以有很多的痛苦的問題,例如像(其中包括):如果鼠標realeased瀏覽器的窗口外面發生了什麼,或在一個有一個處理程序停止傳播的元素。使用setCapture()解決了所有這些問題,以及光標樣式。

你可以閱讀this excellent tutorial,詳細解釋這個,如果你想實現拖放自己。

也許你也可以在你的上下文中使用jQuery UI draggable

+4

setCapture可以在IE和FF/Moz中使用,但是Chrome並不支持這個超棒的功能:( – eselk

+0

setCapture現在只能在Firefox中使用(不在IE 11中),但是它可以在它出現時使用 – ygoe

4
document.body.style.cursor = "move" 

應該工作得很好。

但是,我建議通過CSS來做全局樣式。

定義以下內容:

body{ 
    cursor:move; 
} 

的問題是,在其他元素定義的遊標覆蓋體風格。

你可以做些事情是這樣的:

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

將其從體內或CSS重置爲繼承樣式:但是

body *{ 
    cursor:inherit; 
} 

注意,那*通常被認爲是一個壞的選擇-選擇。

2

如果你做一個CSS聲明:

* {cursor:move;}

它應該工作。

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); 
} 
+1

setCapture工程在IE中,但不要認爲Chrome有任何類似的東西 – eselk

+0

setCapture在IE 11中無法正常工作.Firefox說這是一個微軟API,他們可能已經放棄了它。但是你不需要一個覆蓋div,一個CSS規則和設置一個班就夠了。 – ygoe

0

這是我做的,它在火狐,Chrome,Edge和IE工程作爲2017年

這個CSS規則添加到您的網頁:

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

<html>元素具有「reset-all-cursors」類,它將覆蓋爲style屬性中的元素單獨設置的所有遊標 - 而不實際操作元素本身。沒有必要清理整個地方。

然後,當您想要覆蓋整個頁面上的光標時,使用任何element即e。 G。元素被拖動,在JavaScript這樣做:

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

它使用setCapture函數,其中可用。目前這只是Firefox,儘管他們說這是一個微軟API。然後將特殊類添加到整個文檔中,禁用所有自定義遊標。最後在文檔上設置你想要的光標,以便它應該出現在任何地方。

結合捕獲事件,這甚至可能會將拖動光標擴展到頁面和瀏覽器窗口之外。 setCapture在Firefox中可靠地執行此操作。但在其他地方,它並不是每次都有效,這取決於瀏覽器,UI佈局以及鼠標光標離開窗口的路徑。 ;-)

當你完成,清理:

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

這包括jQuery的用於addClassremoveClass。在簡單情況下,您可以簡單地比較並設置document.documentElementclass屬性。儘管如此,這將破壞像Modernizr這樣的其他圖書館。如果您已經知道該元素所需的光標,則可以刪除css函數,或嘗試諸如element.style.cursor之類的操作。