一邊學習前端,一邊通過部落格的形式自己總結一些東西,當然也希望幫助一些和我一樣開始學前端的小夥伴。
如果出現錯誤,請在評論中指出,我也好自己糾正自己的錯誤
author: thomaszhou
- 目錄
- [1. 基本語法]
- [2. 排序sort()預設和自定義]
- [3. js一些簡單提高效能例項]
- [4. this的理解和應用]
- [5. 點選事件的除錯錯誤]
- [6. js可以為所有標籤新增任何自定義屬性]
- [7. 資料型別和型別轉換]
- [8. 函式傳參(未完成)]
- [9. 作用域]
- [10. 定時器]
- [11. 日期物件]
- [12. 字串方法]
- [13. 陣列方法]
- json,物件
基本語法-1
- javascript分別提供內建函式 parseInt()和parseFloat(),轉換為數字 注:如果被轉換的字串,同時又數字和字元構成,那麼parseInt會一直定位數字,直到出現非字元。 所以"10abc" 會被轉換為 10
- 使用內建函式Boolean() 轉換為Boolean值 當轉換字串時:非空即為true 當轉換數字時:非0即為true 當轉換物件時:非null即為true
- Number和parseInt一樣,都可以用來進行數字的轉換 區別在於,當轉換的內容包含非數字的時候,Number() 會返回NaN(Not a Number) parseInt() 要看情況,如果以數字開頭,就會返回開頭的合法數字部分,如果以非數字開頭,則返回NaN
- getElementsByTagName和getElementsById區別!
- 返回值不同:getElementsByTagName是選擇標籤的型別。返回的是一個一堆的標籤,也就是一個集合(不是陣列,但是擁有和陣列一樣的方法).getElementsById返回的是一個標籤
var oLi = oDiv.getElementsByTagName('li'); //oLi其實是一個集合 for(var i = 0; i < arrUrl.length; i++) { // 如果oLi[i]後的 事件 或者 屬性 是確定的,可以用.來寫 oLi[i].index = i; oLi[i].onclick = fn1; 重要!!!!!!!!!!!!! // 如果通過函式引數來改變oLi[i]的事件 或者 屬性,就用oLi[i][evt]來寫,例如evt就是引數, //oLi[i]的點選事件還可以如下寫: // var evt = onclick; // oLi[i][evt] = fn1; } 複製程式碼
- 寫法不同:getElementsById只能寫成document.getElementsById,但是getElementsByTagName前面不止可以寫ducument還可以寫別的,如下:
(1) var oUl = document.getElementsByTagName('ul')[0]; /*如何用getElementsByTagName來找一個標籤,就加個[0]*/ var oli = oUl.document.getElementsByTagName('li'); /*選擇的是ul標籤下的所有li標籤*/ (2) 如果查詢的標籤只有一個,可以用id,class,也可以用TagName, 但是如果用TagName就要加上一個[0] var oImag = oDiv.getElementsByTagName('img')[0]; 複製程式碼
- 靜態方法和動態方法: getElementsByTagName是動態方法:即使前面寫了語句獲取某個型別標籤返回為0,只要後面有新增該型別標籤,就可以直接訪問,不需要再來一次查詢。 但是getElementsById如果前面返回值為0,後面如何新增了,也需要再次重複操作一次查詢才可以
aSpan[i].style.left
是修改left值,如果遇到要將整個樣式進行修改,也就是新寫一個樣式,將之前通過js對標籤style進行修改的那些樣式的全部進行一個替換,可以考慮用aSpan[i].style.cssText
(記住:是將js操作修改的樣式全部替換成一個新的,標籤本身通過css設定的樣式不變)- 陣列:中可以包含不同的資料型別: 例如:數子、字串、陣列、路徑(例如存放圖片地址)等 7.函式:函式的引數如果是字串,就像是一個字串陣列
function fn1(args) {
console.log(args[0]);
console.log(typeof args[0]);//string
}
fn1('qwe');//q
fn1(234);//undefined ----typeof undefined也是undefined
複製程式碼
排序sort()預設和自定義-2
- sort()預設升序,但是隻適用於0~9,因為:
var array1 = [0,1,5,10,15];
  array1.sort();//結果為:0,1,10,15,5---->完全不符合
