移动端2

_______________________________________________________________________________________________

十二、手机震动

navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate ||

                    navigator.msVibrate;

if(navigator.vibrate){                    // 判断设备是否支持震动

  var shock = document.getElementById("shock");

  shock.onclick = function(){

    navigator.vibrate(50);                //震动1次:  震动毫秒数

    navigator.vibrate([5000,3000,1000]);  //震动多次: 奇位数是震动毫秒数,偶位数是震动停止毫秒数

    navigator.vibrate(0);                 //停止震动: 传入0或空数组

  };

}

注意: 对navigator.vibrate方法的调用并不会引起手机循环振动,当将参数中需要震动的时间进行完毕后,就会停止震动

_______________________________________________________________________________________________

十三、手机摇动

if(window.DeviceMotionEvent){                //判断手机是否支持摇一摇

  var speed = 25;

  var x = y = z = lastX = lastY = lastZ = 0;

  window.addEventListener('devicemotion', function(){

    var acceleration = event.accelerationIncludingGravity;

    x = acceleration.x;

    y = acceleration.y;

    if(Math.abs(x-lastX) > speed || Math.abs(y-lastY) > speed){    //当摇动距离大于限定距离时

      //摇动时发生的事件

    }

    lastX = x;

    lastY = y;

  }, false);

}

_______________________________________________________________________________________________

十四、全屏显示

var full = document.getElementById("full");

                        //判断是否支持切换到全屏状态

var fullscreenEnabled = document.fullscreenEnabled || document.mozFullScreenEnabled ||

                        document.webkitFullscreenEnabled || document.msFullscreenEnabled;

if(fullscreenEnabled){

  full.onclick = function(){

    var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement ||

                            document.webkitFullscreenElement;    //查找是否有处于全屏状态的节点

    if(!fullscreenElement){

      launchFullscreen(full);

    }else{

      exitFullscreen();

    }

  }

}

function launchFullscreen(elem){              //使某一个节点全屏显示

  if(elem.requestFullscreen){

    elem.requestFullscreen();

  }else if(elem.mozRequestFullScreen){

    elem.mozRequestFullScreen();

  }else if(elem.msRequestFullscreen){

    elem.msRequestFullscreen();

  }else if(elem.webkitRequestFullscreen){

    elem.webkitRequestFullScreen();

  }

}

function exitFullscreen(){              //取消全屏

  if(document.exitFullscreen){

    document.exitFullscreen();

  }else if(document.msExitFullscreen){

    document.msExitFullscreen();

  }else if(document.mozCancelFullScreen){

    document.mozCancelFullScreen();

  }else if(document.webkitExitFullscreen){

    document.webkitExitFullscreen();

  }

}

注意: 放大一个节点时:

Firefox自动将该元素放大至全屏状态,width:100%; height:100%

Chrome则是将该节点放在屏幕的中央,保持原来大小,其他部分变黑

UC浏览器会旋转屏幕

#full:-webkit-full-screen{        全屏时应用的样式

  width: 80%;

  height: 80%;

}

#full:-moz-full-screen{}

#full:-ms-fullscreen{}

#full:fullscreen{}

_______________________________________________________________________________________________

visibilitychange事件: 浏览器标签页被隐藏或显示的时候会触发,隐藏时记录时间戳,显示时记录时间戳,求二者之差/1000得到离开时间(秒)

若是倒计时的话可以判断visibilityState == 'visible'里面重新获取时间戳,重启倒计时

var Visibility={ start:0, end:0, s:0 };

document.addEventListener('webkitvisibilitychange', function(){

  if(document.webkitVisibilityState == 'hidden'){

    Visibility.start = new Date().getTime();

  }else{                                      //visibilityState == 'visible'

    Visibility.end = new Date().getTime();

    Visibility.s = ((Visibility.end-Visibility.start)/1000);    //离开时间: 单位为秒

  }

});

document.addEventListener('mozvisibilitychange', function(){

  if(document.mozVisibilityState == 'hidden'){

    Visibility.start = new Date().getTime();

  }else{

    Visibility.end = new Date().getTime();

    Visibility.s = ((Visibility.end-Visibility.start)/1000);

  }

})

_______________________________________________________________________________________________

防止遮罩层下面的内容滑动(滚动穿透):

