鼠標事件和距離屬性

js中有不少「距離」,爲了避免會混淆這裏總結一下其中部分距離chrome

本文包括元素屬性相關的距離和鼠標事件中的距離,廢話很少說,進入正文編程

先補充一下,本文的測試環境以下:windows

Chrome Dev 54.0.2840.71
Firefox 49.0
Opera 41.0
Safari 10.1
IE 11。

前四者運行在macOS Sierra 10.12上,IE11運行在搭載windows10 1607的虛擬機上瀏覽器

元素屬性中的各類「距離」

元素屬性中的距離有如下6對:測試

scrollLeft: 設置或獲取位於對象左邊界和窗口中可見內容的最左端之間的距離
scrollTop: 設置或獲取位於對象最頂端和窗口中可見內容的最頂端之間的距離

offsetHeight: 得到對象的可視區域的高度,包括邊框
offsetWidth: 得到對象的可視區域的寬度,包括邊框spa

clientHeight: 得到對象邊框內部分的高度
clientWidth: 得到對象邊框內部分的寬度firefox

offsetLeft: 獲取對象相對於版面或由offsetParent屬性指定的父座標的計算左側位置
offsetTop: 獲取對象相對於版面或由offsetTop屬性指定的父座標的計算頂端位置3d

clientTop: 獲取對象頂部邊框寬度
clientLeft: 獲取對象左側邊框寬度code

scrollWidth: 獲取對象的滾動寬度
scrollHeight: 獲取對象的滾動高度。orm

上面提到了offsetParent屬性,其實當前div相對誰定位,這個屬性就是誰。根據position值不一樣,有如下2種狀況

  • 當父輩元素都沒有relative屬性時,不管當前元素的position是absolute,relative,fixed或fixed,offsetParent都是body元素
  • 父輩元素有relative屬性時,不管當前元素的position是absolute,relative,fixed或fixed,offsetParent是具備relative屬性的最近父元素

分不清楚? 看下圖

這個裏面能夠清晰的看到上方的前4對,和他們之間的關係。

關於jQuery的元素距離屬性,文章最後整理了他們和DOM屬性之間的關係。

第一個值得強調的是,上面的這個例子中的div的box-sizing屬性是默認的content-box, 它的offsetHeight,clientHeight,clientWidth和offsetWidth有以下關係:

clientHeight = height + paddingTopWidth + paddingBottomWidth;
clientWidth = width + paddingLeftWidth + paddingRightWidth;

offsetHeight = clientHeight + borderTopWidth + borderBottomWidth;
offsetWidth = clientWidth + borderLeftWidth + borderRightWidth;

若是box-sizing屬性是border-box,那麼,它們的關係將以下(ie6 ie7默認是這樣的):

offsetHeight = height;
offsetWidth = width;

clientHeight = height - borderTopWidth - borderBottomWidth;
clientWidth = width - borderLeftWidth - borderRightWidth;

第二個值得強調的是,這個例子中,因爲它的父元素沒有設置position:relative,因此圖中這個div利用position:absolute;相對文檔定位,若是給他添加一個具備position:relative屬性的父div,那麼offsetLeft和offsetTop就是下圖這樣:

不過不管它怎麼的定位,哪怕是position:relative或fixed,它的計算關係也不會發生變化,依然是:

offsetLeft = left + marginLeft;
offsetTop = top + marginTop;

講了這麼多,那麼scrollWidth和scrollHeight呢?scrollWidth和scrollHeight在不一樣瀏覽器裏面並不一致,以下圖(從左到右依次是Chrome, Firefox, Opera, Safari, IE11)

diff

其實仔細研究這個裏面的不一樣,會發如今不一樣的瀏覽器div的offsetLeft、offsetTop這兩個值的屬性並不徹底相同。當div裏面的內容溢出時,只有IE保留了padding的所有值,chrome、opera和safari會忽略padding-right的值視其爲0,firefox會同時忽略padding-right和padding-bottom,以下圖

