前端开发(HTML+CSS)
近些年来,一直从事后端开发,只有刚开始入行的时候,还是前后端不分离的时代,就是一套组合: jQuery + PHP
后来的工作中就是前后端分离的开发模式,也就专心从事后端的开发, 几经变更,后端语言也涉猎了很多, 但是前端的技术已经是日新月异.有些语法或者基础都已经不熟悉了, 至此总结,记录一番
JS)
1.进制转换
# 10进制转16进制 var num = 255 console.log(num.toString(16)) //输出:ff 或 console.log((255).toString(16)) 注意: 下面这种事错误的 console.log(255.toString(16)) //这样会报错 Invalid or unexpected token
# 16进制转10进制
parseInt("0x26F1627")
toString(); 方法: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Number/toString
2.apply, call
在 javascript 中,call 和 apply 都是为了改变某个函数运行时的上下文(context)而存在的,换句话说,就是为了改变函数体内部 this 的指向。
示例:
function fruits() {} fruits.prototype = { color: "red", say: function() { console.log("My color is " + this.color); } } var apple = new fruits; apple.say(); //My color is red
但是如果我们有一个对象banana= {color : "yellow"} ,我们不想对它重新定义 say 方法,那么我们可以通过 call 或 apply 用 apple 的 say 方法:
banana = { color: "yellow" } apple.say.call(banana); //My color is yellow apple.say.apply(banana); //My color is yellow
所以,可以看出 call 和 apply 是为了动态改变 this 而出现的,当一个 object 没有某个方法(本栗子中banana没有say方法),但是其他的有(apple有say方法),我们可以借助call或apply用其它对象的方法来操作。
apply、call 的区别
对于 apply、call 二者而言,作用完全一样,只是接受参数的方式不太一样。例如,有一个函数定义如下:
var func = function(arg1, arg2) {
};
func.call(
this
, arg1, arg2);
func.apply(
this
, [arg1, arg2])
其中 this 是你想指定的上下文,他可以是任何一个 JavaScript 对象(JavaScript 中一切皆对象),call 需要把参数按顺序传递进去,而 apply 则是把参数放在数组里。
常见使用:
// 数组追加 var array1 = [12 , "foo" , {name "Joe"} , -2458]; var array2 = ["Doe" , 555 , 100]; Array.prototype.push.apply(array1, array2); /* array1 值为 [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */ // 获取数组中最大值和最小值 var numbers = [5, 458 , 120 , -215 ]; var maxInNumbers = Math.max.apply(Math, numbers), //458 maxInNumbers = Math.max.call(Math,5, 458 , 120 , -215); //458 number 本身没有 max 方法,但是 Math 有,我们就可以借助 call 或者 apply 使用其方法 // 验证是否是数组(前提是toString()方法没有被重写过) functionisArray(obj){ return Object.prototype.toString.call(obj) === '[object Array]' ; }
更多参考:https://www.cnblogs.com/coco1s/p/4833199.html
3) es6中的Object.assign()
Object.assign方法用于对象的合并,将源对象( source )的所有可枚举属性,复制到目标对象( target )
var target = { a: 1 }; var source1 = { b: 2 }; var source2 = { c: 3 }; Object.assign(target, source1, source2); target // {a:1, b:2, c:3}
Object.assign方法的第一个参数是目标对象,后面的参数都是源对象。
注意,如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性。
如果只有一个参数,Object.assign会直接返回该参数。
var obj = {a: 1}; Object.assign(obj) === obj // true
如果该参数不是对象,则会先转成对象,然后返回。
typeof Object.assign(2) // "object"
由于undefined和null无法转成对象,所以如果它们作为参数,就会报错
Object.assign(undefined) // 报错 Object.assign(null) // 报错
如果非对象参数出现在源对象的位置(即非首参数),那么处理规则有所不同。首先,这些参数都会转成对象,如果无法转成对象,就会跳过。这意味着,如果undefined和null不在首参数,就不会报错。
let obj = {a: 1}; Object.assign(obj, undefined) === obj // true Object.assign(obj, null) === obj // true
其他类型的值(即数值、字符串和布尔值)不在首参数,也不会报错。但是,除了字符串会以数组形式,拷贝入目标对象,其他值都不会产生效果。
var v1 = 'abc'; var v2 = true; var v3 = 10; var obj = Object.assign({}, v1, v2, v3); console.log(obj); // { "0": "a", "1": "b", "2": "c" }
上面代码中,v1、v2、v3分别是字符串、布尔值和数值,结果只有字符串合入目标对象(以字符数组的形式),数值和布尔值都会被忽略。这是因为只有字符串的包装对象,会产生可枚举属性。
注意点
Object.assign方法实行的是浅拷贝,而不是深拷贝。也就是说,如果源对象某个属性的值是对象,那么目标对象拷贝得到的是这个对象的引用。
var obj1 = {a: {b: 1}}; var obj2 = Object.assign({}, obj1); obj1.a.b = 2; obj2.a.b // 2
上面代码中,源对象obj1的a属性的值是一个对象,Object.assign拷贝得到的是这个对象的引用。这个对象的任何变化,都会反映到目标对象上面。
对于这种嵌套的对象,一旦遇到同名属性,Object.assign的处理方法是替换,而不是添加。
var target = { a: { b: 'c', d: 'e' } } var source = { a: { b: 'hello' } } Object.assign(target, source) // { a: { b: 'hello' } }
上面代码中,target对象的a属性被source对象的a属性整个替换掉了,而不会得到{ a: { b: 'hello', d: 'e' } }的结果。这通常不是开发者想要的,需要特别小心。
4) void 的使用
在 JavaScript 中 void 是一元运算符,出现在操作数的左边,操作数可以是任意类型的值,void右边的表达式可以是带括号形式(例如:void(0)),也可以是不带括号的形式(例如:void 0)
从性能方面: void 0 比 undefined 少了三个字节
>"undefined".length 9 >"void 0".length 6
保证结果不变性
undefined并不是javascript中的保留字,我们可以使用undefined作为变量名字,然后给它赋值。void 0输出唯一的结果undefined,保证了不变性。
使用场景:
a)
(1)立即调用的函数表达式
在使用立即执行的函数表达式时,可以利用 void
运算符让 JavaScript 引擎把一个function
关键字识别成函数表达式而不是函数声明(语句)。
void function iife() { var bar = function () {}; var baz = function () {}; var foo = function () { bar(); baz(); }; var biz = function () {}; foo(); biz(); }();
b) javascript URIs
当用户点击一个以 javascript:
开头的URI 时,它会执行URI中的代码,然后用返回的值替换页面内容,除非返回的值是undefined
。void
运算符可用于返回undefined
。例如:
<a href="javascript:void(0);"> 这个链接点击之后不会做任何事情,如果去掉 void(), 点击之后整个页面会被替换成一个字符 0。 </a> <p> chrome中即使<a href="javascript:0;">也没变化,firefox中会变成一个字符串0 </p> <a href="javascript:void(document.body.style.backgroundColor='green');"> 点击这个链接会让页面背景变成绿色。 </a>
注意,虽然这么做是可行的,但利用 javascript:
伪协议来执行 JavaScript 代码是不推荐的,推荐的做法是为链接元素绑定事件。
(3)箭头函数中避免泄漏
箭头函数标准中,允许在函数体不使用括号来直接返回值。 如果右侧调用了一个原本没有返回值的函数,其返回值改变后,则会导致非预期的副作用。 安全起见,当函数返回值是一个不会被使用到的时候,应该使用 void
运算符,来确保返回 undefined
(如下方示例),这样,当 API 改变时,并不会影响箭头函数的行为。
button.onclick = () => void doSomething();
void 是 JavaScript 中的一种运算符,它用于返回一个未定义值(undefined)。它通常用于阻止某个表达式产生任何副作用。
工作原理
void 运算符接受一个表达式作为参数,并返回 undefined,无论该表达式的值是什么。这意味着它会忽略表达式的结果,只返回 undefined。
用法
void 运算符主要用于以下情况:
- 抑制函数或方法的返回值:可以将 void 用于函数或方法的调用,以忽略其返回值。
- 解决表达式中的错误:如果一个表达式产生错误,可以使用 void 来抑制错误,并继续执行代码。
- 防止副作用:void 可以防止某些表达式产生副作用,例如更改全局变量或进行 I/O 操作。
示例
// 抑制函数返回值 const result = void console.log('Hello world!'); // undefined // 解决表达式中的错误 const input = null; const length = void input.length; // undefined // 防止副作用 void fetch('https://example.com/'); // 不会进行网络请求
注意
- void 运算符不会改变表达式的值,因为它只返回 undefined。
- 虽然 void 主要用于抑制副作用,但过度使用它可能会导致难以调试的代码。
CSS)
1) !import
CSS 中的 !important 规则用于增加样式的权重。
!important 与优先级无关,但它与最终的结果直接相关,使用一个 !important 规则时,此声明将覆盖任何其他声明。
#myid { background-color: blue; } .myclass { background-color: gray; } p { background-color: red !important; }
以上实例中,尽管 ID 选择器和类选择器具有更高的优先级,但三个段落背景颜色都显示为红色,因为 !important 规则会覆盖 background-color 属性。
注:
使用 !important 是一个坏习惯,应该尽量避免,因为这破坏了样式表中的固有的级联规则 使得调试找 bug 变得更加困难了。
当两条相互冲突的带有 !important 规则的声明被应用到相同的元素上时,拥有更大优先级的声明将会被采用。
何时使用 !important
如果要在你的网站上设定一个全站样式的 CSS 样式可以使用 !important。
2)border-radius 圆角
# 语法结构: div{border-radius:5px} #设置div对象四个角5像素的圆角效果 div{border-radius:5px 5px 0 0;} #设置div对象左上角和右上角5像素的圆角,其他两个都是0不圆角 border-radius:3px 4px 5px 6px 代表设置对象左上角3px圆角、右上角4px圆角、右下角5px圆角、左下角6px圆角 注: 如果是0的话可以不写单位
3) padding
padding属性用于设置元素的内边距,包括上(top)、右(right)、下(bottom)、左(left)四个方向。通过调整这些值,我们可以控制元素内容与边框之间的空间。
1.1、Padding的四个方向
padding-top:元素顶部内边距
padding-right:元素右侧内边距
padding-bottom:元素底部内边距
padding-left:元素左侧内边距
2、Padding的值类型
Padding的值可以是以下几种类型:
长度值:像素(px)、百分比(%)、em、rem等
inherit:继承父元素的padding值
注意:padding不允许负值。
简写方式:
一个值:所有方向使用相同值 两个值:第一个值用于上/下,第二个值用于左/右 三个值:第一个值用于上,第二个值用于左右,第三个值用于下 四个值:分别用于上、右、下、左
设置padding会增加元素的总尺寸,因为它在内容区域周围添加了空间。例如,一个宽高为200px的元素,如果设置了20px的左右padding和30px的上下padding,其总宽度会变为240px,总高度变为260px。
解决方案:
1.Box-sizing属性
使用box-sizing: border-box;
可以让元素的宽度包括padding和border,而不会影响元素的实际宽度。
.box { width: 200px; height: 200px; background-color: #f0f; margin-bottom: 20px; box-sizing: border-box; }
如果不使用box-sizing: border-box;
,则需要手动计算实际的宽度,包括padding在内。
4)position 定位
属性值:
1、position:static:默认值;没有定位; (可以用于取消元素之前的定位设置)
2、position:relative(相对定位):相对定位 (参照物:自己所在的位置)
特点: 如果没有定位偏移量,对元素本身没有任何影响
不使元素脱离文档流,空间是会被保留。
不影响其他元素布局
3、position:absolute(绝对定位):绝对定位 (参照物:包含块—该元素的祖先级元素)
特点:使元素完全脱离文档流
使内联元素支持宽高{让内联具备块元素}
使块元素默认宽根据内容决定(让块具备内联的特性)
注:left、top、right、bottom是相对于当前元素自身进行偏移的 ,不能独自存在,必须配合定位元素一起使用 。
5.固定定位 fixed
(参照物:始终都是 相对于整个浏览器窗口进行固定定位的)
使元素完全脱离文档流
使内联元素支持宽高 (让内联具备内联块特性)
使块元素默认宽根据内容决定(让块具备内联块的特性)
相对于整个浏览器窗口进行偏移,不受浏览器滚动条的影响不会受到祖先元素的影响。
6.最后一个粘性定位(sticky)
这个很好理解, 在没有到达指定位置的时候,是没有定位效果的,到达了指定位置,就变成了固定模式。就成了和fixed差不多的一个样式 固定在一个地方不动了 常见于页面的搜索框。
5) var() 使用
css变量 ==> 自定义属性
CSS中原生的变量定义语法是:变量名前面要加两根连词线 --* 变量使用语法是:var()函数用于读取变量 var(--*) 其中 * 表示我们的变量名称 变量名大小写敏感,--header-color和--Header-Color是两个不同变量
css变量名
不能包含$,[,^,(,%等字符,普通字符局限在只要是“数字[0-9]”“字母[a-zA-Z]”“下划线_”和“短横线-”这些组合,但是可以是中文,日文或者韩文
无论是变量的定义和使用只能在声明块{}里面
变量值只能用作属性值,不能用作属性名
全局和局部变量
:root 伪类可以看做是一个全局作用域,在里面声明的变量,他下面的所有选择器都可以拿到; 局部变量; // 全局变量 :root { --color: blue; } .box{color: var(--color)} // 局部变量 .box{ --color: red; color: var(--color); }
var() 函数还可以使用第二个参数,表示变量的默认值。如果该变量不存在,就会使用这个默认值。 第二个参数不处理内部的逗号或空格,都视作参数的一部分; color: var(--foo, #7F583F); var(--font-stack, "Roboto", "Helvetica"); var(--pad, 10px 15px 20px);
如果变量值是一个字符串,可以与其他字符串拼接; 如果变量值是数值,不能与数值单位直接连用; 如果变量值带有单位,就不能写成字符串; // 字符串 --bar: 'hello'; --foo: var(--bar)' world'; // 变量值是数值 foo { --gap: 20; margin-top: var(--gap)px; /* 无效 */ } // 上面代码中,数值与单位直接写在一起,这是无效的。必须使用calc() 函数,将它们连接, foo { --gap: 20; margin-top: calc(var(--gap) * 1px); } // 变量值带有单位 .foo { --foo: '20px'; font-size: var(--foo); /* 无效 */ } .foo { --foo: 20px; font-size: var(--foo); /* 有效 */ }
同一个 CSS 变量,可以在多个选择器内声明。读取的时候,优先级最高的声明生效。这与 CSS 的"层叠"(cascade)规则是一致的; <style> :root { --color: blue; } div { --color: green; } #alert { --color: red; } * { color: var(--color); } </style> <p>蓝色</p> <div>绿色</div> <div id="alert">红色</div>
body { --foo: #7F583F; } .content { --bar: #F7EFD2; } 上面代码中,变量--foo的作用域是body选择器的生效范围,--bar的作用域是.content选择器的生效范围。 由于这个原因,全局的变量通常放在根元素:root里面,确保任何选择器都可以读取它们。 :root { --main-color: #06c; }
响应式布局:
CSS 是动态的,页面的任何变化,都会导致采用的规则变化。 利用这个特点,可以在响应式布局的media命令里面声明变量,使得不同的屏幕宽度有不同的变量值 body { --primary: #7F583F; --secondary: #F7EFD2; } a { color: var(--primary); text-decoration-color: var(--secondary); } @media screen and (min-width: 768px) { body { --primary: #F7EFD2; --secondary: #7F583F; } }
浏览器不支持css变量的兼容性处理:
// 用属性值得无效声明 a { color: #7F583F; color: var(--primary); } // 也可以使用@support命令进行检测 @supports ( (--a: 0)) { /* supported */ } @supports ( not (--a: 0)) { /* not supported */ } // JavaScript 检测浏览器是否支持 CSS变量 const isSupported = window.CSS && window.CSS.supports && window.CSS.supports('--a', 0); if (isSupported) { /* supported */ } else { /* not supported */ } // JavaScript 操作 CSS 变量的写法 window.onload = function() { // 设置值 document.body.style.setProperty("--primary","pink"); // 读取值 let primary = document.body.style.getPropertyValue("--primary"); console.log(primary); // 删除变量;返回删除的变量值 let delPrimary = document.body.style.removeProperty("--primary"); console.log(delPrimary); }
注意点:
- 当存在多个同样名称的变量时候,变量的覆盖规则由CSS选择器的权重决定的,但并无!important这种用法。
- 变量的取值采用就近原则。
- 如果变量值是数值,不能与数值单位直接连用。必须使用calc()函数,将它们连接;
- 如果变量值带有单位,就不能写成字符串。
- CSS属性名是不可以使用变量的;
- CSS变量是存在缺省值,只要定义正确,里面的值不对,结果以缺省值显示;
- CSS变量默认尾部是有空格的;
6)