//用 class 獲取元素 function getElementsByClass(className,context) { context = context || document; if(document.getElementsByClassName) { return context.getElementsByClassName(className); } else { var i; var arr = []; var elements = context.getElementsByTagName("*"); for (i in elements) { if(hasClass(className,elements[i])) { arr.push(elements[i]); } } return arr; } } //判斷一個元素有沒有給定的class function hasClass(className,ele) { if(!ele.className) {//如果元素根本沒有class,退出. return false; } var classNames = ele.className.split(/\s+/); for (var i = 0; i < classNames.length; i++) { if(className === classNames[i]) { return true; } } } //通過屬性名查找元素 function getElementsByAttr(attr,context) { var elements; var match = []; if(document.all) { elements = context.all; } else { elements = context.getElementsByTagName("*"); } attr = attr.replace(/\[|\]/g,"");//去掉中括號 if(attr.indexOf("=") == -1) {//沒有等於號的情況 for (var i = 0; i < elements.length; i++) { if(elements[i].getAttribute(attr)) { match.push(elements[i]); } } } else {//有等於號的情況 attrArr = attr.split("="); for (var j = 0; j < elements.length; j++) { if(elements[j].getAttribute(attrArr[0]) === attrArr[1]) { match.push(elements[j]); } } } return match; } //轉換為數組 function convertToArray(nodes) { var array; try { array = Array.prototype.slice.call(nodes,0); } catch (ex) { array = []; for(var i in nodes) { array.push(nodes[i]); } } return array; } //后一個兄弟元素 function nextSibling(node) { var tempLast = node.parentNode.lastChild; if (node == tempLast) return null; var tempObj = node.nextSibling; while (tempObj.nodeType != 1 && tempObj.nextSibling != null) { tempObj = tempObj.nextSibling; } return (tempObj.nodeType==1)? tempObj:null; } //前一個兄弟元素 function prevSibling(node) { var tempFirst = node.parentNode.firstChild; if (node == tempFirst) return null; var tempObj = node.previousSibling; while (tempObj.nodeType != 1 && tempObj.previousSibling != null) { tempObj = tempObj.previousSibling; } return (tempObj.nodeType==1)? tempObj:null; } //定義取消冒泡事件函數 function cancelBubble(e) { var evt = e ? e : window.event; if (evt.stopPropagation) { //W3C evt.stopPropagation(); } else { //IE evt.cancelBubble = true; } } //判斷一個變量是不是數組 function isArray(arr) { return Object.prototype.toString.call(arr) ==="[object Array]"; } // 判斷fn是否為一個函數,返回一個bool值 function isFunction(fn) { return Object.prototype.toString.call(fn) ==="[object Function]"; } //得到一個元素的子元素. function getChildNodes(node){ var child = node.childNodes; function convertToArray(nodes) { var array; try { array = Array.prototype.slice.call(nodes,0); } catch (ex) { array = []; for(var i in nodes) { array.push(nodes[i]); } } return array; } child = convertToArray(child); var arr = []; for(var i in child) { if(child[i].nodeType === 1) { arr.push(child[i]); } } return arr; } // var arr2 = [].concat(arr1); // var arr3 = arr1.slice(0); // var arr1 = [1,3,5,"dog",{name:"wang",age:5}]; // 使用遞歸來實現一個深度克隆,可以復制一個目標對象,返回一個完整拷貝 // 被復制的對象類型會被限制為數字、字符串、布爾、日期、數組、Object對象。不會包含函數、正則對象等 function clone(obj) { var newObj = (obj.constructor === Object) ? {} : []; if(window.JSON){ var temp = JSON.stringify(obj); newObj = JSON.parse(temp); } else { for(var key in obj) { if(obj.hasOwnProperty(key)){ newObj[key] = (typeof obj[key] === "object") ? clone(obj[key]) : obj[key]; } } } return newObj; } // 對數組進行去重操作,只考慮數組中元素為數字或字符串,返回一個去重后的數組 function uniqArray(arr) { var temp = []; if(arr[0]){ temp.push(arr[0]); } outer: for (var i = 1; i < arr.length; i++) { for(var j in temp){ if(arr[i] === temp[j]){ continue outer; } } temp.push(arr[i]); }; return temp; } // var arr1 = [1,2,3,4,2,5,3,6,1,5,6,7,87]; // 實現一個簡單的trim函數,用於去除一個字符串,頭部和尾部的空白字符 // 假定空白字符只有半角空格、Tab // 練習通過循環,以及字符串的一些基本方法,分別掃描字符串str頭部和尾部是否有連續的空白字符,並且刪掉他們,最后返回一個完成去除的字符串 function simpleTrim(str) { var temp = ""; for(var i = 0;i < str.length; i++) { if( //自己有值且不是空格,復制 (str.charAt(i) && str.charAt(i) != " ") //自己是空格,且上一位和下一位都不是空格,復制 || (str.charAt(i) === " " && (str.charAt(i + 1) && str.charAt(i + 1) != " ") ) ) { temp += str.charAt(i); } } //如果第0位是空格,就返回第1位及以后的字符,否則返回整個字符串 return temp = (temp.charAt(0) === " ")? temp.slice(1) : temp; } // var str = " hello world hello world hello world hello world"; // simpleTrim(str); // 對字符串頭尾進行空格字符的去除、包括全角半角空格、Tab等,返回一個字符串 // 嘗試使用一行簡潔的正則表達式完成該題目 function trim(str) { str = str.replace(/^\s*|\s*$/g, "");//刪除首尾空格 return str = str.replace(/\s+/g, " ");//刪除中間多余空格 } // 實現一個遍歷數組的方法,針對數組中每一個元素執行fn函數,並將數組索引和元素作為參數傳遞 function each(arr, fn) { for (var i = 0,len = arr.length; i < len; i++) { fn(arr[i],i); }; } function say(value,index) { if(arguments.length === 1) { console.log(value); } else if(arguments.length === 2) { console.log(index + ": " + value); } } // 獲取一個對象里面第一層元素的數量,返回一個整數 function getObjectLength(obj) { var index = 0; for(var i in obj){ index ++; } return index; } // var obj = { // a: 1, // b: 2, // c: { // c1: 3, // c2: 4 // } // }; // console.log(getObjectLength(obj)); // 3 // 判斷是否為郵箱地址 function isEmail(emailStr) { //郵箱以數字或字母開頭,包含字母 數字 下划線 短橫線 var mailReg = /^[A-Za-z0-9][A-Za-z0-9_-]+@[A-Za-z0-9_-]+(\.[A-Za-z0-9_-]+)+$/; return mailReg.test(amailStr); } // 判斷是否為手機號 function isMobilePhone(phone) { // 手機號11位,純數字.可能會有國家編號 var phoneReg = /^(\+(\d){2})?1\d{10}$/; return phoneReg.test(phone); } // 3 DOM // 為element增加一個樣式名為newClassName的新樣式 function addClass(element, newClassName) { if(newClassName){ if(element.className === "") { element.className = newClassName; } else { element.className += " " + newClassName; } } } // 移除element中的樣式oldClassName function removeClass(element, oldClassName) { if(oldClassName){ var removeClassName = new RegExp(oldClassName); element.className = element.className.replace(removeClassName,""); } } // 判斷siblingNode和element是否為同一個父元素下的同一級的元素,返回bool值 function isSiblingNode(element, siblingNode) { return element.parentNode === siblingNode.parentNode; } // 獲取element相對於瀏覽器窗口的位置,返回一個對象{x, y} function getViewPosition1(element) { var position = {}; function getLeft() { var left = element.offsetLeft; var current = element.offsetParent; while(current !== null){ left += current.offsetLeft; current = current.offsetParent; } return left; } function getTop(){ var top = element.offsetTop; var current = element.offsetParent; while(current !== null) { top += current.offsetTop; current = current.offsetParent; } return top; } var elementScrollLeft = document.documentElement.scrollLeft || document.body.scrollLeft; var elementScrollTop = document.documentElement.scrollTop || document.body.scrollTop; position.x = getLeft() - elementScrollLeft; position.y = getTop() - elementScrollTop; return position; } //獲取element 相對窗口位置的另一種快捷方法 function getViewPosition2(element) { var position = {}; position.x = element.getBoundingClientRect().left; position.y = element.getBoundingClientRect().top; return position; } //獲取元素絕對位置 function getElePosition(element) { var position = {}; position.x = element.getBoundingClientRect().left + getScrollLeft(); position.y = element.getBoundingClientRect().top + getScrollTop(); return position; } //滾動條高度 function getScrollTop(){ return document.documentElement.scrollTop || document.body.scrollTop; } //滾動條寬度 function getScrollLeft(){ return document.documentElement.scrollLeft || document.body.scrollLeft; } //鼠標絕對位置 function getPointerLocation(event){ event = event || window.event; var position = {}; position.X = event.pageX || event.clientX + getScrollLeft(); position.Y = event.pageY || event.clientY + getScrollTop(); return position; } //得到窗口大小 function getViewport(){ if (document.compatMode === "BackCompat"){ return { width: document.body.clientWidth, height: document.body.clientHeight } } else { return { width: document.documentElement.clientWidth, height: document.documentElement.clientHeight } } } // 實現一個簡單的Query function $(selector,context) { var element = []; current = context || document; function query(ele,current) { var firstLetter = ele.charAt(0); switch (firstLetter) { case "#": return current.getElementById(ele.slice(1)); break; case ".": return getElementsByClass(ele.slice(1),current); break; case "[": return getElementsByAttr(ele,current); break; default : return current.getElementsByTagName(ele); break; } } //因為參數之間的分割是空格,沒有逗號,所以 arguments 的長度是1 //這一步把參數用空格分割開 var arg = selector.split(/\s+/); //console.log(arg); for (var i = 0; i < arg.length; i++) { if(i == 0) { //把結果保存在數組里. //getElementsByClassName() getElementsByTagName() 返回的是類數組的對象,但不是數組.不能直接運用數組方法.需要類型轉換 if(arg[i][0] == "#") { element = element.concat(query(arg[i],current)); } else { element = element.concat(convertToArray(query(arg[i],current))); } } else { var temp = []; var result = []; for(var j in element) { // current = element[j]; temp = convertToArray(query(arg[i],element[j])); if(temp.length) { result = result.concat(convertToArray(temp)); } } element = result; result = []; } } //如果輸入的選擇器中最后一個是 id ,就輸出第一個元素.因為 id 唯一. if(arg[arg.length-1][0] == "#") { return element[0]; } else { return element; } } // 可以通過id獲取DOM對象,通過#標示,例如 // $("#adom"); // 返回id為adom的DOM對象 // 可以通過tagName獲取DOM對象,例如 // $("a"); // 返回第一個<a>對象 // 可以通過樣式名稱獲取DOM對象,例如 // $(".classa"); // 返回第一個樣式定義包含classa的對象 // 可以通過attribute匹配獲取DOM對象,例如 // $("[data-log]"); // 返回第一個包含屬性data-log的對象 // $("[data-time=2015]"); // 返回第一個包含屬性data-time且值為2015的對象 // 可以通過簡單的組合提高查詢便利性,例如 // $("#adom .classa"); // 返回id為adom的DOM所包含的所有子節點中,第一個樣式定義包含classa的對象 // 4 事件 // 給一個element綁定一個針對event事件的響應,響應函數為listener function addListener(element, type, listener) { if(element.addEventListener) { element.addEventListener(type,listener,false); } else if(element.attachEvent) { element.attachEvent("on" + type,listener); } else { element["on" + type] = listener; } } // 移除element對象對於event事件發生時執行listener的響應 function removeListener(element, type, listener) { if(element.removeEventListener) { element.removeEventListener(type,listener,false); } else if(element.detachEvent) { element.detachEvent("on" + type,listener); } else { element["on" + type] = null; } } // 實現對click事件的綁定 function addClickEvent(element, listener) { addEvent(element,click,listener); } // 實現對於按Enter鍵時的事件綁定 function addEnterListener(element, listener) { element.onkeydown = function(event) { var event = event || window.event; if(event && event.keyCode === 13) { addEvent(element,type,listener); } } } // 事件代理, 基於addListener function delegateEvent(element, tag, type, listener) { function getEventTarget(e) { e = e || window.event; return e.target || e.srcElement; } function eventFn(type) { var target = getEventTarget(event); if(target && target.tagName.toLowerCase() === tag) { listener(); } } addListener(element,type,eventFn); } //將函數封裝為以下形式 var Event = {}; //事件綁定 Event.on = function(selector, event, listener) { var element = $(selector);//調用$() if(element.addEventListener) { element.addEventListener(event,listener,false); } else if(element.attachEvent) { var ieEvent = "on" + event; element.attachEvent(ieEvent,listener); } } //點擊事件 Event.click = function(selector, listener) { Event.on(selector,click,listener);//調用Event.on() } //解除事件綁定 Event.un = function(selector, event, listener) { var element = $(selector); if(element.removeEventListener) { element.removeEventListener(event,listener,false); } else if(element.detachEvent) { var ieEvent = "on" + event; element.detachEvent(ieEvent,listener); } } //事件代理 Event.delegate = function(selector, tag, event, listener) { var element = $(selector); function getEventTarget(e) { var e = e || window.event; return e.target || e.srcElement; } function eventFn(e) { var target = getEventTarget(e); if(target.tagName.toLowerCase() === tag) { listener(); } } addEvent(element, event, eventFn); } // 使用示例: // $.click("[data-log]", logListener); // $.delegate('#list', "li", "click", liClicker); // 5 BOM // 判斷是否為IE瀏覽器,返回-1或者版本號 function isIE() { return !-[1,]; } // 設置cookie function setCookie(cookieName, cookieValue, expiredays) { var d = new Date(); d.setDate(d.getDate() + expiredays); var cookieText = encodeURIComponent(cookieName) + "=" + encodeURIComponent(cookieValue); if (expiredays) { cookieText += "; expires=" + expiredays.toGMTString(); } document.cookie = cookieText; } // 獲取cookie值 function getCookie(cookieName) { var arrCookie = document.cookie.split(";"); for (var i = 0; i < arrCookie.length; i++) { var _arr = arrCookie[i].split("="); if(_arr[0] === cookieName) { return _arr[1]; } } else { return null; } } // 6 Ajax function ajax(url, options) { var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP'); var type = options.type ? options.type : "get"; var afterHandleData = handleData(options.data); if(type === "get"){ url = url + "?" + afterHandleData; xhr.open(type,url,true); xhr.onreadystatechange = ready; xhr.send(null); } else if(type === "open") { xhr.open(type,url,true); xhr.onreadystatechange = ready; xhr.send(afterHandleData); } function ready() { if(xhr.readyState === 4) { if(xhr.status === 200) { options.onsuccess(); } else { options.onfail(); } } } function handleData(data) { var temp = ""; var key; for(key in data) { temp += "&" + key + "=" + data[key]; } //刪掉第一個 & if(temp.charAt(0) === "&"){ temp = temp.slice(1); } return temp; } } // 使用示例: /*ajax( 'http://localhost:8080/server/ajaxtest', { data: { name: 'simon', password: '123456' }, onsuccess: function (responseText, xhr) { console.log(responseText); } } )*/ // options是一個對象,里面可以包括的參數為: // type: post或者get,可以有一個默認值 // data: 發送的數據,為一個鍵值對象或者為一個用&連接的賦值字符串 // onsuccess: 成功時的調用函數 // onfail: 失敗時的調用函數
如何阻止事件冒泡和默認事件
function stopBubble(e)
{
if (e && e.stopPropagation){
e.stopPropagation()
}else{
window.event.cancelBubble=true
}
return false