① 弹出遮罩层后, 动态设置 body{overflow: hidden;}

②在'touchstart'事件中:e.preventDefault();   //除IE外的浏览器

                        e.returnValue=false;     //IE系列

document.addEventListener("touchstart", function(e){    //或者使用'touchmove'也可以

  if($(".mask").length>0 && $(".mask").css("display")!="none"){

   e.preventDefault();                             //当显示遮罩层时,禁止滑动

  }

}, {passive: false});

③ 设置 body{position: fixed;}  但滚动条的位置会丢失,需要保存滚动条位置,关闭时还原滚动位置

  scrollTop = (window.pageYOffset||document.documentElement.scrollTop)-(document.documentElement.clientTop||0);              //打开时保存页面卷去的高度

  document.body.style.position = "fixed";             //设置为固定定位

  document.body.style.top = -scrollTop + 'px';        //设置top为 '-页面卷去的高度'

  document.scrollingElement.scrollTop = scrollTop;    //关闭时再还原页面卷去的高度

当显示遮罩层上的文字与遮罩层元素平级时:

if($(".mask_toast").css("display")!="none"){          //判断遮罩层是否已经显示

  $(".mask_toast").css("margin-top",parseInt($(".mask_toast").css("margin-top"))+scrollTop);

}        //设置提示文字的margin-top为原来的margin-top加上页面卷去的高

触摸遮罩层的灰色层,隐藏遮罩层

document.addEventListener("touchstart", function(e){

  if($(".mask").css("display") != "none" && $(e.target).is(".mask")){

    $(".mask").hide();

   e.preventDefault();        //阻止后续触发 click事件、a链接

  }

}, { passive: false });

注意: 从chrome56开始,在window、document和body上注册的touchstart和touchmove事件处理函数,会默认为是passive:true。浏览器忽略preventDefault()可以立即滚动,提高滚动效果

如: window.addEventListener('touchmove', fn)

    window.addEventListener('touchmove', fn, { passive: true })

这两句的效果一样

如果在window、document、body的touchstart和touchmove事件处理函数中调用e.preventDefault(),会被浏览器忽略掉,并不会阻止默认行为

解决方案: 2个

① 注册处理函数时,明确声明不是被动的

window.addEventListener('touchmove', fn, {passive: false})

② 应用CSS属性 touch-action:none; 这样任何触摸事件都不会产生默认行为,但是touch事件照样触发

________________________________________________________________________________________________

移动端和PC端判断手指(鼠标)的滑动方向及距离

反弹效果: 在元素距离边界为0时,根据滑动距离修改元素的transform:translateY(Y),并在touchend时还原状态

移动端:

$(".demo").on("touchstart", function(e){

  e.preventDefault();

  startX = e.originalEvent.changedTouches[0].pageX,    //jQuery中的API,zepto中没有

  startY = e.originalEvent.changedTouches[0].pageY;    //jQuery中的API

});

$(".demo").on("touchmove", function(e){

  e.preventDefault();

  moveEndX = e.originalEvent.changedTouches[0].pageX,

  moveEndY = e.originalEvent.changedTouches[0].pageY,

  X = moveEndX - startX,

  Y = moveEndY - startY,

  absX = Math.abs(X),

  absY = Math.abs(Y);

  if( absX > absY){

    if( X > 0 ){

      console.log("从左向右");

    }else{

      console.log("从右向左");

    }

  }else if( absX < absY){

    if( Y > 0 ){

      console.log("从上向下");

    }else{

      console.log("从下向上");

    }

  }else{

    console.log("没有滑动");

  }

});

原生写法:

var touch = { startX:0, startY:0, moveEndX:0, moveEndY:0,

              X:0, Y:0, absX:0, absY:0, endX:0, endY:0 };

document.body.addEventListener("touchstart", function(e){

  touch.startX = e.touches[0].pageX;

 touch.startY = e.touches[0].pageY;

});