在各個瀏覽器中,對於滾動條自己的渲染也不同。它們會在計算scrollWidth和scrollHeight時排除各自的滾動條寬度。除了上述的不一樣,實際發現每一個瀏覽器中scrollLeft和scrollTop的最大值也不同,甚至差距極大,因爲scrollLeft和scrollTop隨滾動事件發生而輸出,博主就上述例子的最大值記錄以下:

maximum value chrome Firefox opera safari IE11
scrollLeft 330 160 827 330 217
scrollTop 230 210 485 230 330

實際上就是因爲這些元素屬性在不一樣瀏覽器中的差別致使scrollWidth和scrollHeight的不一樣,具體使用應格外注意。不過博主看過一些資料表示這兩個屬性和offsetParent有關,經過實際編程發現它們和offsetParent無關,這裏不展開描述了,由於低版本瀏覽器,尤爲ie7 ie6的實現方式可能會比較奇葩。

鼠標事件中的各類「距離」

鼠標事件不少,不過每一個事件中關於距離的屬性含義是同樣的,這裏用mousemove來說解,具體的內容會在不久以後寫到了js事件部分講解。
鼠標實現對於如今的瀏覽器來講,實現都是同樣的了,下面例子都在Chorme中實現。

鼠標事件有如下6對:

event.clientX:相對瀏覽器左上角的水平座標
event.clientY:相對瀏覽器左上角的垂直座標

event.offsetX:相對於事件源(event.target||event.srcElement)左上角水平偏移
event.offsetY:相對於事件源(event.target||event.srcElement)左上角垂直偏移

event.pageX:相對於document左上角的水平座標
event.pageY:相對於document左上角的垂直座標

event.layerX:相對於offsetParent左上角的水平偏移
event.layerY:相對於offsetParent左上角的水平偏移

event.movementX:相對於前一次事件中screenX的偏移
event.movementY:相對於前一次事件中screenY的偏移

event.screenX:相對於屏幕左上角的水平座標
event.screenY:相對於屏幕左上角的垂直座標

x:和pageX同樣,用於兼容IE8及之前瀏覽器
y:和pageY同樣,用於兼容IE8及之前瀏覽器

總之,仍是先看圖

<todo>
*這個圖中,黑色實線邊框表示瀏覽器可視區域部分,外層藍色虛線框表示整個DOM部分,整個圖爲電腦屏幕

圖裏面怎麼沒有movementX和movementY?由於這個事件的值和上一個事件有關,關係以下:

currentEvent.movementX = currentEvent.screenX - previousEvent.screenX
currentEvent.movementY = currentEvent.screenY - previousEvent.screenY

值得注意的時offsetX和offsetY,他表示鼠標到事件源padding左上角的的偏移,這裏mousemove事件註冊在window上,因此位置如圖所示。

當瀏覽器的水平滾動條滑動之後,pageX和clientX就不一樣了。同理,當瀏覽器的垂直滾動條滑動之後,pageY和clientY就不一樣了,但它們始終存在如下關係:

event.pageX = event.clientX + body.scrollLeft;
event.pageY = event.clientY + body.scrollTop;

鼠標事件中的距離比元素中的簡單一些,具體的使用放在以後寫的事件部分。

jQuery中元素距離屬性

var $div = $("#div");

$div.width(); //元素寬度,不包括padding和border
$div.height(); //元素高度,不包括padding和border

$div.innerWidth(); //元素內寬度,包括padding,不包括border
$div.innerHeight(); //元素內高度,包括padding,不包括border

$div.outterWidth(); //元素可見寬度,包括padding和border
$div.outterHeight(); //元素可見高度,包括padding和border

$div.outterWidth(true); //元素所有寬度,包括padding、border和margin$div.outterHeight(true); //元素所有高度,包括padding、border和margin

相關文章
相關標籤/搜索