在第一節我們實作了基本的拖拽效果的時候,window.onload事件的響應函數定義如下:
Javascript代碼
- window.onload = function(){
- test = document.getElementById("test");
- test.onmousedown = down;
- test.onmousemove = move;
- document.onmouseup = up;
- //下面三行被标出。本頁中顔色無法顯示
- test.style.position = "relative";
- test.style.top = "0px";
- test.style.left = "0px";
- }
window.onload = function(){
test = document.getElementById("test");
test.onmousedown = down;
test.onmousemove = move;
document.onmouseup = up;
//下面三行被标出。本頁中顔色無法顯示
test.style.position = "relative";
test.style.top = "0px";
test.style.left = "0px";
}
注意重點标出的三行代碼,我們給元素設定了relative的position屬性,這是由于元素隻有定義了position屬性,它的top和 left屬性才會有效,才能進一步地制作拖拽的效果。是以給元素假定定位為relative實在是迫于無奈,隻能犧牲一些靈活性(當然也可以指定為 absolute,要根據實際情況)。
之後我們又設定元素的top和left屬性都為0px,這是為了友善後面的代碼獲得這兩個CSS屬性,簡化了代碼。但是這同時給使用這段代碼的文檔提了一個要求——要拖拽的元素必須設定top和left屬性為0。這顯然是一個不太合理的要求。
解決問題
我們在上一個例子中已經看到如何跨浏覽器地利用JavaScript獲得元素的CSS屬性了。現在就來稍稍修改上一個例子中的函數來,讓它服務于我們的拖拽代碼:
Javascript代碼
- <script type="text/javascript">
- ……
- function dragInit(node){
- if(node.className == "drag"){
- ……
- //仍然要求元素是relative定位
- node.style.position = "relative";
- node.dragging = false;
- }
- var children = node.childNodes;
- for(var i = 0;i < children.length; i++){
- dragInit(children[i]);
- }
- }
- window.onload = function(){
- dragInit(document);
- document.onmouseup = docUp;
- }
- function down(event)
- {
- event = event || window.event;
- dragElement = this;
- mouseX = parseInt(event.clientX);
- mouseY = parseInt(event.clientY);
- objY = parseInt(getNodeStyle(dragElement,"top"));
- objX = parseInt(getNodeStyle(dragElement,"left"));
- //IE不傳回未設定的CSS屬性
- if(!objY)objY=0;
- if(!objX)objX=0;
- this.style.zIndex = max++;
- }
- ……
- function getNodeStyle(node,styleName){
- var realStyle = null;
- if(node.currentStyle){
- realStyle = node.currentStyle[styleNmae];
- }else if(window.getComputedStyle){
- realStyle = window.getComputedStyle(node,null)[styleName];
- }
- return realStyle;
- }
<script type="text/javascript">
……
function dragInit(node){
if(node.className == "drag"){
……
//仍然要求元素是relative定位
node.style.position = "relative";
node.dragging = false;
}
var children = node.childNodes;
for(var i = 0;i < children.length; i++){
dragInit(children[i]);
}
}
window.onload = function(){
dragInit(document);
document.onmouseup = docUp;
}
function down(event)
{
event = event || window.event;
dragElement = this;
mouseX = parseInt(event.clientX);
mouseY = parseInt(event.clientY);
objY = parseInt(getNodeStyle(dragElement,"top"));
objX = parseInt(getNodeStyle(dragElement,"left"));
//IE不傳回未設定的CSS屬性
if(!objY)objY=0;
if(!objX)objX=0;
this.style.zIndex = max++;
}
……
function getNodeStyle(node,styleName){
var realStyle = null;
if(node.currentStyle){
realStyle = node.currentStyle[styleNmae];
}else if(window.getComputedStyle){
realStyle = window.getComputedStyle(node,null)[styleName];
}
return realStyle;
}
可以看到,我們使用getNodeStyle函數來獲得元素的CSS屬性值,這樣我們的代碼就可以适用于事先設定了top和left定位值的元素了。我做了一個測試頁面,給兩個可拖拽的div分别設定了如下的CSS規則:
Javascript代碼
- <style type="text/css">
- .drag{border:1px solid; width:400px; background:#CCCCCC;}
- #test1{ top:20px;}
- #test2{ left:40px;}
- </style>
<style type="text/css">
.drag{border:1px solid; width:400px; background:#CCCCCC;}
#test1{ top:20px;}
#test2{ left:40px;}
</style>
點選進入測試頁面。這樣,我們的拖拽代碼又改進了一小步。
JavaScript拖拽系列
1. JavaScript拖拽
2. JavaScript拖拽2——多元素、分離JS
3. JavaScript拖拽3——解決快速拖拽的問題
4. JavaScript拖拽4——獲得元素的位置
5. JavaScript拖拽5——性能優化
6. JavaScript拖拽6——修複錯誤