document.body.addEventListener("touchmove", function(e){

 touch.moveEndX = e.touches[0].pageX;

 touch.moveEndY= e.touches[0].pageY;

 touch.X =touch.moveEndX -touch.startX;

 touch.Y =touch.moveEndY -touch.startY;

 touch.absX = Math.abs(touch.X);

 touch.absY = Math.abs(touch.Y);

  if(touch.absX > touch.absY){              //可设置touch.absX>300时,触发转换事件

    if(touch.X > 0 ){

      console.log("从左向右");

    }else if(touch.X < 0){

      console.log("从右向左");

    }

  }else if(touch.absX < touch.absY){        //可设置touch.absY>300时,触发转换事件

    if(touch.Y > 0){

      console.log("从上向下");

    }else if(touch.Y < 0){

      console.log("从下向上");

    }

  }else{

    console.log("没有滑动");

  }

});

document.body.addEventListener("touchend", function(e){

 touch.endX = e.changedTouches[0].pageX;

 touch.endY = e.changedTouches[0].pageY;

  console.log('滑动结束:',touch.endX,touch.endY);

});

PC端:

$(".demo").mousedown(function(e){

  e.preventDefault();

  startX = e.pageX;

  startY = e.pageY;

  $(this).mousemove(function(e){

    e.preventDefault();

    moveEndX = e.pageX;

    moveEndY = e.pageY;

    X = moveEndX - startX;

    Y = moveEndY - startY;

    absX = Math.abs(X),

    absY = Math.abs(Y);

  if( absX > absY){

    if( X > 0 ){

      console.log("从左向右");

    }else{

      console.log("从右向左");

    }

  }else if( absX < absY){

    if( Y > 0 ){

      console.log("从上向下");

    }else{

      console.log("从下向上");

    }

  }else{

    console.log("没有滑动");

  }

  })

}).mouseup(function(){

  $(this).off("mousemove")

})

下拉刷新

.container{

  position: relative;

}

.scroll{

  width: 100%;

  margin-top: 0;

  position: absolute;

  top: 0;

  left: 0;

  height: 500px;

  background-color: #DDD;

}

<div class="container">

下拉刷新

var scroll = document.querySelector('.scroll');

var container = document.querySelector('.container');

var touchStart = 0;

container.addEventListener('touchstart', function(event){

  touchStart = event.targetTouches[0].pageY;

}, {passive: false});

container.addEventListener('touchmove', function(event){

  var touch = event.targetTouches[0];

  console.log(touch.pageY - touchStart);

  scroll.style.top = scroll.offsetTop + touch.pageY - touchStart + 'px';

  touchStart = touch.pageY;

}, {passive: false});

container.addEventListener('touchend', function(){

  touchStart = 0;

  var top = scroll.offsetTop;

  if(top > 70){

    console.log('下拉刷新');

  }

  if(top > 0){

    scroll.style.transition = 'all 0.3s ease-in-out';

    scroll.style.top = '0px';

    setTimeout(function(){

      scroll.style.transition = 'none';

    }, 300)

  }

}, {passive: false});

_______________________________________________________________________________________________

微信浏览器如果按系统的返回按钮,页面会被缓存,但是js文件没有重新调用(各项数值不会修改),可调用pageshow事件来解决

e.addeventListener('pageshow', function(e){

  e.persisted && fn();    //fn:返回页面后需要运行的函数

})

_______________________________________________________________________________________________

复制内容

document.execCommand()方法: 可以允许运行命令来操作可编辑区域的内容

bool = document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)

方法返回一个Boolean值,表示操作是否成功

① aCommandName: 表示命令名称,比如:copy、cut、print等

② aShowDefaultUI: 是否展示用户界面,一般是false

③ aValueArgument: 有些命令需要额外的参数,一般用不到

<input type="text" id="copyInput" value="想要复制的内容"readonly/>    //只读,防止拉起键盘

function copy(){

  var input = document.querySelector('#copyInput');

 input.select();

  input.setSelectionRange(0, 9999);    //input.select()在ios下没有选中全部内容

                                       //用 input.setSelectionRange(0, input.value.length)解决

  var boolean =document.execCommand('copy');

  console.log(boolean)

}

https://clipboardjs.com/              //参考插件

复制的内容进行换行:

① 把input换成textarea,input无法输入换行,可换成多行文本textarea

② 将换行符 <br> 使用 \r\n 代替

_______________________________________________________________________________________________

window.location.href = "weixin://"    //从网页打开微信客户端

从网页跳转到微信内的某个页面:

