您的位置:首页 > Web前端 > JQuery

使用jquery、light7实现手机移动段的长按事件

2017-08-15 11:39 162 查看
           这篇文章是我在一次项目的开发中,项目需要对一个列表名称,可以通过长按来进行修改。我在做这个长按的事件的功能时,主要还是在网上搜索各位大神们的经验博客来做的,当然也有根据自己的项目需要做了些修改。现在的我发表这篇文章,主要还是想把我的做法记录下来以备以后需要时可以直接查看,当然如果有人查看的话,发现不足之处,欢迎指正


          哎,刚才废话了下,现在直接上主题。我的项目是主要是对一个light7 做出来的列表,通过长按后,列表的名称变成可以输入框,输入完成之后,点击输入框之外的地方就给出一个confirm询问框,询问是否要修改,点击修改时,就访问后台进行修改,点击否时,则将回置为之前的内容,当然如果只是长按但没有改动名称,点击外面时则直接恢复名称列表为不可修改状态,不做出询问。这里的处理主要是根据我的项目需要来做的。
       
        自己模拟长按事件当然还是需要 touchstart、touchmove、touchend 这三个事件来处理的。
         touchstart:按下时会触发一个event事件
         touchmove:按下后移动时会触发一个event事件
         touchend :按下离开时会触发一个event事件
         长按事件的模拟就是通过这三个来实现,touchstart是按下,touchend是离开,只要在touchstart中定义一个定时器,当触碰的时间达到定时器的时间就可以去做长按事件的处理,那为什么还要使用touchmove呢,这是因为按下后如果鼠标或者手指滑来滑去,这不算是长按,算是拖动,所以也需要在touchmove中对事件的监听处理。
        
          手机上模拟长按时,首先要去除系统自带的长按时间,否则自己写的长按事件的处理不会起作用,
         去掉系统自带长按事件的方式:e.preventDefault(); 
       (这句话我在使用 vue.js来做的时候没作用,不知道为什么,请知道的各位告知,我在这里先谢谢了



        现在先上我的效果图:(随便模拟的一些数据,请不要在意)
          


                                                     图 1
       上面的图1就是长按前的效果,这个是使用light7实现的,其中的每一个名称都是 input 框,通过控制属性readonly和样式border来到达以上的效果。



                                              图 2
        上面的图2 是长按名称后,将名称的input框变回可输入和有边框的样式。



                                                    图 3
        修改名称后,当点击输入框的外面任意地方时,则给出的询问框。
在我实现这个询问框弹出时,由于document上的一些特性,弹出询问框后马上去调用了其他的方法(不知道调用了什么,等以后再好好的查找下),造成了询问框一闪而过,最后还是通过了定时器setTimeout来,让询问框在document 调用其他的方法后在弹出来,我延迟的时间是50ms,这个在直观上完全察觉不出来,而且这是在前段的延迟,不影响其他。
       效果上说了,现在可以说代码的实现了。
var touchFlag = false; //长按标志
var touchId = ""; //长按触发的input Id
var timeOutEvent=0;
var preTouchValue = ""; //修改前的值
var clickGroupId = "";
function longTouch(){
$("#ui li").on({ // 给每个li 绑定 touchstart、touchmove、touchend 事件
touchstart: function(e){
var _this = $(this);
clickGroupId = _this.find("input").attr("id"); //li下对应input 的id ,我在这里获取一个,因为我这里也还需要点击的方法
e.preventDefault(); //去除系统自带的长按事件,就这一句话,很神奇
timeOutEvent = setTimeout(function(){ //设置长按的时间,500ms刚刚好,这里面就是长按后的处理了,根据自己的需要来写
timeOutEvent = 0;

var lis = $("#qfzui li");
for(var i=0;i<lis.length;i++){
var pt = $(lis[i]).find("input");
$(pt).attr("readOnly","true");
$(pt).css("border","none");
}

var ipt = _this.find("input");
preTouchValue = ipt.val(); //长按修改前的值
touchId = ipt.attr("id");
touchFlag = true;
$(ipt).removeAttr("readOnly");
$(ipt).css("border","1px solid #ccc");
$(ipt).css("width","11rem");
$(ipt).css("height","1.6rem");
ipt.focusEnd(); // 这里的这个方法是我自己的写的插件,是将光标定位到了input框的后面

},500);

},
touchmove: function(e){
clearTimeout(timeOutEvent); // 当按下去后,有滑动时,要把模拟长按的定时器清楚掉,不触发模拟长按的处理,下面的touchend中的也一样
timeOutEvent = 0;
},
touchend: function(e){
clearTimeout(timeOutEvent);
if(timeOutEvent!=0){

if(!touchFlag){ //当触按离开后,如果不是长按,则做点击的处理,这里的goPage();方法,我这里就不给出来了

9d89
goPage(clickGroupId,'z');
}
}
return false;
}
});

}
//组件 将光标定位到了input 后面
$.fn.focusEnd = function(){

var selectionStart = this.val().length;
var selectionEnd = this.val().length;
if(this.lengh == 0) return this;
input = this[0];

if (input.createTextRange) {
var range = input.createTextRange();
range.collapse(true);
range.moveEnd('character', selectionEnd);
range.moveStart('character', selectionStart);
range.select();
} else if (input.setSelectionRange) {
input.focus();
input.setSelectionRange(selectionStart, selectionEnd);
}

return this;
}


长按处理了,那下面就是要实现点 input 的外面来触发修改了。我这里主要还是通过使用 input 的 id 值来判断当前点击的是不是被长按 input 的外面,因外在数据生成一个 li 列表时,我给了每一个input 一个id 值,这样就能区分当我触发长按后,再点击其他的地方时,点击的是当前的input 还是外面了。

function documentTouch(){
document.addEventListener("touchstart",function(e){  //监听整个document
if(touchFlag){
var id = $(e.target).attr("id");  // 当点击的外面有id值时,就是id的值,没有则是undefind
var className = e.target.className;
var $ipt = $("#"+touchId);
var newGourpName = $ipt.val();
//值发生变化才提示是否要修改
if(newGourpName==preTouchValue){
if(id!=touchId){
setTimeout(function(){
touchFlag = false;
$ipt.attr("readOnly","true");
$ipt.css("border","none");
},300);
}
return;
}
if(id!=touchId){  //在这里比较就行,点击的是不是长按input的外面
if(newGourpName==""){
$.toast("群组名不能为空");
return;
}

setTimeout(function(){
touchFlag = false;
$.confirm("是否要把群组名为 \""+newGourpName+"\""
,function(){
$ipt.attr("readOnly","true");
$ipt.css("border","none");
savegname(touchId,newGourpName);

},function(){
$ipt.attr("readOnly","true");
$ipt.css("border","none");
$ipt.val(preTouchValue);
});

},50);

}

}

})
}


写到这里,这个长按事件的实现已经做好了,当然上面的描述和代码只是一种实现的方式,并不能直接拿来运行,因为还要有html页面的生成呢,这个我这里不多说了,相信各位都会。

  

 

           
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