首页 > 上网技巧 > 电脑小技巧 > 正文

使用HTML5的drag and drop做一个数独游戏

时间:2013-02-03 10:42 作者:QQ地带 我要评论

数独是很好玩的游戏,之前我用jQuery做了一个数独游戏,因为用javaScript来实现drag和drap非常麻烦,jQuery的UI提供了一套非常不错的drag和drap(以后就简称DnD算了),方便我们开发。现在HTML5支持原生的DnD了,那我们来学习下,并且将原先的数独游戏迁移到HTML5的DnD应用来。



 


先简单的了解下HTML5的DnD事件模型,事件发生在源元素(被拖动的元素)和目标元素(被进入的元素)上,为了简单的描述,我们将源元素称为src,目标元素叫des。


 


drag:src[拖动中]    dragstart:src[开始拖动]


dragenter:des[进入目标]


dragover:des[在目标移动]


dragleave:des[离开目标]


drop:des[释放拖动]


dragend:src[拖动完成]


所有的事件我们知道肯定都应该给我们一个event对象,帮助我们获得一些信息或我们来设置一些信息,以上事件都可以得到一个event,如果我们的事件函数是function(e)那


 


e.dataTransfer.effectAllowed,只能在dragstart事件设置,值为以下之一:"none", "copy", "copyLink", "copyMove", "link", "linkMove", "move", "all", and "uninitialized"


e.dataTransfer.dropEffect,返回拖来的行为,对应上面的effectAllowed,值是:"none", "copy", "link", and "move"


e.target,可以得到当前事件的dom对象,比如你可以得到e.target.innerHTML,或者设置e.target.classList.add,或者e.target.classList.remove


e.dataTransfer.setData(foramt,value),为拖动赋值,foramt的值是为了描述值的类型,一般有text/plain 和 text/uri-list


e.dataTransfer.getData(foramt),获取被拖来的元素通过setData存储的值


e.stopPropagation,阻止事件冒泡,这样可以防止子元素的拖动处理被带到父元素事件中(触发父元素事件),在IE中可以用e.cancelBubble = true


e.preventDefault,阻止默认事件发生,也可以简单的写return false,在IE中可以用e.returnValue = false


有了上面的基本概念,我们先做一个小小的模型,来测试几个技术要点:监视拖放事件,改变元素在拖放中的样式,传递值和检查值什么的


在body里面,我们声明了10个div元素,并且都标记允许拖放


 


<body>


    <div style="width: 50px; height: 50px; background-color: Red;" draggable="true">


        1


    </div>


    <div style="width: 50px; height: 50px; background-color: Yellow;" draggable="true">


        2


    </div>


    <div style="width: 50px; height: 50px; background-color: Blue;" draggable="true">


        3


    </div>


    <div style="width: 50px; height: 50px; background-color: Lime;" draggable="true">


        4


    </div>


    <div style="width: 50px; height: 50px; background-color: Maroon;" draggable="true">


        5


    </div>


    <div style="width: 50px; height: 50px; background-color: Black;" draggable="true">


        6


    </div>


    <div style="width: 50px; height: 50px; background-color: Orange;" draggable="true">


        7


    </div>


    <div style="width: 50px; height: 50px; background-color: Olive;" draggable="true">


        8


    </div>


    <div style="width: 50px; height: 50px; background-color: Teal;" draggable="true">


        9


    </div>


    <div style="width: 50px; height: 50px; background-color: Green;" draggable="true">


        10


    </div>


</body>


现在我们想做一个应用,只有相互有倍数关系的div之间才可用拖放。


 


首选我们做一个用于输出调式的小工具代码


$.log = function(msg) {


    console.log(msg);


}


 


这个我们可以方便的$.log()输出,而不要写冗长的console.log了


 


第一步,编写dragStart事件函数


function handleDragStart(e) {


    this.style.opacity = "0.5";


    e.dataTransfer.effectAllowed = "move";


    e.dataTransfer.setData("text/plain", this.innerHTML);


    //$.log(this.innerHTML);


    //$.log(e.target.innerHTML);


    //$.log(e.srcElement.innerHTML);


    [ ].forEach.call(document.querySelectorAll("div"),


    function(item) {


        var a = parseInt(e.target.innerHTML);


        var b = parseInt(item.innerHTML);


        if (a % b != 0 && b % a != 0) {


            item.style.opacity = "0.1";


 


        }


    });


}


 


以上的代码有几个要点


 


1 对事件来讲this、e.target和e.srcElement都是同一对象


2 在forEach中,this是指item,所以forEach中,我们要用e.target来引用


但是一测试我们就发现虽然元素可以拖拉,但并没有事件激活,那是应为我们没有为元素绑定事件,所以现在我们用addEventListener来将元素和事件绑定


$(


function() {


    [ ].forEach.call(document.querySelectorAll("div"),


function(item) {


     item.addEventListener("dragstart", handleDragStart, false);  


}


);


}


);


 


现在我们可以看到,当任意元素拖动的时候,不和其元素有相互倍数的元素变了很淡了。


 


第二步,当我们拖放完成后,所有div恢复原先颜色,那自然是编写handleDragEnd


function handleDragEnd(e) {


    if (e.preventDefault) {


        e.preventDefault(); //不要执行与事件关联的默认动作


    }


    [ ].forEach.call(document.querySelectorAll("div"),


    function(item) {


        item.style.opacity = "1";


    }


    );


}


 


记得将上面的事件做绑定哦,应该类似以下代码


$(


function() {


    [ ].forEach.call(document.querySelectorAll("div"),


function(item) {


     item.addEventListener("dragstart", handleDragStart, false);


     item.addEventListener("dragend", handleDragEnd, false);  


}


);


}


);


第三步,我们要通知那些互为倍数的元素允许我们做拖入操作


 


我们先需要为目标元素定义些事件函数


function handleDragEnter(e) {


    $.log(e);


}


 


function handleDragOver(e) {


    if (e.preventDefault) {


        e.preventDefault(); //不要执行与事件关联的默认动作


    }


    if (e.stopPropagation) {


        e.stopPropagation(); //停止事件的传播


    }


    $.log(e);


    return false;


}


 


 


function handleDragLeave(e) {


    $.log(e);


}


 


function handleDrop(e) {


    if (e.preventDefault) {


        e.preventDefault(); //不要执行与事件关联的默认动作


    }


    if (e.stopPropagation) {


        e.stopPropagation(); //停止事件的传播


    }


    console.log(e);


    return false;


}


 


 



标签:Html5
顶一下
(0)
0%
踩一下
(0)
0%

Google提供的广告