gayechen / blog Goto Github PK
View Code? Open in Web Editor NEWissue博客
issue博客
new Webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('production'),
}),
new HtmlWebpackPlugin({
title: '',
template: __dirname + '/../public/index.html',
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
chunksSortMode:'dependency'
}),
get发送一个TCP数据包,post产生两个TCP数据包
get向服务请求数据,post向服务器推送数据
get将请求参数放在url中,post放在请求体中(request body)
get请求参数,因浏览器有长度限制,post参数长度无限制
通常使用标准化就可以了
当需要实现非常个性化的网页设计时,我会选择重置的方式,因为我要写很多自定义的样式以满足设计需求,这时候就不再需要标准化的默认样式了。
详情:http://www.zhangxinxu.com/wordpress/2016/01/understand-css-stacking-context-order-z-index/
创建BFC的条件(只要元素满足下面任一条件即可触发 BFC)
作用
<div style="clear: both;"/>
::after
.clearfix::after {
content: '',
display: block;
clear: both;
}
大型项目中一般使用第二种,当子元素高度大于父元素时,设置overflow:hidden可能使其子元素显示不完整
雪碧图是把多张图片整合到一张图片上。他被运用在众多使用了很小图标的网站上。实现方式:
好处:
生成器:https://www.toptal.com/developers/css/sprite-generator
visibility: hidden
: 元素仍在页面流中,并占用空间width: 0; height: 0
: 使元素不占用空间,导致不显示它position: absolute; left: -99999px
: 将它置于屏幕之外text-indent: -9999px
: 这是适用于block元素中的文本分开屏幕显示与打印的样式
<link rel="stylesheet" type="text/css" media="screen" href="/css/styles.css" />
<link rel="stylesheet" type="text/css" media="print" href="/css/print.css" />
设计一份打印样式表
i. 用点单位(pt)指定大小
body {
font-family: "Times New Roman", serif;
font-size: 12pt;
}
实在太简单了,比起用像素单位来说,这个应该更能想象12点字体会印多大,同时我们也选用serif字体,这种字体打印出来比较细致,而且比较容易阅读.
ii. 隐藏不必要的标签节省墨水
body {
font-family: "Times New Roman", serif;
font-size: 12pt;
}
#nav, #sidebar, #advertising, #search {
display: none;
}
iii. 去掉背景图片和颜色
body {
background: none;
}
<style type="text/css">
@import url("screenstyles.css") screen;
@media print {
/* 打印时使用的样式放置在此 *
}
优点:
sass的优缺点
通过node-sass使用sass,它用 C ++ 编写的 LibSass 绑定,在Node版本切换时,必须重新编译
less用javascript编写,与NodeJS高度结合
block | inline-block | inline | |
---|---|---|---|
大小 | 填充父容器的宽度 | 取决于内容 | 取决于内容 |
定位 | 从新的一行开始,并且不允许旁观有HTML元素(除非是float) | 与其他内容一起流动 | 与其他内容一起流动 |
能否设置width和height | 能 | 能 | 不能 |
能否使用vertical-align对齐 | 不可以 | 可以 | 可以 |
边距和填充 | 各个方向都存在 | 各个方向都存在 | 只有水平方向存在。尽管border和padding在content周围,垂直方向上的空间取决于line-height |
— 使用更高分辨率的图形(显示尺寸的两倍)来处理视网膜显示。
更好的方法是使用媒体查询,像@media only screen and (min-device-pixel-ratio: 2) { ... },然后改变background-image。
实现lazyman
一道被人轻视的JS面试题
获取元素最终的backgroundColor
(function(window, undefined) {
var taskQueue = [];
// 订阅
function subscribe() {
var params = {},
args = [].slice.call(arguments);
if (args.length < 1) {
throw new Error('subscribe 参数不能为空');
}
params.msg = args[0];
params.args = args.slice(1);
if (params.msg == 'sleepFirst') {
taskQueue.unshift(params);
} else {
taskQueue.push(params);
}
}
// 发布
function publish() {
if (taskQueue.length > 0) {
run(taskQueue.shift());
}
}
function LazyMan() { }
LazyMan.prototype.eat = function (str) {
subscribe('eat', str);
return this;
};
LazyMan.prototype.sleep = function (num) {
subscribe('sleep', num);
return this;
};
LazyMan.prototype.sleepFirst = function (num) {
subscribe('sleepFirst', num);
return this;
};
// 暴露接口
window.LazyMan = function (str) {
subscribe('lazyMan', str);
setTimeout(function () {
publish();
}, 0);
return new LazyMan();
};
function lazyManLog(str) {
// console.log(str);
alert(str);
}
// 具体方法
function lazyMan(str) {
lazyManLog('Hi!This is ' + str + '!');
publish();
}
function eat(str) {
lazyManLog('Eat ' + str + '~');
publish();
}
function sleep(num) {
setTimeout(function () {
lazyManLog('Wake up after ' + num);
publish();
}, num * 1000);
}
function sleepFirst(num) {
setTimeout(function () {
lazyManLog('Wake up after ' + num);
publish();
}, num * 1000);
}
// 鸭子叫
function run(option) {
var msg = option.msg,
args = option.args;
switch (msg) {
case 'lazyMan':
lazyMan.apply(null, args);
break;
case 'eat':
eat.apply(null, args);
break;
case 'sleep':
sleep.apply(null, args);
break;
case 'sleepFirst':
sleepFirst.apply(null, args);
break;
default:
}
}
})(window);
function Foo() {
getName = function () { alert (1); };
return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}
//请写出以下输出结果:
Foo.getName();
getName();
Foo().getName();
getName();
new Foo.getName();
new Foo().getName();
new new Foo().getName();
(function(WDS, undefined) {
function camelize(params) {
return str.replace(/-(\w)/g, function(strMatch, p1) {
return p1.toUpperCase();
});
}
function getStyle(ele, property) {
if (!ele || !property) {
return false;
}
var value = ele.style[camelize(property)],
css;
if (!value) {
if (document.defaultView && document.defaultView.getComputedStyle) {
css = document.defaultView.getComputedStyle(ele, null);
value = css ? css.getPropertyValue(property) : null;
}
}
return value;
}
function checkBgValue(ele) {
var value = getSyle(ele, 'background-color'),
hasColor = value ? true : false;
if (value == 'transparent' || value == 'rgba(0, 0, 0, 0)') {
// 未设置background-color,或者设置为跟随父节点
hasColor = false;
} else if (getSyle(ele, 'opacity') == '0') {
// dom节点透明度为全透明
hasColor = fasle;
} else if (getStyle(ele, 'visibility') == 'hidden') {
// dom节点不可见
hasColor = false;
} else if (getStyle(ele, 'display' == 'none')) {
hasColor = false;
}
return hasColor ? value : hasColor;
}
function getRealBg(ele) {
if (checkBgValue(ele)) {
return checkBgValue(ele);
} else if (ele != document.documentElement) {
return getRealBg(ele.parentNode);
}
return ''
}
})(window.WDS || (window.WDS = {}));
- 怪异模式:不同的浏览器在页面的渲染上没有统一的规范,产生了差异,那些网页是按照当时占**地位的浏览器的渲染模式来渲染的,因为不同浏览器解析方式不同,所以称之为怪异模式
- 标准模式是指,浏览器按照W3C的最新标准解析执行代码
- 浏览器解析时到底使用标准模式还是怪异模式,与你网页中的DTD声明直接相关,DTD声明定义了标准文档的类型(标准模式解析)文档类型,会使浏览器使用相应的方式加载网页并显示,忽略DTD声明,将使网页
- 详细https://blog.csdn.net/xujie_0311/article/details/42044277
主要区别
- 在JavaScript框架变得流行之前,前端开发者经常使用data-属性,把额外数据存储在 DOM 自身中。当时没有其他 Hack 手段(比如使用非标准属性或 DOM 上额外属性)。
- 这样做是为了将自定义数据存储到页面或应用中,对此没有其他更适当的属性或元素。
- 而现在,不鼓励使用data-属性。
原因之一是,用户可以通过在浏览器中利用检查元素,轻松地修改属性值,借此修改数据。数据模型最好存储在 JavaScript 本身中,并利用框架提供的数据绑定,使之与 DOM 保持更新。
上面提到的技术名词,都是在客户端以键值对存储的存储机制,并且只能将值存储为字符串。
- 后两者都由客户端初始化,cookie也可以有服务器使用set—Cookie请求头初始化
- cookie手动设置过期时间,session页面关闭时过期,local永不过期
- Cookies会通过Cookie请求头自动发给服务器,而后两者不会
- cookie容量为4KB,后两者都是5MB
- cookie和local任一窗口都可访问,session仅在当前窗口
cookie |
localStorage |
sessionStorage |
|
---|---|---|---|
由谁初始化 | 客户端或服务器,服务器可以使用Set-Cookie 请求头。 |
客户端 | 客户端 |
过期时间 | 手动设置 | 永不过期 | 当前页面关闭时 |
在当前浏览器会话(browser sessions)中是否保持不变 | 取决于是否设置了过期时间 | 是 | 否 |
是否随着每个 HTTP 请求发送给服务器 | 是,Cookies 会通过Cookie 请求头,自动发送给服务器 |
否 | 否 |
容量(每个域名) | 4kb | 5MB | 5MB |
访问权限 | 任意窗口 | 任意窗口 | 当前页面窗口 |
为什么最好把JS的<script>标签恰好放在</body>之前,有例外情况吗?
<link>
标签放在<head></head>
之间是规范要求的内容<script>
标签恰好放在</body>
之前<script>
标签放在底部,保证HTML首先解析完成,将页面呈现给用户。<script>
标签放在底部,意味着浏览器不能开始下载脚本,直到整个文档(document)被解析。也许,对此比较好的做法是,<script>
使用defer
属性,放在<head>
中DOMContentLoaded
/load
事件加载其他资源和内容。<img>
标签中使用srcset属性?请描述浏览器遇到该属性后的处理过程因为需要设计响应式图片。我们可以使用两个新的属性——srcset 和 sizes——来提供更多额外的资源图像和提示,帮助浏览器选择正确的一个资源。
srcset 定义了我们允许浏览器选择的图像集,以及每个图像的大小。
sizes 定义了一组媒体条件(例如屏幕宽度)并且指明当某些媒体条件为真时,什么样的图片尺寸是最佳选择
所以,有了这些属性,浏览器会
<img srcset="elva-fairy-320w.jpg 320w,
elva-fairy-480w.jpg 480w,
elva-fairy-800w.jpg 800w"
sizes="(max-width: 320px) 280px,
(max-width: 480px) 440px,
800px"
src="elva-fairy-800w.jpg" alt="Elva dressed as a fairy">
- 必不可少的快捷键📝📝📝
快捷键 | 作用 |
---|---|
Ctrl + 关机 | 关机 |
⌘ + Option + Esc | 强制退出 |
快捷键 | 作用 |
---|---|
⌘ + N | 打开新窗口 |
⌘ + T | 打开新标签页 |
⌘ + O | 通过浏览器打开本地文件 |
⌘ + Shift + N | 打开新的无痕窗口 |
⌘ + Shift + T | 重新打开上次关闭的标签页(浏览器可记住最多10个标签) |
⌘ + W | 关闭当前标签页 |
⌘ + Shift + W | 关闭当前窗口 |
⌘ + Option + 左/右箭头 | 切换到上一个/下一个标签页 |
⌘ + [ ,⌘ + ] | 历史记录后退/前进 |
⌘ + L, | 选中地址栏 |
⌘ + D | 收藏标签页 |
⌘ + L, ⌘ + Enter | 复制当前url到一个新的标签页 |
快捷键 | 作用 |
---|---|
⌘ + , | 打开设置 |
⌘ + Option + B | 打开书签管理器 |
⌘ + Y | 打开历史记录 |
⌘ + Shift + Delete | 打开“清除数据”对话框 |
无状态函数组件
React.createClass
var Greeting = React.createClass = ({
getInitialState: function() {
return {
work_list: []
};
},
render: function () {
return (
<div>
<input type="text" ref="myWork" placeholder="What need to be done?" onKeyUp={this.Enter}/>
<ul>
{
this.state.work_list.map(function (textValue) {
return <li key={textValue}>{textValue}</li>;
})
}
</ul>
</div>
);
},
shouldComponentUpdate(nextProps, nextState) {
// 如果当前的value值与待更新不相等,才执行更新
return this.props.value !== nextProps.value;
}
import React, { PureComponent } from 'react'
class Example extends PureComponent {
render() {
// ...
}
}
array.map(val, key) => {
return <span key={key}>{val}</span>
})
注意:1. PureRenderMixin、PureComponent 内进行的仅仅是浅比较对象(shallowCompare)
componentDidMount,因为:
新的核心架构Fiber
//string
render(){
return 'hello,world'
}
//number
render(){
return 12345
}
//boolean
render(){
return isTrue?true:false
}
//null
render(){
return null
}
//fragments,未加key标识符,控制台会出现warning
render(){
return [
<div>hello</div>,
<span>world</span>,
<p>oh</p>
]
}
//最佳实践:将ErrorBoundary抽象为一个公用的组件类
export default class ErrorBoundary extends Component {
constructor(props) {
super(props)
this.state = { hasError: false }
}
componentDidCatch(err, info) {
this.setState({ hasError: true })
//sendErrorReport(err,info)
}
render(){
if(this.state.hasError){
return <div>Something went wrong!</div>
}
return this.props.children
}
}
//使用方式
render(){
return (
<div>
<ErrorBoundary>
<Profile user={this.state.user} />
</ErrorBoundary>
<button onClick={this.onClick}>Update</button>
</div>
)
}
符合以下规则:
sea.js跟AMD的规范在预加载这一点上是相同的,明显不同的地方是调用,和声明依赖的地方
// CMD
define(function(require, exports, module) {
var a = require('./a');
a.doSomething();
var b = require('./b');
b.doSomething();
})
// AMD
define(['a', 'b'], function(a, b){
a.doSomething()
b.doSomething()
})
建议不要使用未声明变量。如果定义了暂时没有用到的变量,声明时赋值为null,养成良好习惯。
作用:
var persion = new Persion()
// call实现
Function.prototype.mycall = function (context, ...args) {
context = context || window
context.fn = this
var result = null;
if(window.JSON) {
result = context.fn(...args)
} else {
var args2 = [];
var args3 = [];
for(var i = 1, len = arguments.length; i < len; i++) {
args2.push('arguments[' + i + ']')
}
result = eval('context.fn(' + args2 + ')')
}
delete context.fn
return result
}
// apply实现
Function.prototype.myapply = function (context, args) {
context = context || window
args = args || []
context.fn = this
var result = null;
if (window.JSON) {
result = context.fn(...args)
} else {
var args2 = [];
for (var i = 0, len = args.length; i < len; i++) {
args2.push('args[' + i + ']')
}
result = eval('context.fn(' + args2 + ')')
}
delete context.fn
return result
}
// bind实现
Function.prototype.mybind = function (context, ...args) {
if (typeof this !== "function") {
throw new Error("Function.prototype.bind - what is trying to be bound is not callable");
}
var self = this
var args = [].slice.call(arguments, 1);
var fnNOP = function () {};
var resFn = function (...params) {
if(window.JSON) {
return self.apply(context, [...args, ...params])
}
var bindArgs = [].slice.call(arguments);
return self.apply(context, args.concat(bindArgs))
}
// 修改返回函数的 prototype 为绑定函数的 prototype,实例就可以继承绑定函数的原型中的值
fnNOP.prototype = this.prototype
resFn.prototype = new fnNOP();
return resFn
}
function myNew() {
var obj = {};
Constructor = [].shift.call(arguments);
obj.__proto__ = Constructor.prototype;
Constructor.apply(obj, arguments);
return (ref = typeof Constructor === "object" ? ref || obj : obj);
}
<head/>和<body/>
会被移除),将文档内容替换成函数传入的字符串参数。因此这个函数被认为是危险并且容易被误用。// 功能检测
if ('geolocation' in navigator) {
// 可以使用 navigator.geolocation
} else {
// 处理 navigator.geolocation 功能缺失
}
// 功能推断
if (document.getElementsByTagName) {
element = document.getElementById(id);
}
==
” 和 “===
” 的区别for(var i = 0; i < 100; i++) {
let f = i % 3 === 0
let b = i % 5 === 0
console.log(f ? b ? 'Fizzbuzz' : 'Fizz' : b ? 'Buzz' : i )
}
包括 CoffeeScript、TypeScript、Elm、ClojureScript、PureScript
// 变量交换
let a = 1;
let b = 3;
[a, b] = [b, a];
console.log(`string text line 1
string text line 2`);
// "string text line 1
// string text line 2"
var a = 5;
var b = 10;
console.log(`Fifteen is ${a + b} and\nnot ${2 * a + b}.`);
// "Fifteen is 15 and
// not 20."
function add(a, b) {
return a + b;
}
var curriedAdd = curry(add);
var addFive = curriedAdd(5);
var result = [0, 1, 2, 3, 4, 5].map(addFive); // [5, 6, 7, 8, 9, 10]
我们通过以上这些属性值获取的结果永远不可能出现小数,都是整数;浏览器获取结果的时候,会在原来真实结果的基础上进行四舍五入。
在存入数组或对象时,会在浏览器的栈空间,存储指向堆空间的指针(及地址),而在堆空间存储真正的内容,访问时通过栈空间的地址来访问;
// 所以对于一个对象的深拷贝
var cloneObj={};
function deepCopy(obj,newObj) {
newObj=newObj || {};
for (var i in obj){
if(obj.hasOwnProperty(i)) {
if (typeof obj[i]==="object"){
newObj[i]=obj[i].constructor===Array?[]:{};
deepCopy(obj[i],newObj[i])
} else {
newObj[i]=obj[i]
}
}
}
return newObj
}
<div class="loading" id="loading">
<div class="progress" id="progress">0%</div>
</div>
var $loading = $('#loading')
var $progress = $('#progress')
var prg = 0
var timer = 0
var now = new Date() // 记录当前时间
var timeout = 5000 // 超时时间
progress([80, 90], [1, 3], 100)
window.onload = () => {
console.log('onLoad');
complete()
}
function complete() {
progress(100, [1, 5], 10, () => {
window.setTimeout(() => { // 延迟了一秒再隐藏loading
$loading.hide()
}, 1000)
})
}
// window.setTimeout(() => { // 设置5秒的超时时间
// complete()
// }, timeout - (now - loadingStartTime))
if (now - loadingStartTime > timeout) { // 超时
complete()
} else {
window.setTimeout(() => { // 未超时,则等待剩余时间
complete()
}, timeout - (now - loadingStartTime))
}
function progress(dist, speed, delay, callback) {
var _dist = random(dist)
var _delay = random(delay)
var _speed = random(speed)
window.clearInterval(timer)
timer = window.setTimeout(() => {
if (prg + _speed >= _dist) {
window.clearInterval(timer)
if (callback) {
prg = _dist
callback()
}
} else {
prg += _speed
progress(_dist, speed, delay, callback)
}
$progress.html(parseInt(prg) + '%')
console.log(prg)
}, _delay)
}
function random(n) {
if (typeof n === 'object') {
var times = n[1] - n[0]
var offset = n[0]
return Math.random() * times + offset
} else {
return n
}
}
给xhr对象的onreadystatechange事件设置监听器函数,判断http响应状态(status)200-300之间或者304(缓存)执行回调函数
动态创建一个script标签,利用script标签的src属性访问无限制的特性,来接受不同源服务器的数据,从而实现跨域。
web客户端定义一个全局函数,将这个函数名作为callback参数值作为传递给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹json数据,客户端的函数便可以拿到服务器端返回的数据并进行处理
jsonP与ajax的区别:
同源策略限制以下几种行为:
// 函数节流
var canRun = true;
document.getElementById("throttle").onscroll = function(){
if(!canRun){
// 判断是否已空闲,如果在执行中,则直接return
return;
}
canRun = false;
setTimeout(function(){
console.log("函数节流");
canRun = true;
}, 300);
};
// 函数防抖
var timer = false;
document.getElementById("debounce").onscroll = function(){
clearTimeout(timer); // 清除未执行的代码,重置回初始化状态
timer = setTimeout(function(){
console.log("函数防抖");
}, 300);
};
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.