1.采用原生javaACript 实现全局触摸按钮
首先在控制台输出,观察事件有哪些关于触摸的字段可以使用,然后拿这些字段的数据开始来写方法。
因为要做的是全局触摸按钮,我需要拿到的是按钮时时的坐标位置,通过改变样式来改变按钮任意移动位置。所以就那了changedTouches里面的值。touches里面放的是touchstart的开始位置。用react的时候,touch事件会和click起冲突,导致链接点击有bug,所以需要那touchstart的值在touchend的时候做判断是点击事件还是触摸事件,来控制超链接的跳转。但是在普通h5中并没有这个问题,下面再细说。
这是html代码
<div class="active" id="active"> <a class="vote" id="vote" href="https://www.baidu.com"></a> //是全局可以触摸的对象,点击又可以做跳转 </div>
css样式
*{ margin: 0; padding:0; } //demo里面我就直接去掉所有默认的样式 .active { width: 100%; height: 100%; background: #9ff5ee; } .vote { position: fixed; bottom:40px; //全局触摸按钮使用定位的样式,可是随时改变定位的坐标来控制任意移动 right: 15px; width: 60px; height: 60px; border-radius: 50%; background: yellow; }
接下来是重点的javascript代码,顺便讲解一下(preventDefault()、stopPropagation()这些方法,ps其实是一边写博客一边学习,复习)
window.onload=function(){ //当一个Web页面加载完成后就会触发执行window.onload 里的代码 var vote=document.getElementById("vote");//通过id取按钮这个节点 function handleTouchEvent(e) { //只跟踪一次触摸 var width=document.documentElement.clientWidth,height=document.documentElement.clientHeight; //这里取屏幕的可视宽度和可视高度来控制按钮的最大最小访问 switch (e.type) { case "touchstart": //触摸开始调用的方法 console.log(‘start‘); break; case "touchend": console.log(‘end‘); //触摸结束调用的方法,这里不用用到这两个方法,所以不做详情介绍 break; case "touchmove": //全局触摸主要用到touchmove这个方法,touchmove过程中坐标会不断变化,取这个变化的坐标来控制当前那全局按钮#vote的坐标。使用style对象来修改目前的样式,其间做了一个控制,不让按钮可以移动上左下右任意方向的屏幕外我用了两层三目运算符来限制坐标的最小和最大值。 document.getElementById("vote").style.left=parseInt(e.changedTouches[0].clientX) - 60 <= 0 || parseInt(e.changedTouches[0].clientX) >= width - 60 ? (parseInt(e.changedTouches[0].clientX) - 60 <= 0 ? 0 : width - 60) : parseInt(e.changedTouches[0].clientX); //左右方向,最小位置不小于按钮的直径,最大不超过屏幕的可视宽度减按钮直径,上下方向也是 document.getElementById("vote").style.top=parseInt(e.changedTouches[0].clientY) - 60 <= 0 || parseInt(e.changedTouches[0].clientY) >= height - 60 ? (parseInt(e.changedTouches[0].clientY) - 60 <= 0 ? 0 : height-60) : parseInt(e.changedTouches[0].clientY); break; } } function clickA(e){ e.preventDefault();//这里是点击事件,阻止了默认事件的触发,所以超链接不会跳转,没阻止的话超链接就会正常跳转了 } vote.addEventListener("touchstart", handleTouchEvent, false); vote.addEventListener("touchmove", handleTouchEvent, false); vote.addEventListener("touchend", handleTouchEvent, false); vote.addEventListener("click", clickA, false); }
事件调用的方法有 attachEvent方法适用于IE addEventListener方法适用于FF
attachEvent只有两个参数,第一个参数为事件名称,第二个参数为接收事件处理的函数,因为是做h5的触摸,不需要做ie的兼容,所以没做全兼容。如果要做全兼容,如下
//兼容所有浏览器的事件监听方法 function(element, type, handler){ if (element.addEventListener) { element.addEventListener(type, handler, false); } else if (element.attachEvent) { element.attachEvent("on" + type, handler); } else { element["on" + type] = handler; } }
上文demo中事件的调用采用了addEventListener这个方法,这个方法有三个参数,第一个参数表示事件名称(不含 on,如 "click");第二个参数表示要接收事件处理的函数;第三个参数是一个bool值,一般为false。第三个参数的作用设置事件为冒泡还是捕获,如果为false那就是冒泡bubbling,为true就是捕获capture,冒泡和捕获是什么呢,看图
两层div元素,而且都设定有click事件,一般来说,如果我在内层黄色的元素上click不只会触发黄色元素的click事件,还会同时触发红色元素的click事件,由内到外的触发就是冒泡bubbling,由外层div到内层div触发就是捕获。这时候如果想阻止这些冒泡和捕获事件的发生,就需要用到stopPropagation()方法了,IE中则使用e.cancelBubble = true阻止冒泡,该方法阻止目标元素的冒泡事件,但是会不阻止默认行为。浏览器的默认行为就需要用到preventDefault()方法来阻止默认事件,比如上文的阻止超链接的跳转。
阻止冒泡的效果如下
function clickA(e){ alert(‘aaaa‘) e.stopPropagation(); //点击a#vote按钮,如果没有加入该行,点击该事件会同时出发a#vote和div#active上面的事件,加入该行就可以阻止冒泡 e.preventDefault();//这里是点击事情,阻止了默认事件的触发,所以超链接不会跳转,没阻止的话超链接就会正常跳转了 } function clickDiv(e){ alert(‘444‘) } document.getElementById("vote").addEventListener("click", clickA, false); //事件的调用 document.getElementById("active").addEventListener("click", clickDiv, false);
以上为原生javascript的实现方法react部分等待更新。。。
浅谈 原生javaScript&&react 实现全局触摸按钮(附带对addeventlistener的了解)
原文:http://www.cnblogs.com/whkl-m/p/6256665.html