複製程式碼
原因:是這個函式在進行排序的過程影響其值的根本原因。(其實,在使用sort()進行排序的時候會呼叫toString()函式將其值轉換成字串在進行比較,是按ASCII進行比較的)
解決方法:自定義sort()
compare(a,b)返回的值小於0:那麼a就小於b,也就是說a排在了b的前面
compare(a,b)返回的值大於0: 那麼a就大於b,也就是說a排在了b的後面
compare(a,b)返回的值等於0:那麼a就等於b,也就是說a和b的位置保持不變
var Array1 = [0,1,5,10,15];
Array1.sort(function(a,b){return b-a;});
結果是:15,10,5,1,0
複製程式碼
解釋:a,b表示陣列中的任意兩個元素,若return > 0 b前a後;reutrn < 0 a前b後;a=b時存在瀏覽器相容,簡化一下:a-b輸出從小到大排序,b-a輸出從大到小排序。
var arr1 = [0,19,5,10,15],//數字
arr2 = ['500', '70', '9'];//數字形式的字串
arr3 = [500, '70', '9'];//數字和數字形式的字串混合
function compare(a, b) {
return a-b;
// return (a < b)? -1: (a > b)? 1: 0;
//利用相減的方法,可以對字串形式的數字和純數字都有效,而不需要專程純數字在比較!!!!!
}
console.log(arr1.sort());//[0, 10, 15, 19, 5]
console.log(arr1.sort(compare));//[0, 5, 10, 15, 19]
console.log(arr1.sort(compare)[1]);//5
console.log(arr2.sort());//["500", "70", "9"]
console.log(arr2.sort(compare));//["9", "70", "500"]
console.log(arr3.sort());//[500, "70", "9"]
console.log(arr3.sort(compare));//["9", "70", 500]
//得出,對於數字和數字型別的字串,用了compare函式都是按照數字的大小排序!!!!!!
複製程式碼
- 針對(單個屬性)的物件陣列排序
var obj1 = [
{'name': 'john', 'age': 13},
{'name': 'aohn', 'age': 93},
{'name': 'bohn', 'age': 53}
],
obj2 = [//age的值改為字元形式
{'name': 'john', 'age': '13'},
{'name': 'aohn', 'age': '93'},
{'name': 'bohn', 'age': '53'}
]
//物件陣列排列
function objectSort(args) {
var sortOrder = 1;
if (args[0] === '-') {
sortOrder = -1;
args = args.substr(1);
console.log(args);
}
return function (a, b) {
var result = a[args] - b[args];
return result * sortOrder;
}
}
console.log(obj1.sort(objectSort('age')));
console.log(obj2.sort(objectSort('age')));//結果一樣
//正序:正序和逆序同時顯示就出錯,只有當只有一個的時候就沒問題???
console.log(obj1.sort(objectSort('-age')));
//逆序:正序和逆序同時顯示就出錯,只有當只有一個的時候就沒問題???
複製程式碼
- 針對(多個屬性)的物件陣列排序
<script>
var obj1 = [
{'name': 'john', 'age': '13'},
{'name': 'aohn', 'age': '93'},
{'name': 'john', 'age': '93'},
{'name': 'bohn', 'age': '53'}
]
function objectSortMuti() {//應對物件陣列的多個屬性排序
var props = arguments;
return function (obj1, obj2) {
var i = 0,
result = 0,
numberOfProperties = props.length;
while(result === 0 && i < numberOfProperties) {
//呼叫單個屬性排序的函式objectSort()
result = objectSort(props[i])(obj1, obj2);
i++;
}
return result;
}
}
console.log(obj1.sort(objectSortMuti('name','age')));
// {name: "john", age: "13"}
// {name: "bohn", age: "53"}
// {name: "aohn", age: "93"}
// {name: "john", age: "93"}
</script>
複製程式碼
- 利用sort將陣列內的元素弄成隨機排列
// 數字陣列隨機排列:讓陣列的數字大小隨機排列
function randomSort(a, b) {
return Math.random() - 0.5//因為預設random是0~1,減去0.5就是-0.5~0.5,正負為一半概率
}
console.log(arr1.sort(randomSort));// ["blue", "hum", "zelu"]預設就是字串排序
複製程式碼
效能方面-3:
例1
for(var i = 0; i < arr.length ; i++)
/*裡面的arr.length會每次迴圈都計算一次長度,這樣影響效能!*/
修改為: var num = arr.length;
for(var i = 0; i < num ; i++)
複製程式碼
例2
for( var i=0; i<6000; i++ ){
document.body.innerHTML += '<input type="button" value="按鈕" />';
/*每次迴圈都需要dom一次,效能不好*/
}
/*解決方法:設定一個字串str,將每次的操作都作用在str上,等迴圈結束,一次性全部加在document.body.innerHTML中*/
var str = '';
for( var i=0; i<6000; i++ ){
str += '<input type="button" value="按鈕" />';}
}
document.body.innerHTML = str;
複製程式碼
例3 下面程式碼的點選事件執行點選都會生成4個div,但是每次點選都會生成4個,如何限制按鈕的功能只保證第一次有效
var arr1 = ['qwe','qwe','sdf','qwe'];
for(var i = 0; i < arr1.length;i++){
document.body.innerHTML += '<div>'+arr1[i]+'</div>';
/*如果是 = ,那就是修改,如果是 += ,那就是不斷相加*/
}
方法:寫一個判斷(建立變數onoff,初始為true,點選事件結束後賦值為false,此時通過if判斷無法執行 點選事件)
var arr1 = ['qwe','qwe','sdf','qwe'];
oBtn1.onclick = function(){
onoff = true;
if(onoff){
for(var i = 0; i < arr1.length;i++){
document.body.innerHTML += '<div>'+arr1[i]+'</div>'; }
onoff=false;}
}
複製程式碼
- 注:標籤的背景屬性是不可以用===來判斷的,因為背景後面跟著顏色(多種表達方式)、url等等。一般牽扯到判斷,儘量用變數 如何實現多個div的背景圖片的點選事件(點選一次換一張圖片,再點選一次,恢復原來的圖片),通過變數判斷每個點選事件(點選一次後)
this的理解和應用-4
this 指的是呼叫當前方法(函式)的那個物件
- 判斷this的指向
- 直接在中寫一個alert(this);這個this是window
- 只要見到單獨的fn1(),那麼this就是window。這個this表達的是window不是obtn1,因為是windw呼叫的,不是oBtn1呼叫的
舉例: function fn1(){alert(this);}
// 只要見到單獨的fn1(),那麼this就是window,但是如果是oBtn1.onclick = fn1;
//那麼this指的就是oBtn1(誰呼叫的函式,this就指向誰!)
eg1: fn1(); this ---> window
eg2: oBtn1.onclick = fn1; this -----> oBtn1
eg3: oBtn1.onclick = function(){
fn1(); } this ---> window
複製程式碼
題外話!(點選事件的函式賦值為什麼不能oBtn1.onclick = fn1(),這樣寫為什麼是錯的❌?)
- this應用:
//this ---> aBtn 的三種寫法
//第一種
var aBtn = document.getElementsByTagName('input');
for(var i = 0;i < aBtn.length;i++){
aBtn[i].onclick = function() {
this.style.background = 'red';
}
}
//第二種
var aBtn = document.getElementsByTagName('input');
that = null;
for(var i = 0;i < aBtn.length;i++){
aBtn[i].onclick = function() {
that = this;
fn1();
}
}
function fn1(){
that.style.background = 'red';
}
//第三種
var aBtn = document.getElementsByTagName('input');
for(var i = 0;i < aBtn.length;i++) {
aBtn[i].onclick = fn1;
}
function fn1(){
this.style.background = 'red';
}
複製程式碼
點選事件的除錯錯誤-5
var aBtn = document.getElementsByTagName('input');
for(var i = 0;i < aBtn.length;i++){
aBtn[i].onclick = function(){
that = this;
fn1();
}
/*由於下一句程式碼呆滯程式出錯,載入頁面沒有出錯,但是點選時出錯,且錯誤定位在209行,
不需要用alert()除錯錯誤.錯誤只發生在點選後,也就是說是函式點選事件錯誤或者是呼叫點選事件時發生錯誤,
本例子是下一句發生錯誤,也就是呼叫點選事件的時候發生錯誤,多次定義同一點選事件!*/
// aBtn[i].onclick = fn1; ❌的源頭
}
function fn1(){
that.style.background = '#2a426c';
}
複製程式碼
js可以為所有標籤新增任何自定義屬性-6
- 例子1:建立3個li標籤,每個li的背景圖都是一張圖片,即共三個圖片,每個圖片都寫一個點選事件(點選一次變一下背景圖片,再點一下就回去前一張圖):
document.body.innerHTML = '<ul> <li></li> <li></li> <li></li> </ul>'; // 三個li是存放圖片
var aLi = document.getElementsByTagName('li');
for(var i = 0;i < aLi.length; i++){
aLi[i].style.cssText = 'margin:0;list-style:none;background:url(1.jpg);float:left;width:100px;height:100px;margin-right:10px;'
}
var onoff = true; // 方法一:利用變數的true和false來判斷,點選第一次的時候onoff置false,
//然後通過if else就可以執行else語句
for(var i = 0; i < aLi.length; i++){
aLi[i].onclick = function(){
if(onoff){
//aLi[i].style.background = 'url(2.jpg)';這樣寫是錯的❌
this.style.background = 'url(2.jpg)';
onoff = false;
} else{
this.style.background = 'url(1.jpg)';
onoff=true;
}} }
複製程式碼
方法一的問題:由於是多個圖片並行新增點選事件,而onoff是全域性變數,如果點選第一個li的圖片1,圖片變成2,然後再點選第二個li的圖片1,此時是執行else語句(圖片變成1),但是問題在於此時第二個li的圖片就是1,所以點選事件在使用者看起來是失靈的!每次換一個li點選,都需要點選兩次才可以生效,這就是問題
方法二:同樣是利用判斷,但是,不是利用一個全域性變數,而是利用每個li的自定義屬性onOff。每次置為true和false都是對當前li的自定義屬性onOff屬性操作,這樣就不會影響到其他的 li 標籤,每個onOff都是僅針對對應的標籤
注:
- 給一些標籤陣列設定自定義屬性的時候,會用到for迴圈,但是給標籤陣列設定自定義函式的語句要在for迴圈的開頭寫好,例如下面第二句程式碼
aLi[i].onOff = true;
如果寫在了按鈕事件裡面,就會出錯!(因為寫在裡面的話,如果不做一些類似閉包等操作,i的值不是從0-->aLi.length-1,而是總是length-1) - 該方法是通過自定義建立一個僅屬於某個標籤的屬性,但是如果目前的程式碼中有通過自定義屬性來操作的一些別的功能,我們最好把該屬性拿來判斷,因為如果有現成可以用的,那就用現成的,如果沒有,才去創造一個新的
for(var i = 0; i < aLi.length; i++){
aLi[i].onOff = true; //設定自定義屬性onOff
aLi[i].onclick = function(){
if(this.onOff){
this.style.background = 'url(2.jpg)';
this.onOff = false;
}
else{
this.style.background = 'url(1.jpg)';
this.onOff=true; }} }
複製程式碼
-
自定義屬性---設定索引值index(適用於想建立“匹配”,“對應”關係)
-
例子2:還是三個li,點選每個li時,點選多次依次為A、B、C、D,然後迴圈,三個li各自獨立完成功能
實現方法:建立一個陣列
var arr = ['A','B','C','D']
,然後為每個li標籤設定一個自定義屬性num,初始都為0,在不超過陣列arr
的長度,每次點選都num++
以及將li的value值或者innerHTML置為arr[num]
-
例子三:三個button,三個p標籤,一個包含字串的陣列,點選button,通過索引值將陣列對應的值,對應的對p標籤作出value的修改(利用自定義屬性建立--索引)
陣列也可以包含字串,圖片,路徑等等
-
資料型別和型別轉換-7
- 任何非空的資料型別,都可以新增自定義屬性和自定義方法
- 可以通過
typeof
判斷資料型別,例如:typeof n判斷n的資料型別 - js的資料型別:數字,字串,布林,函式,物件(obj、[]、{}、null),undefine
- 從html上獲取到的值,innerHTML和一些屬性,都是字串!!!!!!!!
- 顯式型別轉換:
- Number()函式:轉化為數字,出現空一般情況下轉為0(除json外),如果遇到字母或者符號,obj型別,json,undefine直接就是NaN
var a = '100'; var b = '000100'; var c = '----100'; var d = ''; 以及 var d = null; var e = 'true'; var f = function(){var a = 777};//轉換函式 var g = ['4'];//一個值 var h = [1,3,5];//多個值 var i = json = {}; var j ;//undifine //Number(a):字串直接轉換為數字 alert(Number(a)+100);// 100+100 alert(Number(b));//100 alert(Number(c));//NaN 含有符號 alert(Number(d));//0 alert(Number(e));//true --> 1 false --> 0 alert(Number(f));//NaN alert(Number(g));//4 alert(Number(h));//NaN alert(Number(i));//json不論是空還是有東西,都是 NaN alert(Number(j));//NaN 複製程式碼
- parseInt()函式:原理是從第一個開始往後找,一旦遇到不是數字的(如果開頭是+或者—或者空格是可以的),立馬截斷,然後把之前讀到的數字轉換成int型數字。(注:適用於轉換一些數字開頭的字串,例如b)
- parseInt(a,10) 表示按照10進位制轉換,也可以是二進位制,十六進位制等等。
var a = 'a100'; var b = '100px'; var c = '000100'; var d = '+100'; var e = ' 100'; 以及 e = 00000100 var f = null; alert(parseInt(a,10));//NaN alert(parseInt(b,10));//100 alert(parseInt(c,10));//100 alert(parseInt(d,10));//100 認識'+ - = ' 分別是 100 -100 100 alert(parseInt(e,10));//100 空格 和 0 自動忽略 alert(parseInt(f,10));//NaN 複製程式碼
- parseInt()和parseFloat()的區別
var a = '12.34fff'; var b = '12.3.4'; alert(parseInt(a));//12 alert(parseFloat(a));//12.34 alert(parseFloat(b));//12.3 只認識第一個小數點 複製程式碼
//兩個轉換的值相等,就可以判斷為整數
if(parseInt(a) == parseFloat(a)){
alert('a是小數');
}else{
alert('a是整數');
}
6. **隱式型別轉換**
隱式型別轉換:
+ 200 + '3' 變成字串 '2003'
- * / % '200' - 3 變成數字 197
++ -- '2'++ 變成數字 3
> < 數字的比較是一個數字和一個字串,那就是預設數子進行比較alert( 10000000 > '9' ); 、
字串的比較 alert( '10000000' > '9' );
! 取反 !'asd' true 把右邊的任何資料型別轉成布林值
== alert('2' == 2) true 只是判斷值
(=== 是判斷 資料型別 和 值 都必須相同)
```
複製程式碼
- 轉換失敗的時候返回NaN。有4個特點:
- NaN在bool型中是 false
- NaN一定是出現非法操作
- NaN是一個數字型別(number),但是它不是一個數字
- 除NaN以外,所有的資料型別的值都是等於本身
- isNaN() 判斷某些值是不是數字:
- 是數字,就是false不是數子,就是true**
- isNaN()內部是通過number()函式來判斷是不是數字!
var arr = [ '100px', 'abc'-6, [], -98765, 34, -2, 0, '300', ,
function(){alert(1);}, null,document, [], true, '200px'-30,'23.45元',
5, Number('abc'), function(){ alert(3); }, 'xyz'-90 ];
/*
1、找到arr裡所有的數字:-98765, 34, -2, 0, 5
*/
for(var i = 0; i < arr.length; i++){
//方法一:把所有數字都找出來
if((typeof arr[i] != 'string')&&(parseFloat(arr[i]) == arr[i])){
console.log(arr[i]);
}
//方法二:判斷是數字,而不是NaN
if((typeof arr[i] === 'number')&&(arr[i] === arr[i]))
}
複製程式碼
- charAt(i)把字串的字元單獨拿出來
str = '123';
str.charAt(2);//3
複製程式碼
作用域-9
瀏覽器:
“JS解析器過程”
1) JS 的預解析:“找一些東西” :僅 var和function
所有的變數,在正式執行程式碼之前,都提前賦了一個值:未定義
所有的函式,在正式執行程式碼之前,都是整個函式塊
注:遇到重名的:只留一個(變數和函式重名了,就只留下函式),
多函式的話,函式留最後的那個!
2)逐行解讀程式碼:
表示式:= + - * / % ++ -- ! 引數……
表示式可以修改預解析的值!
注:script 全域性變數、全域性函式
自上而下
<script>var a =1 ;</script>
<script>alert(a)</script> ===> 1
是可以執行的,因為自上而下,上面的東西會存進倉庫然後杯使用和讀取,
就像一開頭會用script引用一些js檔案一樣
複製程式碼
var a = 1;
function fn1(){
alert(a); // 1
//(作用域鏈,裡面找不到var和函式,就跳到父級,然後找到a=1,所以返回1(由裡到外))
a = 2; //找不到a,然後又是作用域鏈往外面爬,遇到a = 1;然後a =2是將全域性a賦值為2
}
fn1();
alert(a); // 2
預處理結果為:a = undefined fn1 = function fn1{...}
逐行解讀:如上註釋
注:
1. 函式內部找不到變數的宣告,就會跳出來找同名的全域性變數,如果也沒有才會報錯!!!!(由裡到外),
;但是外面不能直接用區域性變數(函式內)
** 想要獲取函式內的值---解決辦法:
方法一:
宣告一個全域性變數,再函式中的區域性變數賦值給全域性變數
var str = '';
function fn1(){
var a = '大雞腿~';
str = a;}
方法二:申明另一個函式,利用引數來傳遞區域性變數
function fn2(){
var a = '9999999克拉鑽石23456789';
fn3(a);}
fn2();
function fn3(a){
alert(a);}
複製程式碼
例子1:
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
alert( typeof a ); //number
a();報錯,因為此時a是變數不是函式
解析過程:
“JS解析器過程”
1)JS 的預解析:
===> 讀取到var a = 1 ==> a = undefined
===> a = function a(){ alert(2); }
===> 讀取到var a = 3 ==> a = undefined
===> a = function a (){ alert(4); }
===> 只留函式,函式留最後的那個
所以預解析的結果是:a = function a (){ alert(4); }
注:遇到重名的:只留一個(變數和函式重名了,就只留下函式)
2)逐行解讀程式碼:
由於預解析得出a = function a (){ alert(4); }
按順序讀,第一個alert(a);是返回一個函式,預處理的結果!
複製程式碼
例子2:
var a = 1;
function fn1(){
alert(a); // undefined
var a = 2;
}
fn1();
alert(a); // 1
解析過程:
“JS解析器過程”
1)JS 的預解析:
===> 讀取到var a = 1 ==> a = undefined
===> fn1 = function fn1(){ alert(a); var a = 2;}
===> 只留函式
所以預解析的結果是:fn1 = function fn1(){ alert(a); var a = 2;}
2)逐行解讀程式碼:
解析結果為表示式
函式呼叫:
1)函式內部預解析(和外部預解析一樣!)
alert(a); ==> null
var a = 2; ==> a=undefined
2)逐行解讀程式碼
alert(a) ==> undefined
alert(a); ==> a是全域性變數a,不是區域性的a,所以是a
複製程式碼
例子3:
var a = 1;
function fn1(a){
引數就相當於一個區域性變數,就相當於var a;,
但是沒有賦值,所以內部js解析器是讀取到a=undefine;
alert(a); // undefined
a = 2;
}
fn1(); 下面是fn1(a);
alert(a); // 1
例子4:
var a = 1;
function fn1(a){
alert(a); // 1
a = 2;
}
fn1(a);
alert(a); // 1
複製程式碼
-
定時器-10
- 函式的返回值
return:返回值
- return可以返回的型別有:數字、字串、布林、函式、物件(元素[陣列]{}\null)、未定義
- 函式名+括號:fn1() ==> return 後面的值;
- 所有函式預設返回值:未定義;
- return 後面任何程式碼都不執行了;
a、返回物件 alert(fn2()); ----> 顯示整個function(b){}(包括註釋) function fn2(){ return function (b){ alert(a+b); // 嘿嘿,我是註釋~ };} a、返回物件 fn3().onload = function (){ document.body.innerHTML = 123; }; function fn3(){ return window;} b、通過雙括號來呼叫 函式 內的 函式 fn2(20)(10); function fn2(a){ return function (b){ alert(a+b); // 嘿嘿,我是註釋~ };} 複製程式碼
- 函式的return小應用
模仿jquery,封裝一個 $方法 function $( v ){ if( typeof v === 'function' ){ --> 如果v是函式 window.onload = v; } else if ( typeof v === 'string' ) { --> 如果v是字串 return document.getElementById(v); } else if ( typeof v === 'object' ) { --> 如果v是一個物件,例如this return v; }} $(function(){ --> 直接用$()方法 $('btn1').onclick = function(){ $( this ).style.background = 'yellow'; };}); 複製程式碼
- argument
fn1( 1,2,3 ); // 實參——實際傳遞的引數 // function fn1( a,b,c ){ // 形參——形式上,abc這些名代表123 function fn1(){ //arguments => [ 1,2,3 ] —— 實參的集合 alert( arguments ); -->[ 1,2,3 ] alert( arguments.length ); -->3 alert( arguments[arguments.length-1] );像陣列一樣,通過[]來定位引數} !!! 當函式的引數個數無法確定的時候:用 arguments 如下: // alert( sum( 1,2,3 ) ); // 6 // alert( sum( 1,2,3,4 ) ); // 10 function sum (){ var n = 0; for( var i=0; i<arguments.length; i++ ){ n += arguments[i]; } return n;} 複製程式碼
- 獲取元素樣式:要注意三點
-
獲取到的是計算機(瀏覽器)計算後的樣式
-
background: url() red …… 複合樣式(不要獲取)
backgroundColor 單一樣式(不要用來做判斷)
-
不要獲取未設定後的樣式:不相容
-
注:該$方法是上個return小應用裡面的自定義方法
- 函式的返回值
return:返回值
alert( getComputedStyle( $('div1') ).width ); IE6 7 8 不相容
alert( $('div1').currentStyle.width ); 標準瀏覽器不相容
例子1:對於以上兩個方法的使用,最好用if-else來多方位考慮
if( $('div1').currentStyle ){ //當為標準瀏覽器時
alert( $('div1').currentStyle.width );
} else { //當為ie 6 7 8時
alert( getComputedStyle( $('div1')).width );
// alert( getComputedStyle( $('div1'),1).width ); FF 4.0 之前要加一個引數,任何數字都可以,此處為1
}
例子2:自定義獲取元素的屬性方法getStyle方便以後呼叫
function getStyle(obj,attr){
return obj.currentStyle?obj.currentStyle[attr]:getComputedStyle(obj)[attr];
}
呼叫方法:
var div2 = document.getElementById('div1')
getStyle(div2,'left'))
如果要獲取右外邊距,不要寫成 getStyle( div2, 'margin-right' ) );
正確寫法:alert( getStyle( div2, 'marginRight' ) );
複製程式碼
- 定時器
定時器:時間概念
var timer = setInterval( 函式, 毫秒 );
重複執行(發動機)
clearInterval( timer );
清除定時器
var timer = setTimeout( 函式, 毫秒 );
僅執行一次!!一些需要重複操作定時器的操作不要用!!!
clearTimeout( timer );
複製程式碼
注:for(var i=0; i<3; i++){ document.title = i; } -->瞬間i = 2
javascript的for迴圈瞬間完成,沒有時間根據
例子1:
功能:到i加到10自動停止
i = 0;
var timer = null;
function fn1(){
i++;
document.title = i;
if( i === 10 ){
clearInterval( timer );
}
}
timer = setInterval( fn1, 200 );
例子2:
功能:每秒切換一張圖片,迴圈顯示
var aBtn = document.getElementsByTagName('input');
var arrUrl = [ 'img/1.jpg', 'img/2.jpg', 'img/3.jpg', 'img/4.jpg' ];
var num = 0;
var timer = null;
var oBody = document.body;
aBtn[0].onclick = function (){
clearInterval( timer );
//必須先進行clearInterval(),才能按鈕的正常
// 如果不先清除,因為多次按第一個按鈕就會不斷的建立新timer(不會覆蓋之前的timer)
timer = setInterval(function(){
oBody.style.background = 'url('+ arrUrl[num] +')';
num++;
num %= arrUrl.length;
}, 1000);
};
aBtn[1].onclick = function (){
clearInterval( timer );
};
例子3:這種只需要操作一次定時器的操作,可以考慮用settimeout()
功能:2s後顯示一張圖片,然後3s後再消失
window.onload = function (){
var miaov = document.getElementById('miaov');
setTimeout( function(){
miaov.style.display = 'inline-block'; 2s後顯示
setTimeout(function(){ 巢狀兩個定時器,顯示後3s再消失
miaov.style.display = 'none';
}, 3000);
}, 2000);
};
例子4:類似滑鼠移到qq頭像,就會彈果,見《ex5定時器.html》
複製程式碼
- 回撥函式
功能:先右移到500,再往下移動到500
Abtn[3].onclick = function(){
move(Odiv,'left',12,500,function(){
move(Odiv,'top',12,500) ------>回撥函式
})
};
引數 obj:物件 attr:屬性
temp:步長 end:終點位置
回撥函式endFn,第5個引數
function move(obj,attr,temp,end,endFn){
//判斷步長是正還是負,也就是向前還是向後
temp = parseInt(getStyle(obj,attr))<end?temp:-temp;
clearInterval( obj.timer );//要對同一timer進行變化和操作
obj.timer = setInterval(function(){
// 判斷temp不能放在定時器內!因為定時器操作div的變化,每次變化temp都會變,
// 此處判斷temp正負是通過初始的left,而不是每時每刻的left值
// temp = parseInt(getStyle(obj,'left'))<end?temp:-temp;
var speed = parseInt(getStyle(obj,attr)) + temp ;
if((speed > end) && (temp>0) || (speed < end) &&(temp<0) ){
//判斷是往前還是往後,通過通過傳參的temp正負來判斷
speed = end;
}
obj.style[attr]= speed + 'px';
if ( speed == end ) { //可加不可加
clearInterval( obj.timer );
// 待left操作結束再執行回撥函式,所以放在這個if語句中
endFn && endFn();
// 等同於如下語句
/*如果endFn引數不為空,就呼叫回撥函式
if ( endFn ) {
endFn();
}
*/
}
},30);
}
複製程式碼
日期物件-11
- 系統時間
var mytime = new Date();//獲取系統當前時間
- 然後通過一些方法獲取年,月,日,星期,天,時分秒,
var iyear = mytime.getFullYear();//2017
var imonth = mytime.getMonth()+1;//得出來的比真實月份小1,所以要加1
var iday = mytime.getDate();//日
var iWeek = mytime.getDay();
var ihours = mytime.getHours();
// alert(ihours);
var imin = mytime.getMinutes();
var isec = mytime.getSeconds();
var str = '';
// 下面是日期的的一些對照
if( iWeek === 0 ) iWeek = '星期日';
if( iWeek === 1 ) iWeek = '星期一';
if( iWeek === 2 ) iWeek = '星期二';
if( iWeek === 3 ) iWeek = '星期三';
if( iWeek === 4 ) iWeek = '星期四';
if( iWeek === 5 ) iWeek = '星期五';
if( iWeek === 6 ) iWeek = '星期六';
str = iyear+'-'+imonth+'-'+iday+'-'+iWeek+'-'+ihours+':'+onTwo(imin)+':'+onTwo(isec);
alert(str)//2017-7-28-星期五-17:23:45
//設定時間:
oDate.setDate( oDate.getDate() + 5 );//將天數加5天
// toGMTString() 方法可根據格林威治時間 (GMT) 把 Date 物件轉換為字串,並返回結果。
alert( oDate.toGMTString());
注:為了更佳合理,如果是1:8:2的時間應該要變成01:08:02,自定義函式onTwo()
function onTwo ( n ) {
//返回的是一個字串
return n < 10 ? '0' + n : '' + n;
}
複製程式碼
例項1:圖片時鐘(通過修改img標籤的src)
<body>
<img src="img/0.JPG" />
<img src="img/0.JPG" />
<img src="img/0.JPG" />
<img src="img/0.JPG" />
<img src="img/0.JPG" />
<img src="img/0.JPG" />
<!--圖片為img的0~9的圖片,-->
<script>
setInterval(date,1000);
date();
// 圖片 時間顯示---------------------------------------------
function date(){
var Oimg = document.getElementsByTagName('img');
var mytime = new Date();
var ihours = mytime.getHours();
var imin = mytime.getMinutes();
var isec = mytime.getSeconds();
// 字串單純拼接
var str = onTwo(ihours)+onTwo(imin)+onTwo(isec);
for(var i = 0; i < str.length; i++)
{
Oimg[i].src = 'img/'+str.charAt(i)+'.jpg'
// alert(typeof(str.charAt(i)));//string
}
}
</script>
複製程式碼
- 倒數計時
// 現在的時間點(在變)
// 未來的時間點(不變)
var iNow = new Date();
//法一:數字形式獲取時間的毫秒形式
var iNew = new Date( 2017, 12, 23, 0,0,0 );//iNewh獲取的是毫秒為單位
// 毫秒 -> 秒(向下取整--去掉小數點)
var t = Math.floor((iNew - iNow)/1000);
//死公式-轉換成 天 時 分 秒 的單位,記住
// 天:Math.floor(t/86400)
// 時:Math.floor(t%86400/3600)
// 分:Math.floor(t%86400%3600/60)
// 秒:t%60
var str = Math.floor(t/86400)+'天'+Math.floor(t%86400/3600)+'時'+Math.floor(t%86400%3600/60)+'分'+t%60+'秒';
alert( str );
// 法二:數字形式:new Date( 2013,4,1,9,48,12 );
//如果要通過某個控制元件來獲取未來的時間,建議用字串形式,因為可以通過dom操作引入value值
// 字串形式:new Date('June 10,2013 12:12:12');
複製程式碼
例項2:設定一個未來時間,然後顯示倒數計時
<!--//如果要通過某個控制元件來獲取未來的時間,建議用字串形式,因為可以通過dom操作引入value值-->
距離:<input type="text" style="width: 200px;"value="November 27,2017 22:3:0"><br>
還剩:<input type="text"style="width: 200px;"><input type="button"value="開始倒數計時">
<script>
var Oinput = document.getElementsByTagName('input');
Oinput[2].onclick = retime;//點選事件
function retime(){
var timer = setInterval(function(){
var iNow = new Date();
var iEnd = new Date(Oinput[0].value);
var t = Math.floor((iEnd-iNow) / 1000);
var str = Math.floor(t/86400)+'天'+Math.floor(t%86400/3600)+
'時'+Math.floor(t%86400%3600/60)+'分'+t%60+'秒';
Oinput[1].value = str;
},1000);
</script>
複製程式碼
測試一個方法的用時
var startime = +new Date();//+new date() == new Date().valueof()返回當前毫秒數
//這裡放測試的程式碼
var endtime = +new Date();
console.log("耗時為"+(endtime - startime)+'ms');
複製程式碼
//+new Date() 中的+其實相當於.valueOf();
// 以下四句console程式碼都是可以返回當前時間的毫秒數
console.log(+new Date);//1512049475622
console.log(+new Date());// 1512049475622
var s = new Date();
console.log(s.valueOf());// 1512049475624
console.log(s.getTime());// 1512049475624
//以下是返回的字串形式
console.log(s.toLocaleString()); // 2017/11/30 下午9:44:35
console.log(s.toLocaleDateString()); // 2017/11/30
console.log(s.toLocaleTimeString()); // 下午9:44:35
複製程式碼
字串方法-12
(1)
字元長度
var str = 'aaaaa';
alert(str.length);
str.length = 1;//但是使其長度為1,無效
alert(str);//還是aaaaa
// 頭三個方法前面是接一個字串
//第三個方法的前面是接String
alert( 'miaov'.charAt(2) );//輸出:字串'miaov'第3個的字元
不能賦值給charAt()
alert( 'miaov'.charCodeAt(2) );//輸出字串'miaov'第3個的字元的ASC編碼
// String.fromCharCode()是可以通過編碼返回對應的字元
//這就彈出23383和23443的字元(用,來隔開,可以轉換多個)
alert( String.fromCharCode(22937, 21619) );//返回22937和 21619編碼對應的字元
複製程式碼
(2)
alert( str.indexOf('m') );//返回str中查詢第一個字元m的位置
// 如果第2個值為負數,預設當成0來處理
alert( str.indexOf('m', 5) );//從第五個位置開始,返回str中查詢第一個字元m的位置
var str = '字串';
var str1 = '字串 ';//空格也算字元長度
alert( str.length );//str--3 str1--5(含兩空格)
alert( str.charAt() );//找字串的某一個,什麼都不寫和charAt(0)就是預設第一個,
alert(str.charAt(0));
alert( str.charCodeAt() );// 返回字元的計算機儲存編碼,字的編碼是23383
alert( str.charCodeAt(1) ); //引數同charAt一樣
// 0~9 48~57 a~z 97~122 A~Z 65~90
alert( String.fromCharCode(23383, 23383) );//字字
複製程式碼
- substring()和slice()-擷取字串函式
var str = 'this is a bag';
str.substring(2);//從第2個位置開始擷取-is is a bag
alert( str.substring(0,2) );//擷取0-2位置的字元
// 兩個都是正數的情況:可以檢測兩個數大小,自動變成(0,2),就和上一行同等
alert( str.substring(2,0) );
alert( str.substring(-3, 2) ); // -3 當成0處理
alert( str.substring(2, -3) );
slice()擷取方法和substring()的區別:
alert( str.slice( 2, 0 ) ); // 不交換位置,但也沒有結果
alert( str.slice( -4, -2 ) ); // 負數從後面倒著往前數~
複製程式碼
(4)
字串比較:第一個字元的編碼大小,即charCodeAt()的值
alert( '莫濤' > '杜鵬' );//true
alert( 'abbbbb' > 'b' );//false
alert( '10000' > '2' );//false
大小寫轉換:
alert( str.toUpperCase() ); // 轉成大寫
alert( str.toLowerCase() ); // 轉成小寫
複製程式碼
- str.split()分割函式--可以把字串變成函式
var str = 'www.baidu.com';
//儲存的是一個陣列形式,然後就可以把arr當作陣列來處理(可用陣列的方法)
alert(str.split('.') ); // [ 'www', 'baidu', 'com' ]
var arr = str.split( '.' );
// alert( arr[1] );
var str1 = 'leo';
//如果不放置分割符,就是整個字元為一個陣列的元素
alert( typeof str1.split() ); // [ 'leo' ]
//如果只寫個空字元為分割符,那就是每個字元都分別分割
alert( str1.split('') ); // [ 'l', 'e', 'o' ]
var str2 = '百度網頁';
alert( str2.split('度') );//['百','網頁']
var str3 = '/www.baidu.com/';
alert( str3.split('/').length );//[ , www.baidu.com, ].第一個和第三個是空格
var str4 = '2013-11-29-23-07';
//-分割,且只保留前3段
alert( str4.split('-', 3) );//['2013','11','29']
複製程式碼
- indexOf(),lastIndexOf(),search(),concat()
var str = 'abcsssbc';
console.log(str.indexOf('bc',1));//1 第一次出現的字串的位置
console.log(str.indexOf('bc',2));//6 第二次出現的字串的位置
// 沒找到返回-1
console.log(str.lastIndexOf('bc'))//6 匹配的字串最後出現的位置
console.log(str.search(/bc/g));//返回於正規表示式查詢內容匹配的第一個字串的位置
console.log(str.concat('aa'));//abcsssbcaa str和字串aa進行拼接
複製程式碼
- join()拼接函式 ->str.join()是以()裡面的內容來拼接,相當於split的對立面
例子:替換段落中的某些文字
(html):
<p id="p1"><span>sadgergfsdfss阿斯頓設施的阿斯頓啊 啊實打實的爽膚水的方式水澱粉
水澱粉十大方式地方十大發生的法十大方式發的法十大法的身份 水澱粉是地方十大發生的 </span></p>
<div>替換文字</div>
<input type="text" value=""/>
<input type="text" />
<input type="button" value="替換" />
(js):
//替換字串裡面的指定字串!
// !!!!!如果這兩句話寫在外面,功能錯誤,為什麼?
// !!!!因為每次點選都要獲取案件的值,獲取控制元件的值是需要通過點選時間來操作的,而不是放在點選事件外
// var tar =aInp[6].value;
// var trans = aInp[7].value;
aInp[8].onclick = function(){
var tar =aInp[6].value;
var trans = aInp[7].value;
if (!tar)return;
op.innerHTML = op.innerHTML.split(tar).join(trans);
};
複製程式碼
trim()方法 已移除前導空格、尾隨空格和行終止符的原始字串。
var s = ' Hello ';
s.trim();
複製程式碼
陣列方法-13
- 標準的json格式{key:value}
var json = { name : 'leo', age : 32 };
alert( json.name );
var json2 = { name : 'miaov' };
//推薦寫成這個格式,key都用''圈住,對於增刪改查完全等同
var json2 = { 'name' : 'miaov' };
//訪問的兩種方式,js任何的.都可以用[]取代,只是格式要注意
alert( json2.name );//適用於上面兩種寫法
alert( json2['name'] );//適用於上面兩種寫法
//替換值-兩種方式
json2.name = '妙味';
json2['name'] = 'miaov';
複製程式碼
- json格式和陣列的形式可以互為結合
// { [], [], [] } [ {}, {}, {} ]
var arr = [ { 'name' : 'TM', 'age' : 23 }, { 'name' : 'leo', 'age' : 32 } ];
alert( arr[0].name + '今年有' + arr[1]['age'] );
var arrUrl = [ 'img/1.png', 'img/2.png', 'img/3.png', 'img/4.png' ];
var arrText = [ '小寵物', '圖片二', '圖片三', '面具' ];
//變成json格式
var imgData = {
url : [ 'img/1.png', 'img/2.png', 'img/3.png', 'img/4.png' ],
text : [ '小寵物', '圖片二', '圖片三', '面具' ]
};
alert( imgData.url[2] );
複製程式碼
- json格式的遍歷
- json只能用的遍歷for in 語法,因為json沒有長度length
- 陣列,兩種for迴圈都可以使用
var arr = [ 'a', 'b', 'c' ]; 第一種 for ( var i in arr ) { alert( arr[i] ); } 第二種 for (var i = 0;i < arr.length;i++){ console.log(arr[i]); } 複製程式碼
var json4 = { 'name' : 'thomas', 'age' : 3, 'fun' : '前端開發' };
for ( var attr in json4 ) {
alert( attr );//返回的是key--name,age,fun
alert( json4[attr] );//返回的是value--thomas,3,前端開發
}
//json和陣列混合的遍歷
//var json5 = { [], [], [] }
var json5 = {
'url' : [ 'img/1.png', 'img/2.png', 'img/3.png', 'img/4.png' ],
'text' : [ '小寵物', '圖片二', '圖片三', '面具' ]
};
for ( var attr in json5 ) {
for ( var i=0; i < json5[attr].length; i++ ) {
alert( json5[attr][i] );
}
}
// var arr = [ {}, {}, {} ];
var arr = [ { 'name' : 'TM', 'age' : 23 }, { 'name' : 'leo', 'age' : 32 } ];
for(var i = 0; i < arr.length; i++){
for(var attr in arr[i]){
console.log(arr[i][attr]);//TM 23 leo 32
console.log(attr);//name age name age
}
}
複製程式碼
- 物件
//物件的遍歷方法和查詢方法
var test = {"events": ["carrot", "exercise", "weekend"], "squirrel": false}
// 另一種遍歷物件陣列的方式
for (item in test) {
console.log(item);
}
// 判斷某個元素是否在test物件陣列裡面
if(('events' in test)){
console.log('event在test物件中');
}
複製程式碼
- 陣列的情況(push,unshift,pop,shift,splice,concat,reverse,replace)
陣列定義
// var arr = [ 1,2,3 ];
// var arr = new Array(1,2,3);
// alert( arr );
陣列可以存放多種資料型別的資料,
var arr = [ 'aaa',2,3 ];
//陣列可以檢視長度,修改長度
alert( arr.length ); // 3
arr.length = 0;
alert( arr );//null
//陣列新增--------
var arr = [ 1,2,3 ];
alert(arr.push(4));//輸出新增4後的arr長度
arr.push(4);//從後面新增4
alert(arr);//1,2,3,4,4
arr.unshift(5);//從前面新增
// IE 6 7 不支援 unshift 返回值
alert(arr.unshift(5));//同push
// alert(arr);//5,5,1,2,3,4
//陣列刪除----------
var arr = [ 1,2,3 ];
// pop()從後刪除,shift()從前刪除,返回值都是被刪除的那個值
var arr = [ 1,2,3 ];
alert( arr.pop() );//3
alert( arr );//1,2
alert( arr.shift() );//1
alert( arr );//2
//小例項----------
var arr = [ 1,2,3 ];
arr.push(arr.shift())
alert(arr);//2,3,1相當於集體向前移一位
arr.unshift(arr.pop());//相當於集體後前移一位,3,1,2
複製程式碼
**注:**由於unshift比push慢非常多,一個更好的解決辦法是:線reverse,在用push,然後再reverse就可以完成相同的效果,而且效率更高
//splice()----------------
splice()可以刪除、替換、新增,但是返回值就是刪除、替換、新增的那個值(或那幾個值)
var arr = [ 1,2,3 ];
// 刪除
arr.splice(0,1);//從第0個位置開始,刪除一個,即1
alert(arr);//2,3
// 新增
arr.splice(0,0,'aaaaaa');//第0個位置,插入'aaaaaa'
alert(arr);//aaaaaa.2,3
//替換
arr.splice(0,2,5);//第0個位置,用5來替換後面兩個值
alert(arr);//5,3
//concat()連結陣列-------------
var arr1 = [ 1,2,3 ];
var arr2 = [ 4,5,6 ];
var arr3 = [ 7,8,9 ];
alert( arr1.concat( arr2, arr3 ) );//可以連線多個陣列
//倒序方法reverse()
var arr1 = [ 1,2,3,4,5,6 ];
arr1.reverse();
alert( arr1 );//6,5,4,3,2,1
//倒敘字串
var str = 'abcdef';
//通過split轉為陣列,然後倒敘,再變為字串
alert(str.split('').reverse().join(''));
//replace()替換
// replace(/\//g, '') 的作用是把/替換成''。
var aa= "adsdd/sdsd12/";
bb=aa.replace(/\//g, '') ;//bb=adsddsdsd12
解釋:1。/pattern/是正規表示式的界定符,裡面的內容(pattern)是要匹配的內容,就是本例中的/\//;
2。\是轉義的意思,\/代表的是/字元。
3。JavaScript中應該是字串的replace() 方法如果直接用str.replace(/\//g, '')只會替換第一個匹配的字元. 而str.replace(/\//g, '')則可以替換掉全部匹配的字元(g為全域性標誌)。
複製程式碼
- sort排序
var arr = [ 'c', 'd', 'a', 'e' ];
arr.sort();
alert( arr );//a,c,d,e 預設按照字元排序
var arr2 = [ 4,3,5,5,76,2,0,8 ];
arr2.sort();
// 對純數字排序時,預設情況是錯誤的,8<76
alert( arr2 );//0,2,3,4,5,5,76,8
自定義排序規則
arr2.sort(function ( a, b ) {
// 如果a-b<0不動,反之調換位置
return a - b;
// 如果b-b<0不動,反之調換位置
// return b-a;降序
});
alert( arr2 );//0,2,3,4,5,5,8,76
複製程式碼
例子1:如果對var arrWidth = [ '345px', '23px', '10px', '1000px' ];排序?
arrWidth.sort(function ( a, b ) {
//轉化為數字,然後排序
return parseInt(a) - parseInt(b);
});
複製程式碼
例子2:自定義一個打亂陣列次序的函式 var arr = [ 1,2,3,4,5,6,7,8 ];
arr.sort(function ( a, b ) {
//random()函式是0~1的隨機數,如果>0.5就調換位置
return Math.random() - 0.5;
});
複製程式碼
- 隨機函式
alert( Math.round(3.4) );//四捨五入--4
Math.random();//0~1的隨機數
//0~10
alert( Math.round(Math.random()*10) );
//5~10
alert( Math.round( Math.random()*5 + 5 ) );
//20~100
alert( Math.round( Math.random()*80 + 20 ) );
// x ~ y
var x = 3;
var y = 49;
alert( Math.round( Math.random()*(y-x) + x ) );
// 0~x
alert( Math.round( Math.random()*x) );
// 1~x
alert( Math.ceil( Math.random()*x) );//ceil()向下取整
複製程式碼