面向對象 ,基本模式、對象字面量模式、工廠模式、構造函數模式、原型模式、組合構造函數和原型模式、其餘模式見電子書:動態原型模式、寄生構造函數模式(不推薦)、穩妥構造函數模式(要求安全的環境,不使用new 和 this)javascript
//面向對象 /* 【 數據屬性】 * configurable true 經過 delete刪除屬性來修改屬性 * enumberable true 經過 for-in 返回屬性 * writable true 修改屬性值 * value 數據值 * es5 經過 Object.defineProperty(obj,屬性名,對象{} ) 可對以上修改 * 屬性名爲 configurable/enumerable/writable/value * 把 configurable 設置爲 false後,就沒法再設置爲true 了, * 調用 Object.defineProperty() 默認屬性名都爲 false * */ var person = {} Object.defineProperty(person,"name",{ writable: false, // 阻止修改屬性值 value:'xiaoming' }) console.log(person.name) person.name = 'xxx'; console.log(person.name) /* 【訪問器屬性】 * configurable false * enumerable * get函數 默認 undefined * set函數 默認 undefined * 添加get set函數 * */ var book = { _year: 2014, // 下劃線表示只能經過對象方法訪問的屬性,可直接訪問 edition:1 } Object.defineProperty(book,'year',{ get:function () { return this._year }, set:function (val) { if(val> 2014){ this._year = val this.edition += val - 2004 } } }) book.year = 2015; console.log(book.edition); console.log(book._year); /* 同時定義多個屬性用 Object.defineProperties() 複數 */ /* 經過 Object.getOwnPropertyDescriptor() 可查看 數據屬性和 訪問器屬性各個值 * js中任何對象,包括DOM對象和BOM對象都有 Object.getOwnPropertyDescriptor() 方法 * * */ var desc =Object.getOwnPropertyDescriptor(book,'_year') console.log(desc.value); console.log(desc.configurable); var desc2 =Object.getOwnPropertyDescriptor(book,'year') console.log(desc2.value); // undefined console.log(desc2.configurable); // false /* 【1.通常模式 】*/ var obj = new Object() obj.name='name' console.log('name: '+obj.name); /* 2.對象字面量 */ var obj2 = { name: 'mama' } console.log('mama: '+obj2.name); /*【 3.工廠模式】 */ function cretePerson(name,age) { var o = new Object(); o.name = name; o.age = age; o.sayName =function () { console.log('xx: ' + this.name); } return o; } var person1 = cretePerson('kang',22) person1.sayName() /* 【4.構造函數模式】*/ function Person(name, age) { this.name=name; this.age=age; this.sayName2=function () { console.log(this.name + 'abccde') // 等同於 this.sayName2 = new Function('...') 每次實例化都會 new Function(),這是缺陷 } } var per2 = new Person('xiao',33) // Person() 當成構造函數用,有 new per2.sayName2() console.log(per2 instanceof Person); // Person('kangddd',44) // Person() 當成普通函數用, // window.sayName2(); var per3 = new Person('aa',33) var per4 = new Person('bb',33) // 實例化兩個對象,裏面有 sayName() 方法,ECMAScript中函數也是對象,每定義一個函數,就是實例化一個對象 console.log('ddd333' + (per3 == per4)); // + 號優先級比 == 高 console.log('eeefff' + false); /* 【5.原型模式】 * 每一個函數都有 prototype(原型)屬性,是一個指針,指向一個對象 * 對象實例共享 prototype 定義的屬性和方法 * */ function PersonSix() { } PersonSix.prototype.name = 'li' PersonSix.prototype.sayName3=function () { console.log(this.name); } var per10 = new PersonSix(); per10.sayName3() // 先查找 per10有沒有sayName3()方法,有則返回,沒有則查找 prototype是否有 sayname3()方法 /* 每建立一個函數,都有prototype */ function test() { return 1 } console.log(test); // 輸入函數 function test(){} console.log(test.prototype); // 返回一個對象 每建立一個函數,都有 prototype console.log(test.prototype.constructor); // 返回 函數 function test(){} function Person100() { } Person100.prototype.name='100name' Person100.prototype.age='100age' var p100 = new Person100() var p101 = new Person100() p100.name = '110name' // 實例中新增同名屬性覆蓋 原型中的 name console.log(p100.name); // '110name' console.log(p101.name); // '100name' delete p100.name; // 經過 delete 能夠找回 原型中的 name console.log(p100.name); // '100name' console.log(p100.hasOwnProperty('name')); // 判斷實例是否有某屬性 hasOwnProperty console.log('name' in p100); // name存在於實例或者原型都會返回 true console.log(Object.keys(Person100.prototype)); // ['name','age'] 拿到全部原型屬性的數組 console.log(Object.getOwnPropertyNames(Person100.prototype)); // ['constructor','name','age'] 拿到全部原型屬性的數組 console.log('ok ? ' + (p100.constructor == Person100)); // 簡化前 這裏是 true /* 簡化原型語法*/ function Car() { } Car.prototype={ constructor: Car, // 手動指定 constructor ,省略後, car.constructor 就再也不指向 Car name:'baoma', age:22 } var car = new Car() console.log(car.name); console.log(Car.prototype.constructor); console.log(car.constructor == Car); // 簡化後,這裏返回 false /* 在 String.prototype中能夠找到 substring() 方法 */ /* 原型模式的缺陷是 若是對象中的屬性是引用類型,如 數組 , 那麼某個實例修改了數組,另外一個實例也拿到了修改後的數據 */ function Dog() { } Dog.prototype={ constructor:Dog, friends:['kang','jia'] } var f1 = new Dog() var f2 = new Dog() f1.friends.push('hehe') console.log(f1.friends); // ['kang','jia','hehe'] console.log(f2.friends); // ['kang','jia','hehe'] /* 【組合使用構造函數械和原型原式 】*/ function Pig(name,age) { // 屬性寫在構造函數中 this.name = name; this.age= age; this.friends = ['dd','ee'] } Pig.prototype={ // 方法寫在原型中 constructor: Person, sayName:function () { console.log(this.name); } } var pig1 = new Pig('piga',11) var pig2 = new Pig('pigb',12) pig1.friends.push('ff') console.log(pig1.friends); console.log(pig2.friends); console.log(pig1.friends === pig2.friends); // false console.log(pig1.sayName === pig2.sayName); // true
閉包css
/* 面向對象繼承方法 見 6.3.4原型式繼承,一個對象繼承另外一個不一樣的對象 更好的是 6.3.6寄生組合式繼承 */ var a = function () { return 5; } console.log(a()); /* 遞歸 嚴格模式下不能用 arguments.callee時的寫法,加多了一個括號,加多一個函數名 */ var factorial = (function f(num) { if (num <= 1) { return 1; } else { return num * f(num - 1) } }) console.log(factorial(5)); /* 普通函數fn被調用時,會建立一個包含 this/arguments/參數val的活動對象, 全局執行環境的變量對象(包含this、res、fn)在執行環境的做用域鏈中則處於第二位*/ function fn(val) { return 5 + val } var res = fn(4) /* 閉包:指有權訪問另外一個函數做用域中的變量的函數,建立閉包的常見方式,就是在一個函數內部建立另外一個函數*/ function createComparison() { return function (obj1, obj2) { // 內部函數會將外部函數 createComparison的活動對象 this等都添加到它的做用域鏈中,所以閉包比通常函數會佔用更多內存,少用 // ... } } // 閉包做用域鏈使閉包只能取得包含函數中任何變量的最後一個值 function fn2() { var result = new Array(); for (var i = 0; i < 10; i++) { result[i] = function () { return i; } } return result; } console.log(fn2()); // 不懂 // 閉包中的 this 指向 window, this通常狀況下,誰調用指代誰 var name = 'window' var obj = { name: 'obj', getName: function () { return function () { return this.name } } } console.log(obj.getName()); // function(){ return this.name} 調用 getName() 返回一個函數 , console.log(obj.getName()()); // 'window' 調用 getName()() 就會當即調用它返回的函數,即返回一個字符串 function assign() { var element = document.getElementById('a'); var id = element.id element.onclick = function () { console.log(id); } element = null; // 把 element 設置爲 null , 手動在閉包中釋放內存 } function f2() { for (var i = 0; i < 10; i++) { console.log(i); } console.log(i); // undefined 還能夠訪問,i是定義在f2()函數的活動對象中的 // console.log(j); // error not defined } console.log(f2()); function f3() { (function () { for (var i = 0; i < 10; i++) { console.log(i); } console.log(i); // 10 (function(){ ... })() 塊級做用域,外部訪問不到,可使用本身定義的變量,不受其餘干擾 })() // console.log(i); // error not defined i 在塊級做用域中,外部訪問不到, } f3() function Test() { var num = 1078; return num; } console.log(Test()); // 函數名能夠大寫、中文, /* * 特權方法 * */ function f4() { var num4 = 4; function getNum() { return false } // 特權方法 this.publicNum = function () { return num4 } // 特權方法 this.publicMothod = function () { return getNum() } // return num4; 不想返回,能夠寫個方法返回 ,並用對象的構造函數模式返回 } console.log(f4()); console.log(new f4().publicMothod()); console.log(new f4().publicNum()); var f6 = function () { console.log(666); }()
setTimeout() 少用setInterval() history() location.replace() 不能後退到當前頁面html
var age = 29; // 使用var 定義後,把 configurable 設置爲false 阻止 delete 【面向對象 數據屬性 configurable 】 window.color='red' delete window.age; delete window.color; console.log(window.age); // 29 console.log(window.color); // undefined 使用window來定義變量color,能夠被 delete // ECMAScript 是 js的核心,在web中使用js,則BOM是web(window location navigator )核心 // 使用 setTimeout() 超時調用, 少用間歇調用setInterval() ,須要 clearInterval var num = 0; var max = 60; function minute() { max--; console.log(max); if (max > num) { setTimeout(minute, 1000) } else { console.log('ok'); } } setTimeout(minute, 1000) // 倒計時效果 /* location.search */ var url = 'http://www.baidu.com?name=kang&age=12' console.log(location.search); // ?name=kang&age=12 /* 取消後退按鈕用 location.replace() */ setTimeout(function () { location.replace('http://www.baidu.com') // 不能後退到以前的頁面 },1000) location.reload() // 從新加載 (有可能從緩存中加載 ) location.reload(true) // 從新加載 (從服務器中加載 ) history.go(1) // 前進一頁 history.forward() history.go(-1) //後退一頁 history.back() // if(history.length == 0){ // 這是用戶打開窗口後的第一個頁面 }
倒計時 setTimeout() 不用 setInterval() java
倒計時 <p id="num">60</p> <script> var max = document.getElementById('num').innerHTML var num = 0; function minute() { max--; document.getElementById('num').innerHTML = max console.log(max); if (max > num) { setTimeout(minute, 1000) } else { console.log('ok'); } } // setTimeout(minute, 1000) </script>
document getElementByClassName classList readyState compatMode outerHTMLnode
console.log(document.title); // 標題 console.log(window.location.href); console.log(document.URL); // 網址 console.log(document.domain); // 域名 /* * document.forms 全部<form>元素 * document.images 全部 <img>元素 * document.links 全部帶 href的<a>元素 * document.anchors 全部帶 name的<a>元素 描點 * */ document.write('<script src = "1.js"></script>') /* 文本 節點分割 */ var element = document.createElement("div") var textNode = document.createTextNode('hello world') element.appendChild(textNode) document.body.appendChild(element) var newNode = element.firstChild.splitText(5) // 文本節點分割 console.log(element.firstChild.nodeValue); console.log(newNode.nodeValue); /* * <div class="a"></div> * */ document.getElementsByTagName('div')[0].innerHTML = 444 document.querySelector('.a').innerHTML = 123 document.getElementsByClassName('a')[0].innerHTML = 888 // h5 新增 getElementsByClassName /* * h5 增長 classList 方法 for(var i = 0;i<div.classList.length; i++){...} * <div class = 'a b c'>ddd</div> * div.classList.remove('a') // 刪除a 樣式 add() 添加 toggle('c') 切換樣式 contains('d') 包含樣式 * */ /* * h5 DOM焦點功能 * document.activeElement 判斷得到焦點是哪一個元素 * document.hasFocus() 是否得到焦點了 * */ var button = document.getElementById('mybtn') button.focus(); console.log(document.activeElement === button); // true console.log(document.hasFocus()); // true /* * h5 文檔加載屬性 readyState loading 加載中 complete 加載完成 * if(document.readyState == 'complete'){ ... // 文檔加載完成 } * */ /* * 渲染模式 * * */ if(document.compatMode == 'CSS1Compat'){ console.log('standards mode'); // 標準模式 }else { console.log('quirks mode'); // 混雜模式 } console.log(document.charset); // utf-8 // h5 新增 document.head (chrome和 safari5 實現了) var head = document.head || document.getElementsByTagName('head')[0]; /* * outerHTML * <div id="mydiv" data-apptest = '12345' data-appName="hehe">div</div> * */ document.getElementById('mydiv').outerHTML="<p>this is p</p>" /* 把 mydiv整個html片段 替換爲 新的內容 */ /* * <div id="mydiv" data-apptest = '12345' data-appName="hehe">div</div> * 在 div同級以前、以後插入元素,在div裏面內容以前、以後插入元素 beforebegin afterbegin beforeend afterend * 使用 innerHTML outerHTML insertAdjacentHTML 要先把原來的元素相關的事件給刪除,減小內存佔用 * */ document.getElementById('mydiv').insertAdjacentHTML('beforebegin','<p>pppp</p>')
js刪除元素的行內樣式 removeProperty() cssText 添加多個樣式android
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>abc</title> </head> <style> .p3{ position: absolute;top:22px;left:33px; color: red; } </style> <body> <div id="test">d</div> <div style="border: 1px solid green;width:200px;height: 300px;position: relative;" > <p style="position: absolute;top:22px;left:33px;color:blue;" id="test2">dddddd</p> <p style="" class="p3" id="test3">dddddd</p> </div> <script src="0.js"></script> 原型對象 p167 <script> /* 刪除樣式,取得默認屬性 * cssText 批量添加樣式、 removeProperty() 刪除樣式 h5的classList 也能夠刪除樣式 * removeProperty() 在不肯定某個給定的CSS屬性擁有什麼默認值的狀況下,能夠移除相應的屬性,就能夠爲元素應用默認值 * */ var test = document.getElementById('test') test.style.color='red' test.style.cssText='font-size:50px;color:blue;' //添加多個樣式 var prop,val for(var i =0;i<test.style.length;i++){ // console.log(test.style[i]); prop = test.style[i] val = test.style.getPropertyValue(prop) console.log(prop + " : " + val); } test.style.removeProperty('color') document.getElementById('test2').style.removeProperty('position') document.getElementById('test2').style.removeProperty('color') document.getElementById('test3').style.removeProperty('color') // 只能刪除行內式,樣式選擇器的刪除不了 /* getComputedStyle(a,b) a:元素, b:僞元素字符串,如 :after ,沒有傳 null ie不支持,用currentStyle 其餘瀏覽器返回值,如border值不一致*/ var computedStyle = document.defaultView.getComputedStyle(test,null) </script> </body> </html>
js 讀取樣式表的屬性 能夠動態添加 樣式 insertRule ie用addRule 刪除樣式 deleteRule() ie用 removeRule() 不經常使用ios
<style> .test{ background: blue; width:110px; height:220px; } .box{ background: red; width:100px; height:200px; } </style> <body> <script> var sheet = document.styleSheets[0]; var rules = sheet.cssRules || sheet.rules; console.log(rules[0].selectorText); // 讀取樣式表的屬性值 console.log(rules[1].style.cssText); console.log(rules[0].style.background); console.log(rules[0].style.width); console.log(rules[0].style.height); </script>
偏移量 offset 客戶區大小 client 滾動大小 scrollTop web
偏移量
offset 內容+padding+border
offsetHeight offsetWidth offsetLeft offsetTop p12.2.3 元素大小
客戶區大小
client 內容+padding
clientHeight clientWidth document.documentElement.clientWidth 低版本用 document.body.clientWidth
滾動大小
scrollHeight 元素內容高度
scrollWidth 元素內容寬度 document.documentElement.scrollWidth
scrollLeft
scrollTop
getBoundingClientRect() DOM遍歷、DOM範圍chrome
每一個元素都有 getBoundingClientRect() , 返回一個矩形對象 left top right bottom ie8不一致
DOM遍歷 p12.3 NodeIterator、TreeWalker ie不支持
DOM範圍 p12.4
事件 event對象 currentTarget target thiswindows
<script> /* 事件都會傳 event對象 , ie8之前由 window.event 得到,若是ie使用 <input type='text' onclick="alert(event.type)"> 這裏的event就能夠直接獲取 ,跟DOM同樣 currentTarget target this 通常狀況下,currentTarget === this === target , 當點擊區域變大了後, target會變成點擊目標,如body,如button等,而 this和currentTarget永遠表示調用的對象,這裏是body*/ document.body.onclick=function (e) { console.log(e.type); // 'click' 'mouseover'等 console.log(e.currentTarget === this); console.log(e.target === this); console.log(e.target); // 點哪一個是哪一個 button 或 body console.log(this); // 誰調用是誰 body } </script>
js訪問form元素簡寫 、 addEventListener() 事件冒泡 stopPropagation()
<body> <form action="" name="form1"> <input type="text" name="username"> <input type="button" onclick="console.log(username.value)" value="click"> <!-- 輸入的值 表單簡寫 --> <input type="button" onclick="console.log(this.value)" value="btn"> <!-- btn --> <input type="button" onclick="console.log(value)" value="btn22"> <!-- btn22 表單簡寫 --> </form> <!-- addEventListener('click',function(){},false) false 表示在冒泡階段調用事件處理程序,即從當前元素,如div 往上一級,body 等促發 true 表示在捕獲階段調用事件處理程序,即從body-> div 再到 body的促發,先由外到內的捕獲,再由內到外的冒泡 --> <!-- /* 取消連接的默認行爲,如連接跳轉,使用 e.preventDefault() * 取消事件冒泡,使用 stopPropagation() * */ --> <div id="mydiv" style="border: 1px solid green;width: 200px;height: 200px;"> <button id="btn">btn</button> </div> <script> // 只有在事件處理期間,event對象纔會存在,一旦事件處理完成,event對象就會被銷燬 document.getElementById('btn').onclick=function (e) { e.stopPropagation() // 阻止後,就不影響 console.log('btn'); // 點擊btn時,也會點到外面的mydiv,會輸入兩行 } document.getElementById('mydiv').onclick=function () { console.log('mydiv'); } </script> </body>
事件 event
/* 【電子書 13.4】 * load 頁面加載後 window.onload , 全部框架加載完,在框架上觸發, 圖片加載完,在img上觸發, object嵌入內容加載完在 object上觸發 * unload 頁面卸載 window.unload ,全部框架卸載完,在框架上觸發, object嵌入內容卸載完在 object上觸發 ,從一個頁面切換到另外一個頁面就會發生 unload事件,多用於清除引用,避免內存泄漏 * abort 用戶中止下載過程時,若是嵌入的內容沒有加載完,在<object>上觸發 * error 當發生javascript錯誤時在window上面觸發,當沒法加載圖像在img觸發,當沒法加載嵌入內容在<object>觸發 * select 當選擇文本框input 或 textarea 中一或多個字符時觸發 * resize 當窗口或框架大小變化在 window 觸發, 最大化、最小化也會觸發 * scroll 當滾動帶滾動條的元素中的內容時,在該元素上面觸發 body元素包含所加載頁面的滾動條 * * <script> 在ie9+ 中,只有設置了script的src屬性,並添加該元素到文檔後,纔會開始加載js文件 * 事件中的 shift ctrl alt meta(指windows鍵盤中的windows鍵,在蘋果機 Cmd鍵 ) * e.shiftKey e.ctrlKey e.altKey e.metaKey * 鼠標左中右鍵 e.button 0 表示左鍵 1 表示鼠標滾輪 2表示鼠標右鍵 * mousewheel 鼠標滾輪事件 有一個 e.wheelDelta 屬性,當用戶向前滾動鼠標時 wheelDelta是120的倍數,向後滾動鼠標,wheelDelta是-120的倍數 * 火狐用 e.DOMMouseScroll 保存在 e.detail 當用戶向前滾動鼠標時 wheelDelta是 -3 的倍數,向後滾動鼠標,wheelDelta是3的倍數 * * 觸摸設備 ios 和 android 沒有鼠標, 沒有 dbclick * 輕擊可觸發 mousemove事件,若是該操做會致使內容變化,將再也不有其餘事件發生,若是屏幕沒有所以變化,那麼會依次發生 mousedown mouseup 和 click 事件 * mousemove事件也觸發 mouseover mouseout事件 * 兩個手指在屏幕上且頁面隨手指移動而滾動時會觸發mousewheel和scroll事件 (好像沒啥用) * * keydown 用戶按下鍵盤任意鍵觸發,按住不放,會重複觸發 * keypress 鍵盤字符鍵、esc鍵觸發,按住不放,會重複觸發 * textInput 文本事件,對keypress的補充,在文本插入文本框以前觸發textInput 事件 * 用戶按下鍵盤的字符鍵後,先觸發 keydown事件、再觸發 keypress事件,再觸發 keyup事件, keydown和keypress是在文本框發生變化以前觸發的。 keyup是文本框發生變化以後觸發的。 * 【電子書 13.4.4】 * */
pageX offsetX screenX clientX 鼠標左中右鍵,滾輪事件 頁面切換事件 unload
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>abc</title> </head> <body> this is 0.html <script> window.onunload=function () { console.log('unload'); // 頁面跳轉,離開當前頁面會執行,頁面刷新也會執行 } </script> <div id="a" style="border: 6px solid green;width:200px;height: 200px;padding:10px;">div</div> <div id="b" style="border: 6px solid green;width:200px;height: 200px;padding:10px;">div</div> <div id="c" style="border: 6px solid green;width:200px;height: 200px;padding:10px;">div</div> <script> document.getElementById('a').onclick=function (e) { console.log(e.clientX); console.log(e.pageX); // 以瀏覽器爲起點,頁面不滾動,二者一致, 頁面滾動,pageX包括滾動條的值 console.log(e.screenX); // 相對當前屏幕,以PC桌面左上角爲起點 console.log(e.offsetX); // 限制在點擊區域內的位置,除去邊框和外邊距 } document.getElementById('b').addEventListener('mousedown',function (e) { console.log(e.button); // 判斷鼠標左中右鍵 e.button的值 0 是左鍵 1 是鼠標滾輪 2是右鍵 },false) document.getElementById('c').addEventListener('mousewheel',function (e) { console.log(e.wheelDelta); },false) document.getElementById('c').addEventListener('DOMMouseScroll',function (e) { console.log(e.detail); // 火狐用 DOMMouseScroll },false) </script> </body> </html>
contextmenu冒泡事件 右鍵菜單
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>abc</title> </head> <body> contextmenu冒泡事件 上下文菜單(右鍵菜單) <div id="mydiv" style="border: 1px solid green;width:800px;height: 1000px;">右鍵菜單</div> <div id="mymenu" style="border: 1px solid green;width:200px;height:200px;display:none;position: absolute;top:80px;left:20px;">右鍵菜單 </div> <script> // 右鍵菜單 var mydiv = document.getElementById('mydiv') var mymenu = document.getElementById('mymenu') mymenu.addEventListener('contextmenu', function (e) { e.preventDefault() // 阻止默認的瀏覽器右鍵菜單 }) mydiv.addEventListener('contextmenu', function (e) { e.preventDefault() // 阻止默認的瀏覽器右鍵菜單 mymenu.style.left = e.clientX + 'px' mymenu.style.top = e.clientY + 'px' mymenu.style.display = 'block' }) document.addEventListener('click', function () { mymenu.style.display = 'none' }) </script> <script> window.addEventListener('beforeunload',function (e) { // 窗口關閉時,彈窗是否關閉 var res = 'abc' e.returnValue=res // ie能夠 return res // chrome 返回不了'abc' }) </script> load事件會在頁面中一切都加載完畢時觸發,包括一堆外部資源 DOMContentLoaded事件則在造成完整的DOM樹以後就會觸發,不理會圖像、JS文件、css文件是否已經下載完畢,用戶能夠早點與頁面進行交互 ie9+支持 不支持的瀏覽器,處理以下 setTimeout(function(){ ... },0); // 不必定有效 readystatechange事件 chrome不支持! ie、firefox支持 pageshow和pagehide事件 在瀏覽器後退和前進按鈕時緩存數據,不會用 ,ie9不兼容 hashchange事件 url中'#'號後面的字符串發生變化時,監聽事件 window.addEventListener('hashchange',function(e){console.log(location.hash);}) ie8+ 支持 手機設備旋轉事件 deviceorientation devicemotion android版 webkit ? 觸摸事件 touchstart touchmove(調用 preventDefault()能夠阻止滾動 ) touchend 觸摸事件(包括鼠標事件的順序,會冒泡) touchstart / moseover / mousemove(一次) / mousedown / mouseup /click/ touchend 手勢事件(要兩個手指在元素範圍內才觸發,會冒泡,只放一個手指會觸發 touchstart事件) ios才支持 gesturestart gesturechange gestureend </body> </html>