if(/baiduboxapp/i.test(navigator.userAgent)){

window.location.replace("bdbox://utils?action=sendIntent&minver=7.4&params=%7B%22intent%22%3A%22weixin://dl/business/?ticket=???%23Intent%3Bend%22%7D");

}else{

window.location.replace("weixin://dl/business/?ticket=???");

}

weixin:// 是微信客户端注册的scheme url,用来在浏览器里唤起微信客户端

dl/business 是一种消息类型实际上就是跳到了: weixin://dl/business/?ticket=(微信URL Schemes)#wechat_redirect

ticket: 该值是由微信后端产生32位的HASH值(时间戳+URL随机生成),属于URL临时票据信息,在微信服务器上会与真实URL的进行绑定,所以微信可以通过这个值能跳到真实地址,该值有时效性,并非一直不变,要不断请求接口获取该值才能正常访问(需要与微信合作,才能获取此ticket)

在京东做活动时,会有漏洞,可以通过京东跳转到指定页面,某些平台会出售此漏洞

_______________________________________________________________________________________________

键盘访问网站的常用操作:

①Tab键索引控件元素

  可按次序不断:focus控件元素,包括链接(带href属性)、按钮、输入框等表单元素或设置了tabindex的普通元素(也可以设置tabindex为某个数字,修改Tab显示的顺序)

②Enter键触发当前元素处于 :focus 状态的点击行为

  按下Enter键,相当于鼠标点击了这个元素,从而触发相应效果

  <input type="checkbox" id="che"/> 可使用空格键修改状态

③ 上下键上下滚动网页

④ Space空格键滚动一屏网页(当前没有:focus checkbox时)

⑤ Home键返回顶部

⑥ End键滚动到底部

注意:

① 对于<form>表单元素,若里面有type="submit"类型的按钮,则浏览器天然支持单行输入框的回车提交行为(当前:focus链接时),否则,若没有<form>元素,也没有原生的提交按钮,则Enter不会触发任何默认行为

例: <input id="btn" type="submit"> <label class="btn" for="btn">提交</label>

    用<label>替代提交按钮,实现Enter提交表单行为,并修改提交按钮的样式

或者使用a标签代替submit,使用ajax提交

<form>

  ...

  <a href="javascript:void(0)" class="login">登录</a>

  <input type="submit" style="display: none"/>

</form>

$('.login, input[type=submit]').click(function(e){

  e.preventDefault();        //阻止默认提交

  ...

});

_______________________________________________________________________________________________

阻止Safari浏览器自带的弹簧滚动特效

方法①

window.addEventListener('touchmove', function(e){    //阻止外层window的tocuch事件

  e.preventDefault();

}, {passive: false});

document.querySelector('body').addEventListener('touchmove', function(e){  //只允许部分touch

  e.stopPropagation();

}, false)

方法②

body{ overscroll-behavior:none; }    //允许控制浏览器的滑动溢出行为,当到达滚动区域的边界时会发生的行为

________________________________________________________________________________________________

ios中,定位在底部的输入框获得焦点时,输入框被覆盖,无法显示

原因: input获得焦点后,fixed失效

方案一、

Web API接口: 使用scrollIntoView,将input输入框显示在可视区域

inputOnFocus(e){            //输入框获得焦点时,元素移动到可视区域

  setTimeout(function(){    //延时: 键盘弹起需要时间

    e.target.scrollIntoView(true);    //true: 元素的顶端将和其所在滚动区的可视区域的顶端对齐

                                      //false: 底端对齐

  }, 200)

}

方案二、不使用fixed将元素固定在底部

<div class="main">

  <section></section>

  <footer> <input type="text" /> </footer>

</div>

.main{ position:relative; height:100% }

section{ box-sizing:border-box; height:100%; padding-bottom:4rem;

         overflow-y:scroll; -webkit-overflow-scrolling:touch    //此属性可使滚动流畅 }

footer{ position:absolute; height:4rem; overflow:hidden; left:0; right:0; bottom:0 }

解决input输入框在ios中无法输入,光标不出现:

-webkit-user-select: text;

user-select: text;

在聚焦到输入框时,使当前元素出现到指定位置,避免光标错位:

e.target.scrollIntoView(true)

e.target.scrollIntoViewIfNeeded()

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容