_______________________________________________________________________________________________
十二、手機(jī)震動(dòng)
navigator.vibrate = navigator.vibrate || navigator.webkitVibrate?|| navigator.mozVibrate ||
? ? ? ? ? ? ? ? ? ? navigator.msVibrate;
if(navigator.vibrate){ ? ? ? ? ? ? ? ? ?? // 判斷設(shè)備是否支持震動(dòng)
? var shock = document.getElementById("shock");
? shock.onclick = function(){
? ? navigator.vibrate(50); ? ? ? ? ? ? ?? //震動(dòng)1次: ?震動(dòng)毫秒數(shù)
? ? navigator.vibrate([5000,3000,1000]);? //震動(dòng)多次: 奇位數(shù)是震動(dòng)毫秒數(shù),偶位數(shù)是震動(dòng)停止毫秒數(shù)
? ? navigator.vibrate(0); ? ? ? ? ? ? ? ? //停止震動(dòng): 傳入0或空數(shù)組
? };
}
注意:?對(duì)navigator.vibrate方法的調(diào)用并不會(huì)引起手機(jī)循環(huán)振動(dòng),當(dāng)將參數(shù)中需要震動(dòng)的時(shí)間進(jìn)行完畢后,就會(huì)停止震動(dòng)
_______________________________________________________________________________________________
十三、手機(jī)搖動(dòng)
if(window.DeviceMotionEvent){ ? ? ? ? ? ? ? ?//判斷手機(jī)是否支持搖一搖
? 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){ ? ?//當(dāng)搖動(dòng)距離大于限定距離時(shí)
? ? ? //搖動(dòng)時(shí)發(fā)生的事件
? ? }
? ? lastX = x;
? ? lastY = y;
? }, false);
}
_______________________________________________________________________________________________
十四、全屏顯示
var full = document.getElementById("full");
? ? ? ? ? ? ? ? ? ? ? ? //判斷是否支持切換到全屏狀態(tài)
var fullscreenEnabled = document.fullscreenEnabled || document.mozFullScreenEnabled ||
? ? ? ? ? ? ? ? ? ? ? ? document.webkitFullscreenEnabled || document.msFullscreenEnabled;
if(fullscreenEnabled){
? full.onclick = function(){
? ? var fullscreenElement = document.fullscreenElement || document.mozFullScreenElement ||
? ? ? ? ? ? ? ? ? ? ? ? ? ? document.webkitFullscreenElement; ?? //查找是否有處于全屏狀態(tài)的節(jié)點(diǎn)
? ? if(!fullscreenElement){
? ? ? launchFullscreen(full);
? ? }else{
? ? ? exitFullscreen();
? ? }
? }
}
function launchFullscreen(elem){ ? ? ? ? ? ?? //使某一個(gè)節(jié)點(diǎn)全屏顯示
? 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();
? }
}
注意: 放大一個(gè)節(jié)點(diǎn)時(shí):
Firefox自動(dòng)將該元素放大至全屏狀態(tài),width:100%; height:100%
Chrome則是將該節(jié)點(diǎn)放在屏幕的中央,保持原來大小,其他部分變黑
UC瀏覽器會(huì)旋轉(zhuǎn)屏幕
#full:-webkit-full-screen{ ? ? ?? 全屏?xí)r應(yīng)用的樣式
? width: 80%;
? height: 80%;
}
#full:-moz-full-screen{}
#full:-ms-fullscreen{}
#full:fullscreen{}
_______________________________________________________________________________________________
visibilitychange事件: 瀏覽器標(biāo)簽頁被隱藏或顯示的時(shí)候會(huì)觸發(fā),隱藏時(shí)記錄時(shí)間戳,顯示時(shí)記錄時(shí)間戳,求二者之差/1000得到離開時(shí)間(秒)
若是倒計(jì)時(shí)的話可以判斷visibilityState == 'visible'里面重新獲取時(shí)間戳,重啟倒計(jì)時(shí)
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); ?? //離開時(shí)間: 單位為秒
? }
});
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);
? }
})
_______________________________________________________________________________________________
防止遮罩層下面的內(nèi)容滑動(dòng)(滾動(dòng)穿透):
① 彈出遮罩層后, 動(dòng)態(tài)設(shè)置 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();? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//當(dāng)顯示遮罩層時(shí),禁止滑動(dòng)
? }
}, {passive: false});
③ 設(shè)置 body{position: fixed;}? 但滾動(dòng)條的位置會(huì)丟失,需要保存滾動(dòng)條位置,關(guān)閉時(shí)還原滾動(dòng)位置
? scrollTop = (window.pageYOffset||document.documentElement.scrollTop)-(document.documentElement.clientTop||0); ? ? ? ? ? ?? //打開時(shí)保存頁面卷去的高度
? document.body.style.position = "fixed"; ? ? ? ? ? ? //設(shè)置為固定定位
? document.body.style.top = -scrollTop + 'px'; ? ? ? ?//設(shè)置top為 '-頁面卷去的高度'
? document.scrollingElement.scrollTop = scrollTop; ? ?//關(guān)閉時(shí)再還原頁面卷去的高度
當(dāng)顯示遮罩層上的文字與遮罩層元素平級(jí)時(shí):
if($(".mask_toast").css("display")!="none"){ ? ? ? ? ?//判斷遮罩層是否已經(jīng)顯示
? $(".mask_toast").css("margin-top",parseInt($(".mask_toast").css("margin-top"))+scrollTop);
} ? ? ?? //設(shè)置提示文字的margin-top為原來的margin-top加上頁面卷去的高
觸摸遮罩層的灰色層,隱藏遮罩層
document.addEventListener("touchstart", function(e){
? if($(".mask").css("display") != "none" && $(e.target).is(".mask")){
? ? $(".mask").hide();
? ?e.preventDefault();? ? ? ? //阻止后續(xù)觸發(fā) click事件、a鏈接
? }
},?{ passive: false });
注意: 從chrome56開始,在window、document和body上注冊(cè)的touchstart和touchmove事件處理函數(shù),會(huì)默認(rèn)為是passive:true。瀏覽器忽略preventDefault()可以立即滾動(dòng),提高滾動(dòng)效果
如: window.addEventListener('touchmove', fn)
? ? window.addEventListener('touchmove', fn, { passive: true })
這兩句的效果一樣
如果在window、document、body的touchstart和touchmove事件處理函數(shù)中調(diào)用e.preventDefault(),會(huì)被瀏覽器忽略掉,并不會(huì)阻止默認(rèn)行為
解決方案: 2個(gè)
① 注冊(cè)處理函數(shù)時(shí),明確聲明不是被動(dòng)的
window.addEventListener('touchmove', fn, {passive: false})
② 應(yīng)用CSS屬性 touch-action:none; 這樣任何觸摸事件都不會(huì)產(chǎn)生默認(rèn)行為,但是touch事件照樣觸發(fā)
________________________________________________________________________________________________
移動(dòng)端和PC端判斷手指(鼠標(biāo))的滑動(dòng)方向及距離
反彈效果:?在元素距離邊界為0時(shí),根據(jù)滑動(dòng)距離修改元素的transform:translateY(Y),并在touchend時(shí)還原狀態(tài)
移動(dòng)端:
$(".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("沒有滑動(dòng)");
? }
});
原生寫法:
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){? ? ? ? ? ? ? //可設(shè)置touch.absX>300時(shí),觸發(fā)轉(zhuǎn)換事件
? ? if(touch.X > 0 ){
? ? ? console.log("從左向右");
? ? }else if(touch.X < 0){
? ? ? console.log("從右向左");
? ? }
? }else if(touch.absX <?touch.absY){? ? ? ? //可設(shè)置touch.absY>300時(shí),觸發(fā)轉(zhuǎn)換事件
? ? if(touch.Y > 0){
? ? ? console.log("從上向下");
? ? }else if(touch.Y < 0){
? ? ? console.log("從下向上");
? ? }
? }else{
? ? console.log("沒有滑動(dòng)");
? }
});
document.body.addEventListener("touchend", function(e){
?touch.endX = e.changedTouches[0].pageX;
?touch.endY = e.changedTouches[0].pageY;
? console.log('滑動(dòng)結(jié)束:',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("沒有滑動(dòng)");
? }
? })
}).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});
_______________________________________________________________________________________________
微信瀏覽器如果按系統(tǒng)的返回按鈕,頁面會(huì)被緩存,但是js文件沒有重新調(diào)用(各項(xiàng)數(shù)值不會(huì)修改),可調(diào)用pageshow事件來解決
e.addeventListener('pageshow', function(e){
? e.persisted && fn();? ? //fn:返回頁面后需要運(yùn)行的函數(shù)
})
_______________________________________________________________________________________________
復(fù)制內(nèi)容
document.execCommand()方法: 可以允許運(yùn)行命令來操作可編輯區(qū)域的內(nèi)容
bool = document.execCommand(aCommandName, aShowDefaultUI, aValueArgument)
方法返回一個(gè)Boolean值,表示操作是否成功
① aCommandName: 表示命令名稱,比如:copy、cut、print等
② aShowDefaultUI: 是否展示用戶界面,一般是false
③ aValueArgument: 有些命令需要額外的參數(shù),一般用不到
<input type="text" id="copyInput" value="想要復(fù)制的內(nèi)容"readonly/>? ? //只讀,防止拉起鍵盤
function copy(){
? var input = document.querySelector('#copyInput');
?input.select();
? input.setSelectionRange(0, 9999);? ? //input.select()在ios下沒有選中全部內(nèi)容
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//用 input.setSelectionRange(0, input.value.length)解決
? var boolean =document.execCommand('copy');
? console.log(boolean)
}
https://clipboardjs.com/? ? ? ? ? ? ? //參考插件
復(fù)制的內(nèi)容進(jìn)行換行:
① 把input換成textarea,input無法輸入換行,可換成多行文本textarea
② 將換行符 <br> 使用 \r\n 代替
_______________________________________________________________________________________________
window.location.href = "weixin://"????//從網(wǎng)頁打開微信客戶端
從網(wǎng)頁跳轉(zhuǎn)到微信內(nèi)的某個(gè)頁面:
if(/baiduboxapp/i.test(navigator.userAgent)){
window.location.replace("bdbox://utils?action=sendIntent&minver=7.4¶ms=%7B%22intent%22%3A%22weixin://dl/business/?ticket=???%23Intent%3Bend%22%7D");
}else{
window.location.replace("weixin://dl/business/?ticket=???");
}
weixin:// 是微信客戶端注冊(cè)的scheme url,用來在瀏覽器里喚起微信客戶端
dl/business 是一種消息類型實(shí)際上就是跳到了: weixin://dl/business/?ticket=(微信URL Schemes)#wechat_redirect
ticket: 該值是由微信后端產(chǎn)生32位的HASH值(時(shí)間戳+URL隨機(jī)生成),屬于URL臨時(shí)票據(jù)信息,在微信服務(wù)器上會(huì)與真實(shí)URL的進(jìn)行綁定,所以微信可以通過這個(gè)值能跳到真實(shí)地址,該值有時(shí)效性,并非一直不變,要不斷請(qǐng)求接口獲取該值才能正常訪問(需要與微信合作,才能獲取此ticket)
在京東做活動(dòng)時(shí),會(huì)有漏洞,可以通過京東跳轉(zhuǎn)到指定頁面,某些平臺(tái)會(huì)出售此漏洞
_______________________________________________________________________________________________
鍵盤訪問網(wǎng)站的常用操作:
①Tab鍵索引控件元素
? 可按次序不斷:focus控件元素,包括鏈接(帶href屬性)、按鈕、輸入框等表單元素或設(shè)置了tabindex的普通元素(也可以設(shè)置tabindex為某個(gè)數(shù)字,修改Tab顯示的順序)
②Enter鍵觸發(fā)當(dāng)前元素處于 :focus?狀態(tài)的點(diǎn)擊行為
? 按下Enter鍵,相當(dāng)于鼠標(biāo)點(diǎn)擊了這個(gè)元素,從而觸發(fā)相應(yīng)效果
? <input type="checkbox" id="che"/> 可使用空格鍵修改狀態(tài)
③?上下鍵上下滾動(dòng)網(wǎng)頁
④ Space空格鍵滾動(dòng)一屏網(wǎng)頁(當(dāng)前沒有:focus checkbox時(shí))
⑤ Home鍵返回頂部
⑥ End鍵滾動(dòng)到底部
注意:
① 對(duì)于<form>表單元素,若里面有type="submit"類型的按鈕,則瀏覽器天然支持單行輸入框的回車提交行為(當(dāng)前:focus鏈接時(shí)),否則,若沒有<form>元素,也沒有原生的提交按鈕,則Enter不會(huì)觸發(fā)任何默認(rèn)行為
例: <input id="btn" type="submit"> <label class="btn" for="btn">提交</label>
? ? 用<label>替代提交按鈕,實(shí)現(xiàn)Enter提交表單行為,并修改提交按鈕的樣式
或者使用a標(biāo)簽代替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();? ? ? ? //阻止默認(rèn)提交
? ...
});
_______________________________________________________________________________________________
阻止Safari瀏覽器自帶的彈簧滾動(dòng)特效
方法①
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; }? ? //允許控制瀏覽器的滑動(dòng)溢出行為,當(dāng)?shù)竭_(dá)滾動(dòng)區(qū)域的邊界時(shí)會(huì)發(fā)生的行為
________________________________________________________________________________________________
ios中,定位在底部的輸入框獲得焦點(diǎn)時(shí),輸入框被覆蓋,無法顯示
原因:?input獲得焦點(diǎn)后,fixed失效
方案一、
Web API接口:?使用scrollIntoView,將input輸入框顯示在可視區(qū)域
inputOnFocus(e){? ? ? ? ? ? //輸入框獲得焦點(diǎn)時(shí),元素移動(dòng)到可視區(qū)域
? setTimeout(function(){? ? //延時(shí):?鍵盤彈起需要時(shí)間
? ? e.target.scrollIntoView(true);? ? //true:?元素的頂端將和其所在滾動(dòng)區(qū)的可視區(qū)域的頂端對(duì)齊
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //false:?底端對(duì)齊
? }, 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? ? //此屬性可使?jié)L動(dòng)流暢 }
footer{ position:absolute; height:4rem; overflow:hidden; left:0; right:0; bottom:0 }
解決input輸入框在ios中無法輸入,光標(biāo)不出現(xiàn):
-webkit-user-select:?text;
user-select:?text;
在聚焦到輸入框時(shí),使當(dāng)前元素出現(xiàn)到指定位置,避免光標(biāo)錯(cuò)位:
e.target.scrollIntoView(true)
e.target.scrollIntoViewIfNeeded()