来源于Lynda.com.HTML5.Geolocation.in.Depth教程,我做了一些简单的注释。
关于html5中关于drap and drop的部分参见这个地址:
http://www.w3.org/TR/html5/dnd.html#the-dragevent-and-datatransfer-interfaces
示例的html文件:
<!DOCTYPE html>
<html>
<!--
RPS.html by Bill Weinman
<http://bw.org/contact/>
created 2011-07-12
updated 2011-07-18
Copyright (c) 2011 The BearHeart Group, LLC
This file may be used for personal educational purposes as needed.
Use for other purposes is granted provided that this notice is
retained and any changes made are clearly indicated as such.
-->
<head>
<title>
Drag and Drop Example: Rock, Paper, Scissors (1.0.8)
</title>
<link rel="stylesheet" type="text/css" href="../CSS/main.css" />
<link rel="stylesheet" type="text/css" href="../CSS/rps.css" />
<script type="text/javascript">
var dndSupported; // true if drag and drop supported
var dndEls = new Array();
var draggingElement;
var winners = {
Rock: 'Paper',
Paper: 'Scissors',
Scissors: 'Rock'
};
var hoverBorderStyle = '2px dashed #999';
var normalBorderStyle = '2px solid white';
// 检测浏览器是否支持drag and drop
function detectDragAndDrop() {
if (navigator.appName == 'Microsoft Internet Explorer') {
var ua = navigator.userAgent;
var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null) {
var rv = parseFloat( RegExp.$1 );
if(rv >= 6.0) return true;
}
return false;
}
if ('draggable' in document.createElement('span')) return true;
return false;
}
// DnD support
function handleDragStart(e) {
var rpsType = getRPSType(this);
draggingElement = this;
draggingElement.className = 'moving';
statusMessage('Drag ' + rpsType);
this.style.opacity = '0.4';
this.style.border = hoverBorderStyle;
e.dataTransfer.setDragImage(getRPSImg(this), 120, 120); // set the drag image
}
function handleDragEnd(e) {
this.style.opacity = '1.0';
// reset the element style
draggingElement.className = undefined;
draggingElement = undefined;
// reset all of the elements
for(var i = 0; i < dndEls.length; i++) {
dndEls[i].style.border = normalBorderStyle;
}
}
function handleDragOver(e) {
// Event.preventDefault() 方法:必須適時執行這個方法,來避免預設的動作被執行。
// 在ondragover中一定要執行preventDefault(),ondrop事件才會被觸發。
// 另外,從其他應用軟體或是文件拖曳東西進來,尤其是圖片時,預設的動作是顯示這個圖片或檔案,而不是真的執行drop。
// 這個時候要用document的ondragover事件把他擋掉。
if(e.preventDefault) e.preventDefault();
this.style.border = hoverBorderStyle;
return false; // some browsers may need this to prevent default action
}
function handleDragEnter(e) {
if(this !== draggingElement) statusMessage('Hover ' + getRPSType(draggingElement) + ' over ' + getRPSType(this));
this.style.border = hoverBorderStyle;
}
function handleDragLeave(e) {
this.style.border = normalBorderStyle;
}
function handleDrop(e) {
if(e.stopPropegation) e.stopPropagation(); // Stops some browsers from redirecting.
if(e.preventDefault) e.preventDefault();
if(this.id === draggingElement.id) return;
else isWinner(this, draggingElement);
}
// utility functions
function isWinner(under, over) {
var underType = getRPSType(under);
var overType = getRPSType(over);
if(overType == winners[underType]) {
statusMessage(overType + ' beats ' + underType);
swapRPS(under, over);
} else {
statusMessage(overType + ' does not beat ' + underType);
}
}
function getRPSFooter(e) {
var children = e.childNodes;
for( var i = 0; i < children.length; i++ ) {
if( children[i].nodeName.toLowerCase() == 'footer' ) return children[i];
}
return undefined;
}
function getRPSImg(e) {
var children = e.childNodes;
for( var i = 0; i < children.length; i++ ) {
if( children[i].nodeName.toLowerCase() == 'img' ) return children[i];
}
return undefined;
}
function getRPSType(e) {
var footer = getRPSFooter(e);
if(footer) return footer.innerHTML;
else return undefined;
}
function swapRPS(a, b) {
var holding = Object();
holding.img = getRPSImg(a);
holding.src = holding.img.src;
holding.footer = getRPSFooter(a);
holding.type = holding.footer.innerHTML;
holding.img.src = getRPSImg(b).src;
holding.footer.innerHTML = getRPSType(b);
getRPSImg(b).src = holding.src;
getRPSFooter(b).innerHTML = holding.type;
}
// Utility functions
var elStatus;
function element(id) { return document.getElementById(id); }
// 状态消息
function statusMessage(s) {
if(!elStatus) elStatus = element('statusMessage');
if(!elStatus) return;
if(s) elStatus.innerHTML = s;
else elStatus.innerHTML = ' ';
}
// App lifetime support
function init() {
if((dndSupported = detectDragAndDrop())) {
statusMessage('Using HTML5 Drag and Drop');
dndEls.push(element('rps1'), element('rps2'), element('rps3'));
for(var i = 0; i < dndEls.length; i++) {
// 注册drag and drop事件响应函数
// 开始拖拽时触发
dndEls[i].addEventListener('dragstart', handleDragStart, false);
// 在drop事件后触发
dndEls[i].addEventListener('dragend', handleDragEnd, false);
// 在被拖拽对象位于目标对象之上移动时触发
dndEls[i].addEventListener('dragover', handleDragOver, false);
// 在被拖拽对象进入目标对象时触发
dndEls[i].addEventListener('dragenter', handleDragEnter, false);
// 在被拖拽对象离开目标对象时触发
dndEls[i].addEventListener('dragleave', handleDragLeave, false);
// 在被拖拽对象位于目标对象之上放开鼠标按键时触发
dndEls[i].addEventListener('drop', handleDrop, false);
}
} else {
statusMessage('This browser does not support Drag and Drop');
}
}
window.onload = function() {
init();
}
</script>
</head>
<body>
<div id="content">
<h1>
Drag and Drop Example: Rock, Paper, Scissors (1.0.8)
</h1>
<p class="message" id="statusMessage" />
<div id="columns">
<!-- 这里的对象必须设置了draggable才能允许拖动 -->
<div class="rps" id="rps1"><img src="../Images/Rock.png" draggable="true" /><footer>Rock</Footer></div>
<div class="rps" id="rps2"><img src="../Images/Paper.png" draggable="true" /><footer>Paper</Footer></div>
<div class="rps" id="rps3"><img src="../Images/Scissors.png" draggable="true" /><footer>Scissors</Footer></div>
</div>
<p id="clear" /> <!-- provide some space at the bottom -->
</div>
</body>
</html>