# 前端笔记
- CSS:渐变色文字
- CSS:美化单选按钮
- CSS:美化滚动条
- CSS:滚动条自动吸附
- CSS:scroll在苹果safari中滚动不流畅问题
- CSS:自定义对话框
- CSS:修改滑块样式
- CSS:自定义光标
- Grid 网格布局参考
- CSS:transition过渡
- CSS:文字省略显示
- CSS:IOS 禁用双击缩放
- VScode:去掉多余空行
- JS:ES6导入模块错误
- JS:DOM获取节点
- JS:DOM添加/插入节点
- JS:DOM删除子节点
- JS:classList操作
- JS:HTML DOM Element 对象
- JS:事件委托,避免父元素执行事件
- JS:阻止默认事件
- JS:sort()排序
- JS:IOS10以上Safari浏览器无法禁止缩放的解决方案
- JS:禁用右键及复制
- JS:面向对象
- JS:闭包
- JS:ES6 Arrow Function 何时不要使用箭头函数
- JS: 类型判断
- JS: 返回按钮
- JS: 数字分隔符
- JS: 仅执行一次的事件侦听器
- JS: console.log包裹变量
- JS: 巧用ES6扩展运算符获取数组最大/最小值
- JS: 检查大小写锁定键是否按下
- JS:拷贝到剪切板
- JS:获取鼠标坐标
- JS:使用length属性裁剪数组
- JS:使用与运算符简写条件语句
- JS:console.table()指定显示的列
- JS:移除数组中重复元素
- JS:字符串转换成数字
- JS:数字转换成字符串
- JS:删除数组中值为false的元素
- JS:简写if语句
- JS:reduce求和
- JS:美化console.log()
- JS:元素自定义属性
- JS:简化嵌套for循环
# CSS:渐变色文字
h1 {
font-size: 4rem;
background: linear-gradient(to left, rgb(112, 101, 214), rgb(230, 106, 213));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
display: inline;
}
2
3
4
5
6
7
效果:
# CSS:美化单选按钮
以下方法利用label::before
伪元素覆盖默认按钮,另外可以用appearance='none'
,在默认样式上修改,详见:MDN <input type="radio">
(opens new window)
HTML:
<div>
<input type="radio" name="option" id="radio_1">
<label for="radio_1">选项1</label>
</div>
<div>
<input type="radio" name="option" id="radio_2">
<label for="radio_2">选项2</label>
</div>
2
3
4
5
6
7
8
CSS:
input[type="radio"] {
display: none;
}
input[type="radio"] + label {
font-size: 1.25rem;
height: 2rem;
display: inline-flex;
align-items: center;
cursor: pointer;
}
input[type="radio"] + label::before {
content: "";
display: inline-flex;
width: 1.25rem;
height: 1.25rem;
margin-right: 0.5rem;
border: 1px solid #ddd;
border-radius: 50%;
}
input[type="radio"]:checked + label::before {
background: url(./icons/checked.svg);
background-size: cover;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
效果:
# CSS:美化滚动条
/*滚动条的宽度*/
::-webkit-scrollbar {
width:9px;
height:9px;
}
/*外层轨道。可以用display:none让其不显示,也可以添加背景图片,颜色改变显示效果*/
::-webkit-scrollbar-track {
width: 6px;
background-color:#0d1b20;
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius:2em;
}
/*滚动条的设置*/
::-webkit-scrollbar-thumb {
background-color:#606d71;
background-clip:padding-box;
min-height:28px;
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius:2em;
}
/*滚动条移上去的背景*/
::-webkit-scrollbar-thumb:hover {
background-color:#fff;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
- ::-webkit-scrollbar - 滚动条整体部分,其中的属性有width,height,background,border(就和一个块级元素一样)等。
- ::-webkit-scrollbar-button - 滚动条两端的按钮。可以用display:none让其不显示,也可以添加背景图片,颜色改变显示效果。
- ::-webkit-scrollbar-track - 外层轨道。可以用display:none让其不显示,也可以添加背景图片,颜色改变显示效果。
- ::-webkit-scrollbar-track-piece - 内层轨道,滚动条中间部分(除去)。
- ::-webkit-scrollbar-thumb - 滚动条里面可以拖动的那部分
- ::-webkit-scrollbar-corner - 边角
- ::-webkit-resizer - 定义右下角拖动块的样式
# CSS:滚动条自动吸附
https://ishadeed.com/article/css-scroll-snap/ (opens new window)
# CSS:scroll在苹果safari中滚动不流畅问题
overflow: hidden auto;
-webkit-overflow-scrolling: touch;
overflow-y: scroll;
2
3
# CSS:自定义对话框
纯CSS实现自定义形状的对话框。
HTML:
<div class="box"></div>
CSS:
.box {
width: 200px;
height: 100px;
background-color: azure;
border-radius: 20px;
position: relative;
}
.box::before {
content: "";
width: 0;
height: 0;
position: absolute;
top: 100%;
left: 50%;
transform: translateX(-25px);
border-left: 25px solid transparent;
border-right: 25px solid transparent;
border-top: 30px solid azure;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
效果:
# CSS:修改滑块样式
HTML:
<div>
<label for="slider"></label>
<input type="range" name="range" id="slider" min="5" max="10" step="0.01">
</div>
2
3
4
CSS:
/* webkit */
input[type="range"] {
-webkit-appearance: none;
outline: none;
background: transparent;
}
input[type="range"]::-webkit-slider-runnable-track {
background: linear-gradient(to right,#12fbc5, #fbff0f);
border-radius: 6px;
height: 10px;
display: inline-flex;
align-items: center;
}
input[type="range"]::-webkit-slider-thumb {
-webkit-appearance: none;
background: linear-gradient(to top, #14cadb, #9ae8fb);
height: 20px;
width: 20px;
border-radius: 50%;
border: 1px solid #fff;
cursor: pointer;
}
/* moz */
input[type=range]::-moz-range-track {
background: linear-gradient(to right,#12fbc5, #fbff0f);
border-radius: 6px;
height: 10px;
display: inline-flex;
align-items: center;
}
input[type=range]::-moz-range-thumb {
background: linear-gradient(to top, #14cadb, #9ae8fb);
height: 20px;
width: 20px;
border-radius: 50%;
border: 1px solid #fff;
cursor: pointer;
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
效果:
相关文章:
How to Style Input Type Range in Chrome, Firefox, and IE (opens new window)
A Sliding Nightmare: Understanding the Range Input (opens new window)
# CSS:自定义光标
语法:
/* 使用URL,并提供一个关键字值作为备用 */
cursor: url(hand.cur), pointer;
2
在线代码:https://codepen.io/zjbcool/pen/WNGjdqz (opens new window)
MDN:https://developer.mozilla.org/zh-CN/docs/Web/CSS/cursor (opens new window)
# Grid 网格布局参考
# CSS属性
- grid-template-columns (opens new window)
- grid-template-rows (opens new window)
- grid-template-areas (opens new window)
- grid-template (opens new window)
- grid-auto-columns (opens new window)
- grid-auto-rows (opens new window)
- grid-auto-flow (opens new window)
- grid (opens new window)
- grid-row-start (opens new window)
- grid-column-start (opens new window)
- grid-row-end (opens new window)
- grid-column-end (opens new window)
- grid-row (opens new window)
- grid-column (opens new window)
- grid-area (opens new window)
- grid-row-gap (opens new window)
- grid-column-gap (opens new window)
- grid-gap (opens new window)
# CSS函数
相关链接:https://developer.mozilla.org/zh-CN/docs/Web/CSS/CSS_Grid_Layout (opens new window)
# 深入解析minmax()函数
https://ishadeed.com/article/css-grid-minmax/ (opens new window)
# CSS:transition过渡
div{
transition: transform 0.75s ease-out;
}
2
3
有多个属性时:
div{
transition: width, height, 0.5s ease;
}
2
3
transition的4个属性:
- transition-property - 过渡属性
- transition-duration - 过渡时长
- transition-timing-function - 过渡动画曲线
- transition-delay - 过渡延时
在线代码: https://codepen.io/zjbcool/pen/rNLGvzX (opens new window)
# CSS:文字省略显示
- 单行固定宽度
p {
width:300px;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
2
3
4
5
6
- 多行固定行数
// 支持所有浏览器,老旧IE除外
p {
width:300px;
display: -webkit-box;
-webkit-line-clamp:3;
-webkit-box-orient:vertical;
overflow:hidden;
}
2
3
4
5
6
7
8
在线代码: https://codepen.io/zjbcool/pen/PoGWWvW (opens new window)
# CSS:IOS 禁用双击缩放
.btn {
touch-action: manipulation;
}
2
3
# VScode:去掉多余空行
打开vscode,执行菜单Edit -> Replace,或使用快捷键crl + H,然后使用正则表达式:^\s*\n ,替换内容为空,即可删除所有空行。
# JS:ES6导入模块错误
ES6导入模块错误Cannot use import statement outside a module
,出现此错误需要在script
标签中加入type="module"
属性。
<script type='module' src='main.js'>
# JS:DOM获取节点
document.getElementById(elementId) // 元素选择器
document.querySelector(Name)
document.querySelectorAll(Name)
parentObj.childNodes // 从父到子 会把换行和空格也当成是节点信息
parentObj.children // 最方便
childNode.parentNode // 从子到父
2
3
4
5
6
7
8
# JS:DOM添加/插入节点
document.createElement('li'); //
document.createTextNode('文本节点') // ==> li.innerHTML = "文本节点";
parent.appendChildren(child); // 在当前节点后插入
el.insertBefore(new_child, parent.children[0]); // 在列表第1项前插入
ele.insertAdjacentHTML("beforeend", '<li>内容</li>');
parent.replaceChild(new_child, parent.children[0]) // 替换节点
2
3
4
5
6
7
# JS:DOM删除子节点
parent.removeChild(thisNode) // 只有这一个方法
删除所有子节点:
for(var i = children.length - 1; i >= 0; i--) {
parent.removeChild(children[i]); // 从后往前,删得干净
}
2
3
# JS:classList操作
var div = document.querySelector('.div');
div.classList.add('class1'); // 添加类
div.classList.remove('class2'); // 删除类
div.classList.toggle('class3'); // 切换类
div.classList.contains('class4'); // 是否包含某个类
div.setAttribute('class', 'class4'); // 设置属性
2
3
4
5
6
7
# JS:HTML DOM Element 对象
https://www.w3school.com.cn/jsref/dom_obj_all.asp (opens new window)
# JS:事件委托,避免父元素执行事件
点击子元素放大,但点击父元素时不受影响
<ul>
<li><img src='img.jpg'>放大</li>
<li><img src='img.jpg'>放大</li>
<li><img src='img.jpg'>放大</li>
</ul>
2
3
4
5
img {
pointer-events: none;
}
2
3
var parent = document.querySelector('ul');
parent.addEventListener('click', function(e){
for(var i=0; i<parent.length; i++){
parent.children[i].style.transform = 'scale(1)';
};
if(this != e.target){
e.target.style.transform = 'scale(2)';
}
}, false)
2
3
4
5
6
7
8
9
在线代码: https://codepen.io/zjbcool/pen/GRqvGdV (opens new window)
# JS:阻止默认事件
a标签
<a href="javascript:void(0);">按钮</a>
<a href="javascript:;">按钮</a>
2
js事件方法:preventDefault()
btn.onclick = function (e){
e.preventDefault(); // e.returnValue = false
}
2
3
# JS:sort()排序
语法:
arr.sort([compareFunction])
例:实现物体列表按数字后缀排序
var objs=['obj_1','obj_3','obj_4','obj_2'];
objs.sort(function(a,b){
return Number(a.replace('obj_', '')) - Number(b.replace('obj_', ''))
})
2
3
4
在线代码:https://codepen.io/zjbcool/pen/ExyLyZK?editors=0010 (opens new window)
# JS:IOS10以上Safari浏览器无法禁止缩放的解决方案
window.onload = function() {
// 阻止双击放大
var lastTouchEnd = 0;
document.addEventListener('touchstart', function(event) {
if (event.touches.length > 1) {
event.preventDefault();
}
});
document.addEventListener('touchend', function(event) {
var now = (new Date()).getTime();
if (now - lastTouchEnd <= 300) {
event.preventDefault();
}
lastTouchEnd = now;
}, false);
// 阻止双指放大
document.addEventListener('gesturestart', function(event) {
event.preventDefault();
});
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# JS:禁用右键及复制
//js禁止鼠标右键打开及复制
document.oncontextmenu = new Function("event.returnValue=false");
document.onselectstart = new Function("event.returnValue=false");
function click1() {
if (event.button == 2) { return false; }
}
document.onselectstart = click1;
2
3
4
5
6
7
8
# JS:面向对象
# 构造函数
function Animal(prop){
this.name = prop.name;
this.color = prop.color;
}
Animal.prototype = {
getName:function(){
console.log(`It\'s a ${this.color} ${this.name}.`)
}
}
// 或者
Object.assign(Aniaml.prototype, {
getName:function(){
console.log(`It\'s a ${this.color} ${this.name}.`)
}
})
// 继承
function Cat(prop){
Animal.call(this, prop);
this.sound = prop.sound;
}
Cat.prototype = Object.assign(Object.create(Animal.prototype), {
constructor: Cat,
sing:function(){
console.log('sing ' + this.sound)
}
});
// 实例
var bird = new Animal({
name:'bird',
color: 'white'
});
bird.getName(); // It's a white bird.
var cat = new Cat({
name:'cat',
color:'black',
sound: 'miao~~'
});
cat.getName(); // It's a black cat.
cat.sing(); // sing miao~~
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 类
class Rect {
constructor(prop){
this.x=0;
this.y=0;
this.w=100;
this.h=100;
this.name = '';
Object.assign(this, prop);
return this;
}
render(){
console.log('render ' + this.name)
}
}
class RoundRect extends Rect {
constructor(prop){
super(prop);
this.raius = 4;
Object.assign(this, prop);
return this;
}
getRadius(){
console.log('radius is ' + this.raius)
}
}
let rect = new Rect({
name:'rect'
})
rect.render();
let roundRect = new RoundRect({
raius:5
});
roundRect.getRadius();
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# JS:闭包
闭包是JS的一种语法现象——当函数中返回函数时,如果返回函数访问了函数中的变量,那么这个变量的生命周期会被延长。
function counter(){
var _count = 0;
return function(){
return ++_count
}
}
var getCount = counter();
var g1 = getCount(); // 1
var g2 = getCount(); // 2
2
3
4
5
6
7
8
9
闭包将函数与数据(环境)关联起来,在OOP中使用只有一个方法的对象的地方,都可以使用闭包。
闭包在处理速度和内存消耗方面对脚本性能具有负面影响。
MDN:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures (opens new window)
# JS:ES6 Arrow Function 何时不要使用箭头函数
- 在构造函数和构造函数的方法中使用时,由于箭头函数不改变this导致错误
//构造函数实例化过程:1.创建一个新(空)对象 2.this指向新对象 3.执行函数内部代码 4.返回新对象 const Person(fname)=> { // this = new Object(); 箭头函数中不执行 this.fname = fname; // this.fname === window.fname // return this; 箭头函数不执行 } const boy = new Person('xiaoMing'); // 类型错误 Person.prototype.sayName = ()=>{ console.log(this.fname) // this.fname === window.fname }
1
2
3
4
5
6
7
8
9
10 - 需要使用this时
document.body.addEventListener('click', ()=> { this.style.background = 'black'; // 类型错误 })
3. 要用到函数中的arguments参数时
```js
const sum = () => {
return Array.from(arguments).reduce((preSum, value) => preSum + value, 0)
}
sum(1,2,3) // 引用错误
2
3
4
5
6
# JS: 类型判断
- typeof运算符 MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/typeof (opens new window)
- instanceof运算符 MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/instanceof (opens new window)
- constructor属性
typeof arr == "object" && arr.constructor == Array;
- Object.prototype.toString
// 在不改变对象的Symbol.toStringTag属性情况下适用
Object.prototype.toString.call(new Object) === "[object Object]" //true;
Object.prototype.toString.call(new Array) === "[object Array]" //true;
2
3
- 生产环境解决方案
function type(obj, showFullClass) {
// get toPrototypeString() of obj (handles all types)
if (showFullClass && typeof obj === "object") {
return Object.prototype.toString.call(obj);
}
if (obj == null) { return (obj + '').toLowerCase(); }
var deepType = Object.prototype.toString.call(obj).slice(8,-1).toLowerCase();
if (deepType === 'generatorfunction') { return 'function' }
return deepType.match(/^(array|bigint|date|error|function|generator|regexp|symbol)$/) ? deepType :
(typeof obj === 'object' || typeof obj === 'function') ? 'object' : typeof obj;
}
2
3
4
5
6
7
8
9
10
11
# JS: 返回按钮
<button onclick="history.back()">返回</button>
# JS: 数字分隔符
为了提高数字的可读性,使用下划线作为分隔符:
const largeNumber = 1_000_000_000;
console.log(largeNumber); // 1000000000"
2
# JS: 仅执行一次的事件侦听器
使用once
参数,除IE外所有浏览器
element.addEventListener('click', () => console.log('I run only once'), {
once: true
});
2
3
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener (opens new window)
# JS: console.log包裹变量
使用大括号包裹变量,可以同时打印出变量名和值
const num = 123;
console.log({num}); // {num: 123}
2
# JS: 巧用ES6扩展运算符获取数组最大/最小值
const numbers = [6, 8, 1, 3, 9];
console.log(Math.max(...numbers)); // 9
console.log(Math.min(...numbers)); // 1
2
3
# JS: 检查大小写锁定键是否按下
使用KeyboardEvent.getModifierState()
检测键盘状态
const passwordInput = document.getElementById('password');
passwordInput.addEventListener('keyup', function (event) {
if (event.getModifierState('CapsLock')) {
// CapsLock is on.
}
});
2
3
4
5
6
# JS:拷贝到剪切板
function copyToClipboard(text) {
navigator.clipboard.writeText(text);
}
2
3
# JS:获取鼠标坐标
document.addEventListener('mousemove', (e) => {
console.log(`Mouse X: ${e.clientX}, Mouse Y: ${e.clientY}`);
});
2
3
# JS:使用length属性裁剪数组
const numbers = [1, 2, 3, 4, 5];
numbers.length = 3;
console.log(numbers); // [1, 2, 3];
2
3
# JS:使用与运算符简写条件语句
// 当条件为真时,执行函数
if (condition) doSomething();
// 可简写为:
condition && doSomething();
// 执行多个表达式
condition && (doSomething(), doSomething1());
2
3
4
5
6
# JS:console.table()指定显示的列
# JS:移除数组中重复元素
const numbers = [2, 3, 4, 4, 2];
console.log([...new Set(numbers)]); // [2, 3, 4]
2
# JS:字符串转换成数字
const str = '404';
console.log(+str) // 404;
2
# JS:数字转换成字符串
const myNumber = 403;
console.log(myNumber + ''); // '403'
2
# JS:删除数组中值为false的元素
const myArray = [1, undefined, NaN, 2, null, '@denicmarko', true, 3, false];
console.log(myArray.filter(Boolean)); // [1, 2, "@denicmarko", true, 3]
2
# JS:简写if语句
const myTech = 'JavaScript';
const techs = ['HTML', 'CSS', 'JavaScript'];
// 判断多个条件:
if (myTech === 'HTML' || myTech === 'CSS' || myTech === 'JavaScript') {
// do something
}
// 简写:
if (techs.includes(myTech)) {
// do something
}
2
3
4
5
6
7
8
9
10
11
12
# JS:reduce求和
const myArray = [10, 20, 30, 40];
console.log(myArray.reduce((total, currentValue) => total + currentValue)); // 100
2
# JS:美化console.log()
# JS:元素自定义属性
<div id="user" data-name="John Doe" data-age="29" data-something="Some Data">
John Doe
</div>
2
3
const user = document.getElementById('user');
console.log(user.dataset); // { name: "John Doe", age: "29", something: "Some Data" }
2
# JS:简化嵌套for循环
for(let x=0;i<X;x++){
for(let y=0;y<Y;y++){
}
}
// 简写为:
for(let i=0;i<X*Y;i++){
const x = i%X;
const y = i%Y;
console.log({x,y});
}
2
3
4
5
6
7
8
9
10