首页
前端面试题
前端报错总结
电子书
更多
插件下载
Search
1
JavaScript基础(二)操作符 流程控制
42 阅读
2
HTML基础
20 阅读
3
Vue基础
17 阅读
4
wctype.h
14 阅读
5
Vue2(知识点)
13 阅读
默认分类
HTML CSS
HTML基础
CSS
HTML5 CSS3
javaScript
javaScript基础
javaScript高级
Web APIs
jQuery
js小总结
WEB开发布局
Vue
PS切图
数据可视化
Git使用
Uniapp
c语言入门
标准库
嵌入式
登录
Search
liuxiaobai
累计撰写
108
篇文章
累计收到
12
条评论
首页
栏目
默认分类
HTML CSS
HTML基础
CSS
HTML5 CSS3
javaScript
javaScript基础
javaScript高级
Web APIs
jQuery
js小总结
WEB开发布局
Vue
PS切图
数据可视化
Git使用
Uniapp
c语言入门
标准库
嵌入式
页面
前端面试题
前端报错总结
电子书
插件下载
搜索到
104
篇与
的结果
2021-09-12
js小技巧
{mtitle style='font-size:25px' title="数组扁平化"/}数组扁平化是将一个多维数组变为一个一维数组:const arr = [1, [2, [3, [ 4,5 ]]],6 ] // => [1,2,3,4,5,6]方法一:使用flat()const arr = [1, [2, [3, [ 4,5 ]]],6 ] // => [1,2,3,4,5,6] const res1 = arr.flat(Infinity);方法二:利用正则const arr = [1, [2, [3, [ 4,5 ]]],6 ] // => [1,2,3,4,5,6] const res2 = JSON.stringify(arr).replace(/\[|\]/g,'').split(',');注:但数据类型都会变为字符串方法三:正则改良版本const arr = [1, [2, [3, [ 4,5 ]]],6 ] // => [1,2,3,4,5,6] const res3 = JSON.parse('[' + JSON.stringify(arr).replace(/\[|\]/g,'') + ']');方法四:使用reduceconst arr = [1, [2, [3, [ 4,5 ]]],6 ] // => [1,2,3,4,5,6] const flatten = arr => { return arr.reduce((pre, cur) => { return pre.concat(Array.isArray(cur) ? flatten(cur) : cur); }, []) } const res4 = flatten(arr)方法五:函数递归const arr = [1, [2, [3, [ 4,5 ]]],6 ] // => [1,2,3,4,5,6] const res5 = []; const fn = arr => { for (let i = 0; i < arr.length; i++){ if (Array.isArray(arr[i])) { fn(arr[i]); } else { res5.push(arr[i]); } } } fn(arr);{mtitle style='font-size:25px' title="数组去重"/}代码和处理后结果如下:const arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}]; // => [1, '1', 17, true, false, 'true', 'a', {}, {}]方法一:利用Setconst arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}]; // => [1, '1', 17, true, false, 'true', 'a', {}, {}] const res1 = Array.from(new Set(arr));方法二:双层for循环+spliceconst arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}]; // => [1, '1', 17, true, false, 'true', 'a', {}, {}] const unique1 = arr => { let len = arr.length; for (let i = 0; i < len; i++) { for (let j = i + 1; j < len; j++) { if (arr[i] === arr[j]){ arr.splice(j ,1); //每删除一个数,j--保证j的值经过自加后不变。同时,len--,减少循环次数提升性能 len--; j--; } } } return arr; }方法三:利用indexOfconst arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}]; // => [1, '1', 17, true, false, 'true', 'a', {}, {}] const unique2 = arr => { const res = []; for (let i = 0; i < arr.length; i++) { if (res.indexOf(arr[i]) === -1) res.push(arr[i]); } return res; }方法四:利用includeconst arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}]; // => [1, '1', 17, true, false, 'true', 'a', {}, {}] const unique3 = arr => { const res = []; for (let i = 0; i < arr.length; i++) { if (!res.includes(arr[i])) res.push(arr[i]); } return res; }方法五:利用filterconst arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}]; // => [1, '1', 17, true, false, 'true', 'a', {}, {}] const unique4 = arr => { return arr.filter((item, index) => { return arr.indexOf(item) === index; }); }方法六:利用Mapconst arr = [1, 1, '1', 17, true, true, false, false, 'true', 'a', {}, {}]; // => [1, '1', 17, true, false, 'true', 'a', {}, {}] const unique5 = arr => { const map = new Map(); const res = []; for (let i = 0; i < arr.length; i++) { if(!map.has(arr[i])) { map.set(arr[i], true) res.push(arr[i]); } } return res; }{mtitle style='font-size:25px' title="类数组转化为数组"/}类数组是具有length属性,但不具有数组原型上的方法。常见的类数组有arguments、DOM操作方法返回的结果。方法一:Array.fromArray.from(document.querySelectorAll('div'))方法二:Array.prototype.slice.call()Array.prototype.slice.call(document.querySelectorAll('div'))方法三:扩展运算符[...document.querySelectorAll('div')]方法四:利用concatArray.prototype.apply([], document.querySelectorAll('div')){mtitle style='font-size:25px' title="Array.prototype.filter()"/}语法:var newArray = arr.filter(callback(element[, index[, array]])[, thisArg])参数callback用来测试数组的每个元素的函数。返回 true 表示该元素通过测试,保留该元素,false 则不保留。它接受以下三个参数: element 数组中当前正在处理的元素。 index可选 正在处理的元素在数组中的索引。 array可选 调用了 filter 的数组本身。thisArg可选执行 callback 时,用于 this 的值。返回值一个新的、由通过测试的元素组成的数组,如果没有任何数组元素通过测试,则返回空数组。Array.prototype.filter = function(callback, thisArg) { if (this == undefined) { throw new TypeError('this is null or not undefined'); } if (typeof callback !== 'function') { throw new TypeError(callback + 'is null or not undefined'); } const res = []; // 让o成为回调函数的对象传递(强制转换对象) const o = Object(this); // >>>0 保证len为number,且为正整数 const len = o.length >>> 0; for (let i = 0; i < len; i++) { // 检查i是否在o的属性(会检查原型链) if (i in o) { // 回调函数调用传参 if (callback.call(thisAry, o[i], i, o)) { res.push(o[i]); } } } return res; }{mtitle style='font-size:25px' title="Array.prototype.map()"/}语法:var new_array = arr.map(function callback(currentValue[, index[, array]]) { // 返回一个新数组 }[, thisArg])参数callback生成新数组元素的函数,使用三个参数: currentValue callback 数组中正在处理的当前元素。 index可选 callback 数组中正在处理的当前元素的索引。 array可选 map 方法调用的数组。thisArg可选执行 callback 函数时值被用作this。返回值一个由原数组每个元素执行回调函数的结果组成的新数组。Array.prototype.map = function(callback, thisArg) { if (this == undefined) { throw new TypeError('this is null or not undefined'); } if (typeof callback !== 'function') { throw new TypeError(callback + 'is null or not undefined'); } const res = []; // 让o成为回调函数的对象传递(强制转换对象) const o = Object(this); // >>>0 保证len为number,且为正整数 const len = o.length >>> 0; for (let i = 0; i < len; i++) { // 检查i是否在o的属性(会检查原型链) if (i in o) { // 回调函数调用传参 res[i] = callback.call(thisAry, o[i], i , this); } } return res; }{mtitle style='font-size:25px' title="Array.prototype.forEach()"/}语法myMap.forEach(callback([value][,key][,map])[, thisArg])参数callbackmyMap 中每个元素所要执行的函数。它具有如下的参数: value 可选 每个迭代的值。 key 可选 每个迭代的键。 map 可选 被迭代的map(上文语法框中的 myMap)。thisArg 可选在 callback 执行中使用的 this 的值。返回值undefined. forEach跟map类似,唯一不同的是forEach是没有返回值的。 Array.prototype.forEach = function(callback, thisArg) { if (this == null) { throw new TypeError('this is null or not undefined'); } if (typeof callback !== 'function') { throw new TypeError(callback + 'is null or not undefined'); } // 让o成为回调函数的对象传递(强制转换对象) const o = Object(this); // >>>0 保证len为number,且为正整数 const len = o.length >>> 0; let k = 0; while(k < len){ if(k in o){ callback.call(thisArg, o[k], k, o); } k++; } }{mtitle style='font-size:25px' title="Array.prototype.reduce()"/}语法arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])参数callback执行数组中每个值 (如果没有提供 initialValue则第一个值除外)的函数,包含四个参数: accumulator 累计器累计回调的返回值; 它是上一次调用回调时返回的累积值,或initialValue(见于下方)。 currentValue 数组中正在处理的元素。 index 可选 数组中正在处理的当前元素的索引。 如果提供了initialValue,则起始索引号为0,否则从索引1起始。 array可选 调用reduce()的数组initialValue可选作为第一次调用 callback函数时的第一个参数的值。 如果没有提供初始值,则将使用数组中的第一个元素。 在没有初始值的空数组上调用 reduce 将报错。返回值函数累计处理的结果Array.prototype.forEach = function(callback, thisArg) { if (this == undefined) { throw new TypeError('this is null or not undefined'); } if (typeof callback !== 'function') { throw new TypeError(callback + 'is null or not undefined'); } // 让o成为回调函数的对象传递(强制转换对象) const o = Object(this); // >>>0 保证len为number,且为正整数 const len = o.length >>> 0; let accumulator = initialValue; let k = 0; //如果第二个参数为undefined的情况下 //则数组的第一个有效值最为累加器的初始值 if(accumulator === undefined) { while(k < len && !(k in o)) { k++; //如果超出数组界限还没有找到累加器的初始值,则TypeError if(k >=len) { throw new TypeError('Reduce of empty array with on initial value'); } accumulator = o[k++]; } while (k < len) { if(k in o){ accumulator = callback.call(undefined, accumulator, o[k], k ,o); } k++; } return accumulator; }{mtitle style='font-size:25px' title="Array.prototype.apply()"/}第一个参数是绑定的this,默认为window,第二个参数是数组或类数组。Function.prototype.apply= function(context=window, args){ if(typeof this !== 'function') { throw new TypeError('Type Error'); } const fn = Symbol('fn'); context[fn] = this; const res = context[fn](...args); delete context[fn]; return res; }{mtitle style='font-size:25px' title="Array.prototype.call()"/}注意:该方法的语法和作用与 apply() 方法类似,只有一个区别,就是 call() 方法接受的是一个参数列表,而 apply() 方法接受的是一个包含多个参数的数组。Function.prototype.call= function(context=window, ...args){ if(typeof this !== 'function') { throw new TypeError('Type Error'); } const fn = Symbol('fn'); context[fn] = this; const res = context[fn](...args); delete context[fn]; return res; }{mtitle style='font-size:25px' title="Array.prototype.bind()"/}bind() 函数会创建一个新的绑定函数(bound function,BF)。绑定函数是一个 exotic function object(怪异函数对象,ECMAScript 2015 中的术语),它包装了原函数对象。调用绑定函数通常会导致执行包装函数。Function.prototype.bind= function(context, ...args){ if(typeof this !== 'function') { throw new Error('Type Error'); } // 保存this的值 var self = this; return function F(){ //考虑new的情况 if(this instanceof F){ return new self(...args, ...arguments) } return self.apply(context,[...args, ...arguments]) } }{mtitle style='font-size:25px' title="debounce(防抖)"/}触发高频时间后n秒内函数只会执行一次,如果n秒内高频时间再次触发,则重新计算时间const debounce = (fn, time) => { let timeout = null; return function() { clearTimeout(timeout); timeout = setTimeout(() => { fn.apply(this, arguments); }, time); } }{mtitle style='font-size:25px' title="throttle(节流)"/}高频时间触发,但n秒内只会执行一次,所以节流会稀释函数的执行频率。const throttle = (fn, time) => { let flag = true; return function() { if (!flag) return; flag = false; setTimeout(() => { fn.apply(this, arguments); flag = true; } , time); } } //第二种写法 非定时器写法 function fun(fn,time){ var activeTime=0 return ()=>{ var current =new Date() if(current-activeTime>time){ fn.apply(this,arguments) activeTime=new Date() } } }注: 节流常应用于鼠标不断点击触发 、 监听滚动事件{mtitle style='font-size:25px' title="函数柯理化"/}指的是将一个接受多个参数的函数变为接受一个参数返回一个函数的固定形式,这样便于再次调用,列如f(1)(2)。经典面试题:实现add(1)(2)(3)(4)=10;、add(1)(1,2,3)(2)=9function add() { const _args = [...arguments]; function fn() { _args.push(...arguments); return fu; } fn.toString = function() { return _args.reduce((sum, cur) => sum + cur); } return fn; }{mtitle style='font-size:25px' title="模拟new操作"/}3个步骤:以ctor.prototype为原型创建一个对象。执行构造函数并将this绑定到新创建的对象上。判断构造函数执行返回的结果是否引用数据类型,若是则返回构造函数执行的结果,否则返回创建的对象。function newOperator(ctor, ...args) { if (typeof ctor !== 'function') { throw new TypeError('Type Error'); } const obj = Object.create(ctor.prototype); const res = ctor.apply(obj, args); const isObject = typeof res === 'object' && res !== null; const isFunction = typeof res === 'function'; return isObject || isFunction ? res : obj; }{mtitle style='font-size:25px' title="instanceof"/}instanceof运算符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上const myInstanceof = (left, right) => { //基于数据类型都返回false if (typeof left !== 'object' || left === null) return false; let proto = Object.getPrototypeOf(left); while (true) { if (proto === null) return false; if (proto === right.prototype) return true; proto = Object.getPrototypeOf(proto); } }{mtitle style='font-size:25px' title="原型继承"/}这里只写寄生组合继承了,中间还有几个演变过来的继承但是有一定缺陷。function Parent(){ this.name='parent'; } function Child(){ Parent.call(this); this.type='children'; } Child.prototype=Object.create(Parent.prototype); Child.prototype.constructor=Child;{mtitle style='font-size:25px' title="Object.is"/}Object.is解决的主要的这两个问题+0 === -0 //true NaN === NaN //false const is = (x, y) => { if (x === y) { // +0和-0应该不相等 return x !== 0 || y !== 0 || 1 / x === 1 / y; } else { return x !== x && y !== y; } }{mtitle style='font-size:25px' title="Object.assign"/}Object.assign()方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象(请注意这个操作是浅拷贝)Object.defineProperty(Object, 'assign', { value: function(target, ...args) { if (target == null) { return new TypeError('Cannot convert undefined or null to object'); } //目标对象需要统一是引用数据类型,若不是会自动转换。 const to = Object(target); for (let i = 0; i < args.length; i++) { //每一个源对象 const nextSource = args[i]; if (nextSource !== null) { //使用for...in和hasOwnProperty双重判断,确保只拿到本身属性,方法(不包含继承的) for (const nextKey in nextSource) { if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { to[nextKey] = nextSource[nextKey]; } } } } return to; }, //不可枚举 enumerable:false, writable:true, configurable:true, }){mtitle style='font-size:25px' title="深拷贝"/}递归的完整版本(考虑到了Symbol属性)const cloneDeep1 = (target, hash = new WeakMap()) => { //对于传入参数处理 if (typeof target !== 'object' || target === null) { return target; } //哈希表中存在直接返回 if (hash.has(target)) return hash.get(target); const cloneTarget = Array.isArray(target) ? [] : {}; hash.set(target, cloneTarget); //针对Symbol属性 const symKeys = Object.getOwnPropertySymbols(target); if (symKeys.length) { symKeys.forEach(Symbol => { if (typeof target[symKeys] === 'object' && target[symKeys] !== null) { cloneTarget[symKeys] = cloneDeep1(target[symKeys]); } else { cloneTarget[symKeys] = target[symKeys]; } }) } for (const i in target) { if (Object.prototype.hasOwnProperty.call(target, i)) { cloneTarget[i] = typeof target[i] === 'object' && target[i] !== null ? cloneDeep1(target[i].hash) : target[i] } } return cloneTarget; }{mtitle style='font-size:25px' title="Promise"/}
2021年09月12日
5 阅读
0 评论
0 点赞
2021-09-09
28个常用JavaScript方法集锦
经常使用的 JS 方法,今天记下,以便以后查询手机类型判断代码如下:var BrowserInfo = { userAgent: navigator.userAgent.toLowerCase() isAndroid: Boolean(navigator.userAgent.match(/android/ig)), isIphone: Boolean(navigator.userAgent.match(/iphone|ipod/ig)), isIpad: Boolean(navigator.userAgent.match(/ipad/ig)), isWeixin: Boolean(navigator.userAgent.match(/MicroMessenger/ig)), }返回字符串长度,汉子计数为2代码如下:function strLength(str) { var a = 0; for (var i = 0; i < str.length; i++) { if (str.charCodeAt(i) > 255) a += 2;//按照预期计数增加2 else a++; } return a; }获取url中的参数代码如下:function GetQueryStringRegExp(name,url) { var reg = new RegExp("(^|\\?|&)" + name + "=([^&]*)(\\s|&|$)", "i"); if (reg.test(url)) return decodeURIComponent(RegExp.$2.replace(/\+/g, " ")); return ""; }js 绑定事件 适用于任何浏览器的元素绑定代码如下:function eventBind(obj, eventType, callBack) { if (obj.addEventListener) { obj.addEventListener(eventType, callBack, false); } else if (window.attachEvent) { obj.attachEvent('on' + eventType, callBack); } else { obj['on' + eventType] = callBack; } }; eventBind(document, 'click', bodyClick);获得当前浏览器JS的版本代码如下:function getjsversion(){ var n = navigator; var u = n.userAgent; var apn = n.appName; var v = n.appVersion; var ie = v.indexOf('MSIE '); if (ie > 0){ apv = parseInt(i = v.substring(ie + 5)); if (apv > 3) { apv = parseFloat(i); } } else { apv = parseFloat(v); } var isie = (apn == 'Microsoft Internet Explorer'); var ismac = (u.indexOf('Mac') >= 0); var javascriptVersion = "1.0"; if (String && String.prototype) { javascriptVersion = '1.1'; if (javascriptVersion.match) { javascriptVersion = '1.2'; var tm = new Date; if (tm.setUTCDate) { javascriptVersion = '1.3'; if (isie && ismac && apv >= 5) javascriptVersion = '1.4'; var pn = 0; if (pn.toPrecision) { javascriptVersion = '1.5'; a = new Array; if (a.forEach) { javascriptVersion = '1.6'; i = 0; o = new Object; tcf = new Function('o', 'var e,i=0;try{i=new Iterator(o)}catch(e){}return i'); i = tcf(o); if (i && i.next) { javascriptVersion = '1.7'; } } } } } } return javascriptVersion; } 获取当前点击事件的Object对象代码如下:function getEvent() { if (document.all) { return window.event; //如果是ie } func = getEvent.caller; while (func != null) { var arg0 = func.arguments[0]; if (arg0) { if ((arg0.constructor == Event || arg0.constructor == MouseEvent) || (typeof (arg0) == "object" && arg0.preventDefault && arg0.stopPropagation)) { return arg0; } } func = func.caller; } return null; };字符串截取方法代码如下:getCharactersLen: function (charStr, cutCount) { if (charStr == null || charStr == '') return ''; var totalCount = 0; var newStr = ''; for (var i = 0; i < charStr.length; i++) { var c = charStr.charCodeAt(i); if (c < 255 && c > 0) { totalCount++; } else { totalCount += 2; } if (totalCount >= cutCount) { newStr += charStr.charAt(i); break; } else { newStr += charStr.charAt(i); } } return newStr; }JS 弹出新窗口全屏代码如下:var tmp = window.open("about:blank", "", "fullscreen=1") tmp.moveTo(0, 0); tmp.resizeTo(screen.width + 20, screen.height); tmp.focus(); tmp.location.href = 'http://www.che168.com/pinggu/eva_' + msgResult.message[0] + '.html'; var config_ = "left=0,top=0,width=" + (window.screen.Width) + ",height=" + (window.screen.Height); window.open('http://www.che168.com/pinggu/eva_' + msgResult.message[0] + '.html', "winHanle", config_); //模拟form提交打开新页面 var f = document.createElement("form"); f.setAttribute('action', 'http://www.che168.com/pinggu/eva_' + msgResult.message[0] + '.html'); f.target = '_blank'; document.body.appendChild(f); f.submit();全选/全不选代码如下:function selectAll(objSelect) { if (objSelect.checked == true) { $("input[name='chkId']").attr("checked", true); $("input[name='chkAll']").attr("checked", true); } else if (objSelect.checked == false) { $("input[name='chkId']").attr("checked", false); $("input[name='chkAll']").attr("checked", false); } }js 判断浏览器代码如下:判断是否是 IE 浏览器 if (document.all){ alert(”IE浏览器”); }else{ alert(”非IE浏览器”); } if (!!window.ActiveXObject){ alert(”IE浏览器”); }else{ alert(”非IE浏览器”); }判断是IE几var isIE=!!window.ActiveXObject; var isIE6=isIE&&!window.XMLHttpRequest; var isIE8=isIE&&!!document.documentMode; var isIE7=isIE&&!isIE6&&!isIE8; if (isIE){ if (isIE6){ alert(”ie6″); }else if (isIE8){ alert(”ie8″); }else if (isIE7){ alert(”ie7″); } }判断浏览器代码如下:function getOs() { if (navigator.userAgent.indexOf("MSIE 8.0") > 0) { return "MSIE8"; } else if (navigator.userAgent.indexOf("MSIE 6.0") > 0) { return "MSIE6"; } else if (navigator.userAgent.indexOf("MSIE 7.0") > 0) { return "MSIE7"; } else if (isFirefox = navigator.userAgent.indexOf("Firefox") > 0) { return "Firefox"; } if (navigator.userAgent.indexOf("Chrome") > 0) { return "Chrome"; } else { return "Other"; } }JS判断两个日期大小 适合 2012-09-09 与2012-9-9 两种格式的对比代码如下://得到日期值并转化成日期格式,replace(/\-/g, "\/")是根据验证表达式把日期转化成长日期格式,这样再进行判断就好判断了 function ValidateDate() { var beginDate = $("#t_datestart").val(); var endDate = $("#t_dateend").val(); if (beginDate.length > 0 && endDate.length>0) { var sDate = new Date(beginDate.replace(/\-/g, "\/")); var eDate= new Date(endDate.replace(/\-/g, "\/")); if (sDate > eDate) { alert('开始日期要小于结束日期'); return false; } } }移除事件代码如下:this.moveBind = function (objId, eventType, callBack) { var obj = document.getElementById(objId); if (obj.removeEventListener) { obj.removeEventListener(eventType, callBack, false); } else if (window.detachEvent) { obj.detachEvent('on' + eventType, callBack); } else { obj['on' + eventType] = null; } }回车提交代码如下:$("id").onkeypress = function (event) { event = (event) ? event : ((window.event) ? window.event : "") keyCode = event.keyCode ? event.keyCode : (event.which ? event.which : event.charCode); if (keyCode == 13) { $("SubmitLogin").onclick(); } }JS 执行计时器代码如下:timeStart = new Date().getTime(); timesEnd = new Date().getTime(); document.getElementById("time").innerHTML = timesEnd - timeStart;JS 写Cookie代码如下:function setCookie(name, value, expires, path, domain) { if (!expires) expires = -1; if (!path) path = "/"; var d = "" + name + "=" + value; var e; if (expires < 0) { e = ""; } else if (expires == 0) { var f = new Date(1970, 1, 1); e = ";expires=" + f.toUTCString(); } else { var now = new Date(); var f = new Date(now.getTime() + expires * 1000); e = ";expires=" + f.toUTCString(); } var dm; if (!domain) { dm = ""; } else { dm = ";domain=" + domain; } document.cookie = name + "=" + value + ";path=" + path + e + dm; };JS 读Cookie代码如下:function readCookie(name) { var nameEQ = name + "="; var ca = document.cookie.split(';'); for (var i = 0; i < ca.length; i++) { var c = ca[i]; while (c.charAt(0) == ' ') c = c.substring(1, c.length); if (c.indexOf(nameEQ) == 0) { return decodeURIComponent(c.substring(nameEQ.length, c.length)) } } return null }Ajax 请求代码如下:C.ajax = function (args) { var self = this; this.options = { type: 'GET', async: true, contentType: 'application/x-www-form-urlencoded', url: 'about:blank', data: null, success: {}, error: {} }; this.getXmlHttp = function () { var xmlHttp; try { xmlhttp = new XMLHttpRequest(); } catch (e) { try { xmlhttp = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { xmlHttp = new ActiveXObject("Microsoft.XMLHTTP"); } } if (!xmlhttp) { alert('您的浏览器不支持AJAX'); return false; } return xmlhttp; }; this.send = function () { C.each(self.options, function (key, val) { self.options[key] = (args[key] == null) ? val : args[key]; }); var xmlHttp = new self.getXmlHttp(); if (self.options.type.toUpperCase() == 'GET') { xmlHttp.open(self.options.type, self.options.url + (self.options.data == null ? "" : ((/[?]$/.test(self.options.url) ? '&' : '?') + self.options.data)), self.options.async); } else { xmlHttp.open(self.options.type, self.options.url, self.options.async); xmlHttp.setRequestHeader('Content-Length', self.options.data.length); } xmlHttp.setRequestHeader('Content-Type', self.options.contentType); xmlHttp.onreadystatechange = function () { if (xmlHttp.readyState == 4) { if (xmlHttp.status == 200 || xmlHttp.status == 0) { if (typeof self.options.success == 'function') self.options.success(xmlHttp.responseText); xmlHttp = null; } else { if (typeof self.options.error == 'function') self.options.error('Server Status: ' + xmlHttp.status); } } }; xmlHttp.send(self.options.type.toUpperCase() == 'POST' ? self.options.data.toString() : null); }; this.send(); };JS StringBuilder 用法代码如下:function StringBuilder() { this.strings = new Array; }; StringBuilder.prototype.append = function (str) { this.strings.push(str); }; StringBuilder.prototype.toString = function () { return this.strings.join(''); };JS 加载到顶部LoadJS代码如下:function loadJS (url, fn) { var ss = document.getElementsByName('script'), loaded = false; for (var i = 0, len = ss.length; i < len; i++) { if (ss[i].src && ss[i].getAttribute('src') == url) { loaded = true; break; } } if (loaded) { if (fn && typeof fn != 'undefined' && fn instanceof Function) fn(); return false; } var s = document.createElement('script'), b = false; s.setAttribute('type', 'text/javascript'); s.setAttribute('src', url); s.onload = s.onreadystatechange = function () { if (!b && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')) { b = true; if (fn && typeof fn != 'undefined' && fn instanceof Function) fn(); } }; document.getElementsByTagName('head')[0].appendChild(s); }, bind: function (objId, eventType, callBack) { //适用于任何浏览器的绑定 var obj = document.getElementById(objId); if (obj.addEventListener) { obj.addEventListener(eventType, callBack, false); } else if (window.attachEvent) { obj.attachEvent('on' + eventType, callBack); } else { obj['on' + eventType] = callBack; } } function JSLoad (args) { s = document.createElement("script"); s.setAttribute("type", "text/javascript"); s.setAttribute("src", args.url); s.onload = s.onreadystatechange = function () { if (!s.readyState || s.readyState == "loaded" || s.readyState == "complete") { if (typeof args.callback == "function") args.callback(this, args); s.onload = s.onreadystatechange = null; try { s.parentNode && s.parentNode.removeChild(s); } catch (e) { } } }; document.getElementsByTagName("head")[0].appendChild(s); }清空 LoadJS 加载到顶部的js引用代码如下:function ClearHeadJs (src) { var js = document.getElementsByTagName('head')[0].children; var obj = null; for (var i = 0; i < js.length; i++) { if (js[i].tagName.toLowerCase() == "script" && js[i].attributes['src'].value.indexOf(src) > 0) { obj = js[i]; } } document.getElementsByTagName('head')[0].removeChild(obj); };JS 替换非法字符主要用在密码验证上出现的特殊字符代码如下:function URLencode(sStr) { return escape(sStr).replace(/\+/g, '%2B').replace(/\"/g, '%22').replace(/\'/g, '%27').replace(/\//g, '%2F'); };按Ctrl + Entert 直接提交表单代码如下:document.body.onkeydown = function (evt) { evt = evt ? evt : (window.event ? window.event : null); if (13 == evt.keyCode && evt.ctrlKey) { evt.returnValue = false; evt.cancel = true; PostData(); } }; 获取当前时间代码如下:function GetCurrentDate() { var d = new Date(); var y = d.getYear()+1900; month = add_zero(d.getMonth() + 1), days = add_zero(d.getDate()), hours = add_zero(d.getHours()); minutes = add_zero(d.getMinutes()), seconds = add_zero(d.getSeconds()); var str = y + '-' + month + '-' + days + ' ' + hours + ':' + minutes + ':' + seconds; return str; }; function add_zero(temp) { if (temp < 10) return "0" + temp; else return temp; } Js 去掉空格方法:代码如下:String.prototype.Trim = function() { return this.replace(/(^\s*)|(\s*$)/g, ""); } String.prototype.LTrim = function() {return this.replace(/(^\s*)/g, "");} String.prototype.RTrim = function() {return this.replace(/(\s*$)/g, "");}js 动态移除 head 里的 js 引用代码如下:this.ClearHeadJs = function (src) { var js = document.getElementsByTagName('head')[0].children; var obj = null; for (var i = 0; i < js.length; i++) { if (js[i].tagName.toLowerCase() == "script" && js[i].attributes['src'].value.indexOf(src) > 0) { obj = js[i]; } } document.getElementsByTagName('head')[0].removeChild(obj); };整个UL 点击事件 加在UL里的onclick里代码如下:function CreateFrom(url, params) { var f = document.createElement("form"); f.setAttribute("action", url); for (var i = 0; i < params.length; i++) { var input = document.createElement("input"); input.setAttribute("type", "hidden"); input.setAttribute("name", params[i].paramName); input.setAttribute("value", params[i].paramValue); f.appendChild(input); } f.target = "_blank"; document.body.appendChild(f); f.submit(); };判断浏览器使用的是哪个 JS 版本代码如下:<script language="javascript"> var jsversion = 1.0; </script> <script language="javascript1.1"> jsversion = 1.1; </script> <script language="javascript1.2"> jsversion = 1.2; </script> <script language="javascript1.3"> jsversion = 1.3; </script> <script language="javascript1.4"> jsversion = 1.4; </script> <script language="javascript1.5"> jsversion = 1.5; </script> <script language="javascript1.6"> jsversion = 1.6; </script> <script language="javascript1.7"> jsversion = 1.7; </script> <script language="javascript1.8"> jsversion = 1.8; </script> <script language="javascript1.9"> jsversion = 1.9; </script> <script language="javascript2.0"> jsversion = 2.0; </script> alert(jsversion);
2021年09月09日
3 阅读
0 评论
0 点赞
2021-09-04
HTML5 的新特性 CSS3 的新特性-选择器 CSS3 的新特性-盒子模型&其他特性
HTML5新特性概述HTML5 的新增特性主要是针对于以前的不足,增加了一些新的标签、新的表单和新的表单属性等。 这些新特性都有兼容性问题,基本是 IE9+ 以上版本的浏览器才支持,如果不考虑兼容性问题,可以大量使用这些新特性。语义化标签 (★★)以前布局,我们基本用 div 来做。div 对于搜索引擎来说,是没有语义的<div class=“header”> </div> <div class=“nav”> </div> <div class=“content”> </div> <div class=“footer”> </div>发展到了HTML5后,新增了一些语义化标签,这样的话更加有利于浏览器的搜索引擎搜索,也方便了网站的seo(Search Engine Optimization,搜索引擎优化),下面就是新增的一些语义化标签<header> 头部标签<nav> 导航标签<article> 内容标签<section> 定义文档某个区域<aside> 侧边栏标签<footer> 尾部标签多媒体标签多媒体标签分为 音频 audio 和视频 video 两个标签 使用它们,我们可以很方便的在页面中嵌入音频和视频,而不再去使用落后的flash和其他浏览器插件了。因为多媒体标签的 属性、方法、事件比较多,因此我们需要什么功能的时候,就需要去查找相关的文档进行学习使用。视频标签- video(★★★)基本使用当前 元素支持三种视频格式: 尽量使用 mp4格式使用语法: <video src="media/mi.mp4"></video>兼容写法由于各个浏览器的支持情况不同,所以我们会有一种兼容性的写法,这种写法了解一下即可<video controls="controls" width="300"> <source src="move.ogg" type="video/ogg" > <source src="move.mp4" type="video/mp4" > 您的浏览器暂不支持 <video> 标签播放视频 </ video >上面这种写法,浏览器会匹配video标签中的source,如果支持就播放,如果不支持往下匹配,直到没有匹配的格式,就提示文本video 常用属性属性很多,有一些属性需要大家重点掌握:autoplay 自动播放注意: 在google浏览器上面,默认禁止了自动播放,如果想要自动播放的效果,需要设置 muted属性width 宽度height 高度loop 循环播放src 播放源muted 静音播放示例代码:<video src="media/mi.mp4" autoplay="autoplay" muted="muted" loop="loop" poster="media/mi9.jpg"></video>音频标签- audio基本使用当前 元素支持三种视频格式: 尽量使用 mp3格式使用语法:<audio src="media/music.mp3"></audio>兼容写法由于各个浏览器的支持情况不同,所以我们会有一种兼容性的写法,这种写法了解一下即可< audio controls="controls" > <source src="happy.mp3" type="audio/mpeg" > <source src="happy.ogg" type="audio/ogg" > 您的浏览器暂不支持 <audio> 标签。 </ audio>上面这种写法,浏览器会匹配audio标签中的source,如果支持就播放,如果不支持往下匹配,直到没有匹配的格式,就提示文本audio 常用属性示例代码:<audio src="media/music.mp3" autoplay="autoplay" controls="controls"></audio>小结音频标签和视频标签使用方式基本一致浏览器支持情况不同谷歌浏览器把音频和视频自动播放禁止了我们可以给视频标签添加 muted 属性来静音播放视频,音频不可以(可以通过JavaScript解决)视频标签是重点,我们经常设置自动播放,不使用 controls 控件,循环和设置大小属性新增的表单元素 (★★)在H5中,帮我们新增加了很多类型的表单,这样方便了程序员的开发课堂案例:在这个案例中,熟练了新增表单的用法案例代码:<!-- 我们验证的时候必须添加form表单域 --> <form action=""> <ul> <li>邮箱: <input type="email" /></li> <li>网址: <input type="url" /></li> <li>日期: <input type="date" /></li> <li>时间: <input type="time" /></li> <li>数量: <input type="number" /></li> <li>手机号码: <input type="tel" /></li> <li>搜索: <input type="search" /></li> <li>颜色: <input type="color" /></li> <!-- 当我们点击提交按钮就可以验证表单了 --> <li> <input type="submit" value="提交"></li> </ul> </form>常见输入类型text password radio checkbox button file hidden submit reset image新的输入类型类型很多,我们现阶段重点记忆三个: number tel searchCSS3新特性CSS3 的现状新增的CSS3特性有兼容性问题,ie9+才支持移动端支持优于 PC 端不断改进中应用相对广泛现阶段主要学习:新增选择器和盒子模型以及其他特性CSS3 新增选择器CSS3 给我们新增了选择器,可以更加便捷,更加自由的选择目标元素。属性选择器结构伪类选择器伪元素选择器属性选择器(★★)属性选择器,按照字面意思,都是根据标签中的属性来选择元素示例代码: /* 只选择 type =text 文本框的input 选取出来 */ input[type=text] { color: pink; } /* 选择首先是div 然后 具有class属性 并且属性值 必须是 icon开头的这些元素 */ div[class^=icon] { color: red; } /* 选择首先是section 然后 具有class属性 并且属性值 必须是 data结尾的这些元素 */ section[class$=data] { color: blue; }属性选择器,按照字面意思,都是根据标签中的属性来选择元素属性选择器可以根据元素特定属性的来选择元素。 这样就可以不用借助于类或者id选择器属性选择器也可以选择出来自定义的属性注意:类选择器、属性选择器、伪类选择器,权重为 10。结构伪类选择器结构伪类选择器主要根据文档结构来选择器元素, 常用于根据父级选择器里面的子元素E:first-child匹配父元素的第一个子元素E <style> ul li:first-child{ background-color: red; } </style> <ul> <li>列表项一</li> <li>列表项二</li> <li>列表项三</li> <li>列表项四</li> </ul>E:last-child 则是选择到了最后一个li标签E:nth-child(n)(★★★)匹配到父元素的第n个元素匹配到父元素的第2个子元素 ul li:nth-child(2){}匹配到父元素的序号为奇数的子元素ul li:nth-child(odd){} odd 是关键字 奇数的意思(3个字母 )匹配到父元素的序号为偶数的子元素ul li:nth-child(even){} even(4个字母 )匹配到父元素的前3个子元素ul li:nth-child(-n+3){} 选择器中的 n 是怎么变化的呢?因为 n是从 0 ,1,2,3.. 一直递增所以 -n+3 就变成了n=0 时 -0+3=3n=1时 -1+3=2n=2时 -2+3=1n=3时 -3+3=0...一些常用的公式: 公式不是死的,在这里列举出来让大家能够找寻到这个模式,能够理解代码,这样才能写出满足自己功能需求的代码常用的结构伪类选择器是: nth-child(n) {...}E:nth-child 与 E:nth-of-type 的区别这里只讲明 E:nth-child(n) 和 E:nth-of-type(n) 的区别 剩下的 E:first-of-type E:last-of-type E:nth-last-of-type(n) 同理做推导即可<style> ul li:nth-child(2){ /* 字体变成红色 */ color: red; } ul li:nth-of-type(2){ /* 背景变成绿色 */ background-color: green; } </style> <ul> <li>列表项一</li> <p>乱来的p标签</p> <li>列表项二</li> <li>列表项三</li> <li>列表项四</li> </ul>也就是说:E:nth-child(n) 匹配父元素的第n个子元素E,也就是说,nth-child 对父元素里面所有孩子排序选择(序号是固定的) 先找到第n个孩子,然后看看是否和E匹配E:nth-of-type(n) 匹配同类型中的第n个同级兄弟元素E,也就是说,对父元素里面指定子元素进行排序选择。 先去匹配E ,然后再根据E 找第n个孩子小结结构伪类选择器一般用于选择父级里面的第几个孩子nth-child 对父元素里面所有孩子排序选择(序号是固定的) 先找到第n个孩子,然后看看是否和E匹配nth-of-type 对父元素里面指定子元素进行排序选择。 先去匹配E ,然后再根据E 找第n个孩子关于 nth-child(n) 我们要知道 n 是从 0 开始计算的,要记住常用的公式如果是无序列表,我们肯定用 nth-child 更多类选择器、属性选择器、伪类选择器,权重为 10伪元素选择器(★★★)伪元素选择器可以帮助我们利用CSS创建新标签元素,而不需要HTML标签,从而简化HTML结构示例demo<style> div { width: 200px; height: 200px; background-color: pink; } /* div::before 权重是2 */ div::before { /* 这个content是必须要写的 */ content: '我'; } div::after { content: '小猪佩奇'; } </style> <body> <div> 是 </div> </body>注意:before 和 after 创建一个元素,但是属于行内元素新创建的这个元素在文档树中是找不到的,所以我们称为伪元素语法: element::before {}before 和 after 必须有 content 属性before 在父元素内容的前面创建元素,after 在父元素内容的后面插入元素伪元素选择器和标签选择器一样,权重为 1应用场景一: 字体图标在实际工作中,字体图标基本上都是用伪元素来实现的,好处在于我们不需要在结构中额外去定义字体图标的标签,通过content属性来设置字体图标的 编码步骤:结构中定义div盒子在style中先申明字体 @font-face在style中定义after伪元素 div::after{...}在after伪元素中 设置content属性,属性的值就是字体编码在after伪元素中 设置font-family的属性利用定位的方式,让伪元素定位到相应的位置;记住定位口诀:子绝父相<head> ... <style> @font-face { font-family: 'icomoon'; src: url('fonts/icomoon.eot?1lv3na'); src: url('fonts/icomoon.eot?1lv3na#iefix') format('embedded-opentype'), url('fonts/icomoon.ttf?1lv3na') format('truetype'), url('fonts/icomoon.woff?1lv3na') format('woff'), url('fonts/icomoon.svg?1lv3na#icomoon') format('svg'); font-weight: normal; font-style: normal; font-display: block; } div { position: relative; width: 200px; height: 35px; border: 1px solid red; } div::after { position: absolute; top: 10px; right: 10px; font-family: 'icomoon'; /* content: ''; */ content: '\e91e'; color: red; font-size: 18px; } </style> </head> <body> <div></div> </body>应用场景二: 仿土豆效果把之前的代码进行了改善步骤:找到之前写过的仿土豆的结构和样式,拷贝到自己的页面中删除之前的mask遮罩在style中,给大的div盒子(类名叫tudou的),设置 before伪元素这个伪元素充当的是遮罩的角色,所以我们不用设置内容,但是需要设置content属性,属性的值为空字符串给这个遮罩设置宽高,背景颜色,默认是隐藏的当鼠标移入到 div盒子时候,让遮罩显示,利用 hover 来实现<head> ... <style> .tudou { position: relative; width: 444px; height: 320px; background-color: pink; margin: 30px auto; } .tudou img { width: 100%; height: 100%; } .tudou::before { content: ''; /* 隐藏遮罩层 */ display: none; position: absolute; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, .4) url(images/arr.png) no-repeat center; } /* 当我们鼠标经过了 土豆这个盒子,就让里面before遮罩层显示出来 */ .tudou:hover::before { /* 而是显示元素 */ display: block; } </style> </head> <body> <div class="tudou"> <img src="images/tudou.jpg" alt=""> </div> <div class="tudou"> <img src="images/tudou.jpg" alt=""> </div> <div class="tudou"> <img src="images/tudou.jpg" alt=""> </div> <div class="tudou"> <img src="images/tudou.jpg" alt=""> </div> </body>应用场景三: 清除浮动回忆一下清除浮动的方式:额外标签法也称为隔墙法,是 W3C 推荐的做法。父级添加 overflow 属性父级添加after伪元素父级添加双伪元素额外标签法也称为隔墙法,是 W3C 推荐的做法注意: 要求这个新的空标签必须是块级元素后面两种伪元素清除浮动算是第一种额外标签法的一个升级和优化盒子模型(★★★)CSS3 中可以通过 box-sizing 来指定盒模型,有2个值:即可指定为 content-box、border-box,这样我们计算盒子大小的方式就发生了改变可以分成两种情况:box-sizing: content-box 盒子大小为 width + padding + border (以前默认的)box-sizing: border-box 盒子大小为 width如果盒子模型我们改为了box-sizing: border-box , 那padding和border就不会撑大盒子了(前提padding和border不会超过width宽度)其他特性(★)图标变模糊 -- CSS3滤镜filterfilter CSS属性将模糊或颜色偏移等图形效果应用于元素语法:filter: 函数(); --> 例如: filter: blur(5px); --> blur模糊处理 数值越大越模糊计算盒子宽度 -- calc 函数calc() 此CSS函数让你在声明CSS属性值时执行一些计算语法:width: calc(100% - 80px);括号里面可以使用 + - * / 来进行计算CSS3 过渡(★★★)过渡(transition)是CSS3中具有颠覆性的特征之一,我们可以在不使用 Flash 动画或 JavaScript 的情况下,当元素从一种样式变换为另一种样式时为元素添加效果。过渡动画: 是从一个状态 渐渐的过渡到另外一个状态可以让我们页面更好看,更动感十足,虽然 低版本浏览器不支持(ie9以下版本) 但是不会影响页面布局。我们现在经常和 :hover 一起 搭配使用。语法:transition: 要过渡的属性 花费时间 运动曲线 何时开始;属性 : 想要变化的 css 属性, 宽度高度 背景颜色 内外边距都可以 。如果想要所有的属性都变化过渡, 写一个all 就可以花费时间: 单位是 秒(必须写单位) 比如 0.5s运动曲线: 默认是 ease (可以省略)何时开始:单位是 秒(必须写单位)可以设置延迟触发时间 默认是 0s (可以省略)后面两个属性可以省略记住过渡的使用口诀: 谁做过渡给谁加过渡练习步骤:创建两个div的盒子,属于的嵌套关系,外层类名叫 bar,里层类名叫 bar_in给外层的bar 这个盒子设置边框,宽高,圆角边框给里层的bar_in 设置 初试的宽度,背景颜色,过渡效果给外层的 bar 添加 hover事件,当触发了hover事件 让里层的bar_in 来进行宽度的变化代码:<head> ... <style> .bar { width: 150px; height: 15px; border: 1px solid red; border-radius: 7px; padding: 1px; } .bar_in { width: 50%; height: 100%; background-color: red; /* 谁做过渡给谁加 */ transition: all .7s; } .bar:hover .bar_in { width: 100%; } </style> </head> <body> <div class="bar"> <div class="bar_in"></div> </div> </body>广义H5说法 了解狭隘H5广义H5广义的 HTML5 是 HTML5 本身 + CSS3 + JavaScript 。这个集合有时称为 HTML5 和朋友,通常缩写为 HTML5 。虽然 HTML5 的一些特性仍然不被某些浏览器支持,但是它是一种发展趋势。HTML5 MDN 介绍:https://developer.mozilla.org/zh-CN/docs/Web/Guide/HTML/HTML
2021年09月04日
6 阅读
0 评论
0 点赞
1
...
33
34
35