title: javascript雜記
date: 2017-05-21 14:34:25
tags: javascript筆記
this的基本用法
首先有一個函數(shù)
function fn1(){
alert(this);
}
直接調(diào)用則this指向window
fn1(); // 指向window;
如果是被元素對象調(diào)用
div.onclick = function(){
var _this = this; // 這個this指的就是div元素對象
fn1(); // 這里打印的this值的就是window,因為上面fn1函數(shù)的環(huán)境就是在全局,所以如果直接調(diào)用函數(shù)剩愧,那么this都是window
}
div.onclick = fn1; // 這里打印的this就是div元素對象行嗤,這里已經(jīng)改變了fn1函數(shù)的環(huán)境冠息,賦值給了div元素對象的事件屬性中弄喘,環(huán)境自然也從全局變?yōu)閐iv元素對象君旦。
判斷瀏覽器名稱
function myBrowser(){
var userAgent = navigator.userAgent; //取得瀏覽器的userAgent字符串
if (userAgent.indexOf("Opera") > -1) { //判斷是否Opera瀏覽器
return "Opera"
};
if (userAgent.indexOf("Firefox") > -1) { //判斷是否Firefox瀏覽器
return "FF";
};
if (userAgent.indexOf("Chrome") > -1){ //判斷是否Chrome瀏覽器
return "Chrome";
}
if (userAgent.indexOf("Safari") > -1) { //判斷是否Safari瀏覽器
return "Safari";
}
if (userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1) { //判斷是否IE瀏覽器
return "IE";
};
}
火狐瀏覽器禁止頁面滾動
if (navigator.userAgent.toLowerCase().indexOf('firefox')>=0){
if (e.preventDefault)
e.preventDefault();
e.returnValue = false;
}
鼠標滾輪事件
非FireFox瀏覽器是使用onmousewheel事件江场,而FireFox瀏覽器使用DOMMouseScroll事件纺酸。
非FireFox瀏覽器使用的是wheelDelta方法判斷滾動方向,F(xiàn)ireFox瀏覽器使用的是detail方法判斷滾動方向址否。
wheelDelta:-120和detail:3 代表向下滾動餐蔬。wheelDelta:120和detail:-3代表向上滾動。
document.body.onmousewheel = function(event) {
event = event || window.event;
console.log(event.wheelDelta)
};
document.body.addEventListener("DOMMouseScroll", function(event) {
console.log(event.detail)
});
jquery兼容性的滾輪事件
$('#scrollSelect-view').on("mousewheel DOMMouseScroll", function (e) {
var delta = (e.originalEvent.wheelDelta && (e.originalEvent.wheelDelta > 0 ? 1 : -1)) || // chrome & ie
(e.originalEvent.detail && (e.originalEvent.detail > 0 ? -1 : 1)); // firefox
if (delta > 0) {
// 向上滾
console.log("wheelup");
} else if (delta < 0) {
// 向下滾
console.log("wheeldown");
}
});
自定義屬性
有時候?qū)懛椒〞r會定義大量變量佑附,有的變量其實比較多余樊诺,很多數(shù)據(jù)可以存儲到元素對象的自定義屬性中去。這樣不用去考慮作用域的問題音同,因為只要這個元素對象存在在這個方法內(nèi)就可以去使用词爬,但是最好只保存和這個元素對象有關(guān)的屬性。
比如:下面代碼就是权均,在事件處理函數(shù)內(nèi)部只能獲取i循環(huán)完畢之后的值顿膨,而通過把i的值作為元素對象的自定義屬性賦值,就沒有作用域的限制叽赊。
for(var i = 0; i < 5; i++) {
div.index = i;
div[i].onclick = function(){
alert(i);
alert(this.index);
}
}
排他思想和清空上一個
排他
通常在tab欄切換中經(jīng)常用到排他虽惭,比如有10個選項,只有當前項才有背景色蛇尚,通常顏色是通過一個類名掛鉤到css中去設(shè)置的芽唇,那么排他就是每次先將所有導航選項的類名清空,然后只給當前點擊的這個元素對象添加類名。
for(var i = 0;i < Lis.length;i++){
Lis[i].index = i;
Lis[i].onclick = function(){
// 這里開始排他
for(var i = 0; i < Lis.length;i++){
Lis[i].className = '';
}
// 單獨設(shè)置當前選項
Lis[this.index].className = 'active';
};
};
清空上一個
這種效果除了排他之外還可以通過清除上一個選項來完成匆笤。創(chuàng)建一個變量存儲上一個選中元素研侣,在點擊當前元素時候清空上一個類名,之后把自己賦值給這個變量炮捧,如此每次只需要清空一個元素的類名即可庶诡。
var oElem = null;
// 初始化,默認第一個元素是當前項
Lis[0].className = 'active';
Elem = Lis[0];
for(var i = 0;i < Lis.length;i++){
Lis[i].index = i;
Lis[i].onclick = function(){
// 這里開始清空上一個
Elem.className = '';
Elem = this;
Lis[this.index].className = 'active';
};
};
jquery的stop()方法
$(selector).stop(stopAll,goToEnd)
stopAll 可選咆课。規(guī)定是否停止被選元素的所有加入隊列的動畫末誓。
goToEnd 可選。規(guī)定是否允許完成當前的動畫书蚪。該參數(shù)只能在設(shè)置了 stopAll 參數(shù)時使用喇澡。
使用懶加載插件
使用的 jquery.lazyload
調(diào)用下載好的插件
$(function(){
$("img.imglazyload").lazyload({
threshold : 200,
effect : "fadeIn"
});
});
html部分,一定要在外層包一個div并且設(shè)置寬高殊校,不要用圖片去撐開晴玖。
<div class="item-image">
<img class="imglazyload" data-original="圖片地址">
</div>
js中的NaN
- NaN是一個數(shù)字類型但不是一個數(shù)值。
- 出現(xiàn)NaN肯定是進行了非法操作而不是獲取數(shù)值有錯为流,如果獲取數(shù)值有錯是undefind呕屎。
- NaN與自己本身也是不相等的。
- NaN轉(zhuǎn)為布爾是false敬察。
- NaN本身的意思是'不是一個數(shù)值'
isNaN可以判斷某些類型是不是一個數(shù)字類型秀睛。如果判斷到是一個數(shù)字為false(不是一個數(shù)值這個判定是錯的),而不是數(shù)字類型的是true(不是一個數(shù)值這個判定是對的)莲祸。
NaN在判斷時是在內(nèi)部使用Number()方法轉(zhuǎn)換蹂安,所以是不是數(shù)字類型的依據(jù)主要是看Number()轉(zhuǎn)出的是什么類型。比如布爾值虫给、空字符串藤抡、字符串數(shù)字都會被認為是數(shù)字類型而返回false侠碧。
js的作用域基礎(chǔ)
作用域?qū)嶋H上是瀏覽器js解析器的一種工作方式抹估。
瀏覽器的js解析器在讀取javascript代碼時會先提升變量和函數(shù),再去逐行解讀代碼弄兜。這是每個作用域的解析步驟药蜻。
預解析
根據(jù)var、function替饿、參數(shù) 找一些東西语泽。
首先js解析器會搜索所有var和function找到所有變量,var聲明的變量提升時值都是未定義视卢,提升function時候會將整個函數(shù)代碼塊一起提升踱卵。
當var和function重名時,會保留function,覆蓋var,但是如果兩個以上同名的function惋砂,那么就看聲明的先后順序了妒挎。
逐行解析
變量提升之后,js解析器會開始逐行解析代碼西饵,這時只有表達式可以改變變量的值酝掩,用下邊的案例來說明。
alert(a); // function a(){alert(4);}
var a = 1;
alert(a); // 1
function a(){alert(2);}
alert(a); // 1
var a = 3;
alert(a) // 3
function a(){alert(4);}
alert(a); // 3
a(); // 報錯
第一個alert打印出函數(shù)的原因是變量提升的規(guī)則眷柔,后面的a打印的都是變量的值而不是函數(shù)期虾,因為變量賦值是一種表達式,而函數(shù)只是一個聲明并不是表達式驯嘱。并且因為現(xiàn)在a是一個數(shù)值镶苞,所以調(diào)用時自然會報錯。
多組script
自上而下的作用域大部分指的是多組script標簽宙拉,如下代碼
<script>
alert(a); // 報錯
</script>
<script>
var a = 1;
</script>
<script>
alert(a); // 1
</script>
/
如果碰到這種情況宾尚,js解析器會對每個script代碼塊進行獨立預解析和逐行解析,第一塊script的代碼還沒聲明a谢澈,第二塊script的代碼聲明和賦值了煌贴,這時到第三塊script代碼塊時a已經(jīng)聲明并賦值了,所以直接會打印1锥忿。
函數(shù)
由內(nèi)而外主要指函數(shù)牛郑,一個函數(shù)也是一個單獨的作用域,javascript中敬鬓,函數(shù)是唯一能分隔作用域的淹朋。
var a = 1;
function fn1(){
alert(a);
var a = 2;
}
fn1(); // undefined
alert(a); // 1
var a = 1;
function fn1(){
alert(a);
a = 2;
}
fn1(); // 1
alert(a); // 2
第一個例子中在函數(shù)內(nèi)部聲明了a,那么在fn1中的a變量就和上級作用域的a變量沒有任何關(guān)系了钉答。按照預解析的步驟這里打印的是undefined础芍。
第二個例子沒有聲明a變量,所以在fn1作用域中就找不到a数尿,這時就會去上級作用域中尋找仑性,上級作用域聲明了a并且賦值為1了,所以打印1右蹦。
如果是下面這種情況
var a = 1;
function fn1(a){
alert(a);
a = 2;
}
fn1(); // undefined
alert(a); // 1
var a = 1;
function fn1(a){
alert(a);
a = 2;
}
fn1(a); // 1
alert(a); // 2
參數(shù)其實就是一個局部變量诊杆,第一個例子沒有傳參,參數(shù)就相當于var a; 第二個例子傳了參數(shù)就相當于var a = 1;
一個函數(shù)的解析順序是先從參數(shù)開始的何陆。
下面看一個最常見的案例
for(var i = 0; i < 3; i++){
btn[i].onclick = function(){
alert(i); // 3
}
}
最開始我以為這里打印的i是會隨著遍歷打印出0,1,2的晨汹,但實際上onclick函數(shù)中相當于一個獨立的作用域,這個作用域中沒有聲明i變量贷盲,所以就要去上級作用域去獲取淘这,那為什么是3呢,因為函數(shù)只有在點擊時才會調(diào)用,只有調(diào)用時才會發(fā)生預解析和逐步解析铝穷,這時去獲取i的值上級作用域早已遍歷完畢朦乏。
js運算符%取余的應用
下面的例子中要在li元素中添加背景色,顏色存儲在arr數(shù)組氧骤。如果不用取余運算符只能寫兩層for循環(huán)呻疹,而使用取余運算,可以直接讓取余后的值自己循環(huán)筹陵。
arr的長度是3刽锤,i是0開始每次+1,那么arr數(shù)組每次的索引就是:arr[0%3=0],arr[1%3=1],arr[2%3=2],arr[3%3=0],arr[4%3=1],arr[5%3=2],arr[6%3=0]
朦佩,這樣就達到了遍歷顏色數(shù)組的目的并思。這種操作很適合于在一個數(shù)組的遍歷內(nèi)部又需要遍歷另外一個數(shù)組的情況。
var li = document.getElementsByTagName('li');
var arr = ['yellow','pink','orange'];
for(var i = 0; i < li.length; i++){
li[i].style.backgroundColor = arr[i%arr.length];
}
下面擴展一下這個案例语稠,加上任意li元素點擊后變色宋彼,再去點擊另一個li,另一個li元素變色仙畦,上一個li元素變回原來的顏色输涕。通常這種功能會用排他來做,這次不用排他慨畸,使用取余操作來寫莱坎。
var li = document.getElementsByTagName('li');
var arr = ['yellow','pink','orange'];
var elem = null;
for(var i = 0; i < li.length; i++){
li[i].index = i;
li[i].style.backgroundColor = arr[i%arr.length];
li[i].onclick = function(){
if(elem){
elem.style.backgroundColor = arr[elem.index%arr.length];
}
elem = this;
this.style.backgroundColor = 'gray';
}
}
排他是將所有l(wèi)i元素變色,再去更改當前點擊的元素的背景色寸士,而這種思路是記錄上一次點擊的元素檐什,在下一次點擊時只改變上一次點擊的元素的背景色就可以了。這里elem.index和i的作用是相同的弱卡。
另外取余操作還可以換算時間乃正,比如現(xiàn)在要將70秒轉(zhuǎn)為分鐘,那么可以這樣寫
var s = 70;
var m = Math.floor( 70/60 + '分' + 70%60 + '秒');
js獲取瀏覽器計算后的屬性值
像width或者height這種屬性直接獲取只能得到行內(nèi)樣式婶博,如果不寫在行內(nèi)就獲取不到瓮具,使用getComputerStyle可以獲取瀏覽器計算后的樣式,也就是被瀏覽器渲染之后得到的元素實際的屬性的值凡蜻。格式是getComputerStyle(element).width;
但是這個方法在ie6搭综、7垢箕、8不兼容划栓。這三個非標準瀏覽器使用的currentStyle屬性。格式是element.currentStyle.width;
条获。
不要用這兩個方法去獲取沒有設(shè)置過的屬性忠荞。
不能用這兩個屬性去獲取復合樣式,比如要獲取背景色不要用background而是要用backgroundColor,不論css是怎么寫的委煤,都要寫具體的屬性堂油。因為如果寫background的話會獲取到所有這個屬性可以設(shè)置的屬性值,如果css沒寫的會獲取到默認的碧绞。
另外在firefox瀏覽器4.0版本之前府框,getComputerStyle的參數(shù)要寫兩個,第二個參數(shù)可以隨便寫比如getComputerStyle(element,'').width;
或getComputerStyle(element,true).width;
讥邻,總之只要寫一個參數(shù)就可以迫靖。
jq中的即使搜索事件
在jq中實現(xiàn)input搜索框的即時搜索和其他即時性的改變需要用到input和propertychange(兼容ie8及以下瀏覽器)事件。
input是標準的瀏覽器事件兴使,一般應用于input元素系宜,當input的value發(fā)生變化就會發(fā)生,無論是鍵盤輸入還是鼠標黏貼的改變都能及時監(jiān)聽到變化发魄。
propertychange只要當前對象屬性發(fā)生改變都會觸發(fā)盹牧,所以使用propertychange時最好排除一下不想觸發(fā)事件的元素。
window.parent
在b.html頁面使用iframe的時候励幼,引入一個Html頁面名稱暫定為a.html汰寓,呢么在a.html中,window指的是a的window對象苹粟,而window.parent指的就是b.html的window對象踩寇。
監(jiān)聽DOM樹加載完成的事件
DOM的加載順序:
解析HTML結(jié)構(gòu)。
加載外部腳本和樣式表文件六水。
解析并執(zhí)行腳本代碼俺孙。
構(gòu)造HTML DOM模型。
加載圖片等外部文件掷贾。
頁面加載完畢
DOMContentLoaded
事件 可以在DOM模型加載完成后就執(zhí)行代碼睛榄,而不用等到加載完圖片或外部文件
移動端獲取屏幕的寬高
document.documentElement.clientWidth
和 document.documentElement.clientHeight
這個得到的是設(shè)備像素可見寬高,比如iPhone 5里為320和504想帅。