移動(dòng)端2

_______________________________________________________________________________________________

十二、手機(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&params=%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()

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容