- 原生js如何实现跨页面通信
- window.addEventListener & window.dispatchEvent
- base64 图片压缩
- base64 转 流文件
- 优雅的处理 人民币单位
- 用 Object.entries() 解构出对象的键值对
jslinsir / my-blog Goto Github PK
View Code? Open in Web Editor NEWThink twice before you act
Think twice before you act
*,
:after,
:before {
-webkit-tap-highlight-color: rgba(0, 0, 0, 0)
}
blockquote,
body,
dd,
div,
dl,
dt,
fieldset,
form,
h1,
h2,
h3,
h4,
h5,
h6,
input,
legend,
li,
ol,
p,
td,
textarea,
th,
ul {
margin: 0;
padding: 0
}
table {
border-collapse: collapse;
border-spacing: 0
}
fieldset,
img {
border: 0
}
li {
list-style: none
}
caption,
th {
text-align: left
}
q:after,
q:before {
content: ""
}
input:password {
ime-mode: disabled
}
:focus {
outline: none
}
body,
html {
min-height: 100%
}
body {
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none
}
a,
img {
-webkit-touch-callout: none
}
此css 属性作用在微信客户端浏览器,也就是腾讯内核的浏览器
img {
pointer-events:none;
}
注意:此css属性同时也会禁用掉图片的点击事件,如果同时要支持图片点击,外层套个div 事件绑定到外层div上
img{
user-select:none;
-webkit-touch-callout:none;
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
}
注意:-webkit-touch-callout主要用于禁止长按菜单。针对iOS webkit内核的浏览器。
user-select属性是css3新增的属性,用于设置用户是否能够选中文本
加一层遮罩如下:
<div class="imgBox">
<div class="imgMask"></div>
<img src="xx.png"/>
</div>
<style>
.imgBox{
position: relative;
width: 100%;
margin: 0 auto;
.imgMask{
position: absolute;
z-index: 100;
left: 0;
right: 0;
top: 0;
bottom: 0;
opacity: 0;
}
img{
display: block;
width: 100%;
}
}
</style>
设置图片为背景图
通过浏览器的模拟器,第二种是生效的,遮罩视乎在浏览器中模拟器不生效
93年人,今天踏进30岁的大门。
没有祝福,没有蛋糕。
从小到大也没有几次正儿八经的过几次,对我也不那么重要
重要的是30岁,这个年龄担子上的责任
成熟不是不会到来,可能来的会慢些;
回想下,这几年也经历了不少事情,自己扛不过来的时候也放声大哭过
有时候也抱怨生活为什么会那么难?生活为什么会有那么多挫折?
这就是生活
,为了心爱的人,为了心疼的人,为了牵挂的人值得你去爱,值得你去付出;
咬咬牙,你这个年纪注定不安逸,一切都会好起来的!
懂感恩,懂责任,懂付出,不去计较,这是你这个角色应当承担的!
16年11月份来的深圳,刚来就爱上了这里
干净的街道,宽阔的马路,琳琅满目的大厦,蓝蓝的天空 埋下了留深的种子
这6年,换了三家公司
越往后,就是大龄程序员,听到这个词,确实很让人焦虑 难道搬一辈子砖?
内心焦虑的时候不如:
路慢慢的走,踩实了走,一步一个脚印 不急于求成,稳中求胜
壬寅年四月十七
20022年5月17日
当输入数字的时候,显示数字的最大单位
如: 1,000 在下方展示 千
10 = 10*1 == 1e1
100 = 10*10 == 1e2
1000 = 10*10*10 == 1e3
Math.log10(10) == 1
Math.log10(100) == 2
Math.log10(1000) == 3
根据上面分析10 的幂运算 和对数运算 对应关系
我们定义一个常量
const charCn = ['个','十','百','千','万','十万','百万','千万','亿','十亿','百亿','千亿','兆','十兆','百兆','千兆','京']
Math.floor(Math.log10(1)) // 向下取整(取10的对数) 得到的既是 对应值的下标
function getCharName(value) {
const charCnIndex = Math.floor(Math.log10(value))
return charCn[charCnIndex]
}
行业内卷,公司绩效也不是太好,这个时候部门互怼开始,产品怼技术,技术怼产品,技术互怼...
前端相比其他工种,比较特殊,对接的工种也比较多
我们在开发过程中,是对接环节比较多的一个工种,如果UI,UE 不完善,那我们就可能出现 页面,或者交互问题,如果接口Mock没有覆盖到位,就有可能出现数据回显,以及状态处理问题等!
对接的多,就需要我们多沟通,有时候别人回的信息不及时,你这个问题就会耽搁,同时也会缩短你的开发时间。
在开发周期固定的情况下,如何快速的交付?这个时候前端同学们就会 老老实实切图,也不会去关心产品逻辑,只关心功能的实现。
在我看来,我不认同不是前端同学们不够细心导致的,代码是人写的,人写的肯定会出错,在周期短的情况下,以及其他工种不够完整的情况下就会出现 上述情况;
当然啦,细心肯定是要有的,这个是职业素养。
问题的出现,不是一个工种的问题,而是整个团队配合的问题。出现问题,不要相互指责,也不要归结到一个工种上;如果这样做,团队氛围也不会好,也不会拧成一股绳 往前冲,而是各组相互吃瓜...
文章:
https://baijiahao.baidu.com/s?id=1584279240152308041&wfr=spider&for=pc
现在的青年失业率非常高。官方统计[2],今年7月份的16岁~24岁青年失业率达到了19.9%。
前景也不乐观。明年的高校毕业生创新高,超过1000万人加入求职大军。而且,市场上还有很多大龄失业者,也在找工作。
这样严峻的就业形势意味着,最终有相当一部分人会考虑创业。
我以前一直赞成创业,但是这几年想法有变化,认为创业有三个条件, 只有满足条件,才适合创业。
我最近读过一篇文章[3],作者是美国最大的创业孵化器 Y Combinator[4] 的创始人之一杰西卡·利文斯顿(Jessica Livingston)。她是四个创始人里面唯一的女性。
她回忆了自己为什么创业,文章的最后一段,她这样说:
你是一块特殊形状的拼图。你可以改变自己的形状,适应公司现有的空缺。那是传统的方案。 但是,还有另一种对你和世界通常都更好的方案:围绕你自己的形状,发展出一幅新的拼图。这就是我所做的,我是一个非常奇怪的形状
她的意思是,你为别人打工,就必须变成别人要求的样子。但这并不是你内心想要的,如果你想顺应自己的内心和天赋,就应该创业。
这话没错,但是有一个前提才能成立:你已经定型了,很难被外界塑造了。 这个时候,你走自己的路,内心满意度会高一些。我觉得这是创业的第一个条件。
据我观察,大部分的**年轻人,达不到这个条件。他们都没有定型,人生观和世界观还在发展中。典型的表现就是,说不出自己想做什么,也不知道自己的竞争力在哪里。
这种情况下,你不是一块特殊形状的拼图,而是没有自己的形状,还在塑造中。如果这样去创业,你的想法可能随着外界的变化,而不断变化,今天想东,明天想西,这是大忌。
反而是给别人打工,公司明确告诉你成为什么形状,你就往这个方向努力。公司把你塑造成型,适合公司的需求,融合进公司的拼图。这就是为什么,大部分创业者都是离职后才创业,因为只有到了这个时候,他们才定型。
创业的第二个条件:
要有可行的项目, 不能先注册公司,再找项目。而且,你的项目最好是用户愿意付费的,有的同学的创业项目是拍短视频和直播,我觉得不靠谱。
创业的第三个条件是:
能够承受负的现金流。 刚开始创业,很可能没有或很少收入,每天却要支出,压力巨大。
只有满足上面三个条件,我认为,才适合创业。
显而易见,刚毕业的学生不容易满足这些条件。前几年,有一种论调鼓励学生创业,这是不正确的。
我的意思不是劝退创业,而是希望大家在越是困难时刻,越不要盲目。 面对失业率上升,你要做的第一位的事情,就是尽快把自己锻造成型,形成稳定的心智和人格,磨练自己的技能。
ios 渐变色 会出现黑色
如下代码:
background-image: linear-gradient(180deg, rgba(0, 0, 0, 0), 1%, #f6f6f6);
background-image: linear-gradient(180deg, rgba(246, 246, 246, 0), 1%, #f6f6f6);
Safari在渐变中对颜色的处理是同时渐变rgba()中的每一个参数,因此该例子中实际上是在渐变从黑色到颜色,从全透明到不透明。因此,中间出现了灰色。
将rgba()中的前三个参数,设置成背景色的颜色值即可。
目前小程序 的image标签已经支持了 svg 的显示
<image src="./xx.svg"/>
大体思路:把svg转成 base64 然后通过 image标签 src设置图片,再动态赋值svg颜色
<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="24 24 48 48"><animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" from="0" to="360" dur="1400ms"></animateTransform><circle cx="48" cy="48" r="20" fill="none" stroke="#eeeeee" stroke-width="2" transform="translate\(0,0\)"><animate attributeName="stroke-dasharray" values="1px, 200px;100px, 200px;100px, 200px" dur="1400ms" repeatCount="indefinite"></animate><animate attributeName="stroke-dashoffset" values="0px;-15px;-125px" dur="1400ms" repeatCount="indefinite"></animate></circle></svg>
%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22100%25%22%20height%3D%22100%25%22%20viewBox%3D%2224%2024%2048%2048%22%3E%3CanimateTransform%20attributeName%3D%22transform%22%20type%3D%22rotate%22%20repeatCount%3D%22indefinite%22%20from%3D%220%22%20to%3D%22360%22%20dur%3D%221400ms%22%3E%3C%2FanimateTransform%3E%3Ccircle%20cx%3D%2248%22%20cy%3D%2248%22%20r%3D%2220%22%20fill%3D%22none%22%20stroke%3D%22%23eeeeee%22%20stroke-width%3D%222%22%20transform%3D%22translate%5C(0%2C0%5C)%22%3E%3Canimate%20attributeName%3D%22stroke-dasharray%22%20values%3D%221px%2C%20200px%3B100px%2C%20200px%3B100px%2C%20200px%22%20dur%3D%221400ms%22%20repeatCount%3D%22indefinite%22%3E%3C%2Fanimate%3E%3Canimate%20attributeName%3D%22stroke-dashoffset%22%20values%3D%220px%3B-15px%3B-125px%22%20dur%3D%221400ms%22%20repeatCount%3D%22indefinite%22%3E%3C%2Fanimate%3E%3C%2Fcircle%3E%3C%2Fsvg%3E
data:image/svg+xml;charset=utf-8,encodeURIComponent后的代码
<image src="data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20width%3D%22100%25%22%20height%3D%22100%25%22%20viewBox%3D%2224%2024%2048%2048%22%3E%3CanimateTransform%20attributeName%3D%22transform%22%20type%3D%22rotate%22%20repeatCount%3D%22indefinite%22%20from%3D%220%22%20to%3D%22360%22%20dur%3D%221400ms%22%3E%3C%2FanimateTransform%3E%3Ccircle%20cx%3D%2248%22%20cy%3D%2248%22%20r%3D%2220%22%20fill%3D%22none%22%20stroke%3D%22%23{{color}}%22%20stroke-width%3D%222%22%20transform%3D%22translate%5C(0%2C0%5C)%22%3E%3Canimate%20attributeName%3D%22stroke-dasharray%22%20values%3D%221px%2C%20200px%3B100px%2C%20200px%3B100px%2C%20200px%22%20dur%3D%221400ms%22%20repeatCount%3D%22indefinite%22%3E%3C%2Fanimate%3E%3Canimate%20attributeName%3D%22stroke-dashoffset%22%20values%3D%220px%3B-15px%3B-125px%22%20dur%3D%221400ms%22%20repeatCount%3D%22indefinite%22%3E%3C%2Fanimate%3E%3C%2Fcircle%3E%3C%2Fsvg%3E" />
注意:这里的颜色 由于是已经被编码了,所以# 已经被转义了 %23, 直接写颜色数字即可
当然你也可以 去掉%23 自己实现一个内部方法
if (color && color.startsWith('#')) {
return `%23${color.slice(1)}`;
}
这样其实就实现了 svg的动态渲染,可是这种写法,写在wxml中 不是特别的优雅,那么如何重构下让我们的代码看起来更优雅呢?
loading.svg.js 文件
export const loadingSvg = (color='#ddd') =>{
const svgXml = `<svg xmlns="http://www.w3.org/2000/svg" width="100%" height="100%" viewBox="24 24 48 48"><animateTransform attributeName="transform" type="rotate" repeatCount="indefinite" from="0" to="360" dur="1400ms"></animateTransform><circle cx="48" cy="48" r="20" fill="none" stroke="${color}" stroke-width="2" transform="translate\(0,0\)"><animate attributeName="stroke-dasharray" values="1px, 200px;100px, 200px;100px, 200px" dur="1400ms" repeatCount="indefinite"></animate><animate attributeName="stroke-dashoffset" values="0px;-15px;-125px" dur="1400ms" repeatCount="indefinite"></animate></circle></svg>`
return `data:image/svg+xml;charset=utf-8,${encodeURIComponent(svgXml)}`
}
onLoad(){
const { loadingSvg } = require('./loading.svg.js')
const svgImg = loadingSvg('#eee')
this.setData({svgImg})
},
<image src="{{svgImg}}"/>
这样看起来舒服多了!!!
@media screen and (orientation: landscape) {
/* 横屏 css*/
body {
flex-direction: row;
}
}
@media screen and (orientation: portrait) {
/*竖屏 css*/
body {
flex-direction: column;
}
}
此属性不等价于设备的屏幕旋转方向。在许多设备上,当屏幕方向为纵向时,打开软键盘将导致视口 viewport 的宽度大于高度,从而导致浏览器突然改用横向样式,而不是保持纵向。
const _body = document.body
const _html = document.documentElement
const clientWidth = _html.clientWidth || _body.clientWidth || window.innerWidth
const clientHeight = _html.clientHeight || _body.clientHeight || window.innerHeight
const viewport = clientWidth > clientHeight ? 'landscape' : 'portrait'
此种方式存在的问题点和 媒体查询一样,当键盘弹起的时候,高度会变化,这个时候判断就会不准确
/*给根节点设置旋转属性*/
body{
-webkit-transform:rotate(-90deg);
-moz-transform: rotate(-90deg);
-ms-transform: rotate(-90deg);
transform: rotate(-90deg);
width: 100vh;
height: 100vh;
}
通过旋转屏幕设置 屏幕横向,这个时候如果使用 vw vh适配的话,要注意旋转后的 vw 即是 vh
EventTarget.addEventListener() 方法将指定的监听器注册到 EventTarget 上,当该对象触发指定的事件时,指定的回调函数就会被执行。 事件目标可以是一个文档上的元素 Element,Document和Window或者任何其他支持事件的对象 (比如 XMLHttpRequest)。
window.addEventListener('sendMsg',function(){
console.log('who dispatch this event?')
}, false);
var res = window.dispatchEvent(new Event('sendMsg'))
Web Components 用原生 js 的方式 构建模块化组件
<template>
和 <slot>
元素使您可以编写不在呈现页面中显示的标记模板。然后它们可以作为自定义元素结构的基础被多次重用,使用过Vue和React等热门框架的应该熟悉。声明一个 class 继承 HTMLElement
class Demo extends HTMLElement {
constructor() {
super()
}
}
// 存在浏览器兼容问题
customElements.define(name, constructor, {extens:'div'})
调用 attachShadow 将一个shadow DOM附加到自定义元素上。使用通常的DOM方法向shadow DOM中添加子元素、事件监听器等等
class Demo extends HTMLElement {
constructor() {
super()
const shadowRoot = this.attachShadow({ mode: "closed" })
shadowRoot.innerHTML = `<div>我是 web components </div>`
this.shadow = shadowRoot
}
}
innerHTML 方式 向影子节点 赋值 一个字符串式的标签
...
shadowRoot.innerHTML = `<div></div>`
this.shadow = shadowRoot
appendChild 方式 向影子节点块后增加一个 element 节点
const pElem = document.createElement('p');
shadowRoot.appendChild(pElem);
<template id="person-template">
<div>
<h2>Personal ID Card</h2>
<slot name="person-name">NAME MISSING</slot>
<ul>
<li><slot name="person-age">AGE MISSING</slot></li>
<li><slot name="person-occupation">OCCUPATION MISSING</slot></li>
</ul>
</div>
</template>
class Demo extends HTMLElement {
constructor() {
super();
const template = document.getElementById('person-template');
const templateContent = template.content;
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.appendChild(templateContent.cloneNode(true));
}
}
const template = document.createElement('template')
template.innerHTML = `<div>test</div>`
class TestComponents extends HTMLElement {
constructor() {
super()
const shadowRoot = this.attachShadow({ mode: "close" })
shadowRoot.appendChild(template.content.cloneNode(true))
}
}
customElements.define('test-components', TestComponents)
const style = document.createElement('style')
style.textContent = `
.wrapper {
color: red;
}`
shadow.appendChild(style)
const style2 = new CSSStyleSheet();
style2.replaceSync(`.wrapper {font-weight:bold;}`)
shadow.adoptedStyleSheets = [style2]
注意adoptedStyleSheet与style标签混合使用都会生效,互相影响
javaScript的类型 包含了 ‘基本数据类型’ 和 ‘引用数据类型’
let Car = function() {}
let benz = new Car()
benz instanceof Car // true
console.log(Object.prototype.toString.call(undefined)) // [object Undefined]
console.log(Object.prototype.toString.call(null)) // [object Null]
var date = new Date();
console.log(Object.prototype.toString.call(date)) // [object Date]
var number = 1; // [object Number]
var string = '123'; // [object String]
var boolean = true; // [object Boolean]
var und = undefined; // [object Undefined]
var nul = null; // [object Null]
var obj = {a: 1} // [object Object]
var symbol = symbol(1) // [object Symbol ]
var array = [1, 2, 3]; // [object Array]
var date = new Date(); // [object Date]
var error = new Error(); // [object Error]
var reg = /a/g; // [object RegExp]
var func = function a(){}; // [object Function]
console.log(Object.prototype.toString.call(Math)); // [object Math]
console.log(Object.prototype.toString.call(JSON)); // [object JSON]
function a() {
console.log(Object.prototype.toString.call(arguments)); // [object Arguments]
}
a();
function myInstanceof(left, right) {
// 这里先用typeof来判断基础数据类型,如果是,直接返回false
if(typeof left !== 'object' || left === null) return false;
// getProtypeOf是Object对象自带的API,能够拿到参数的原型对象
let proto = Object.getPrototypeOf(left);
while(true) { //循环往下寻找,直到找到相同的原型对象
if(proto === null) return false;
if(proto === right.prototype) return true;//找到相同原型对象,返回true
proto = Object.getPrototypeof(proto);
}
}
// 验证一下自己实现的myInstanceof是否OK
console.log(myInstanceof(new Number(123), Number)); // true
function isEmptyObject( obj ) {
var name;
for ( name in obj ) {
return false;
}
return true;
}
在 JavaScript 中,语言所能够保证“安全”(精确)地进行计算的最大整数是 2^53 - 1 ,也就是 9007199254740991 (常量 Number.MAX_SAFE_INTEGER)超过了这个数值,JS 就会产生一些意想不到的问题。比如:
9007199254740991 + 1 // => 结果是 9007199254740992
9007199254740991 + 2 // => 结果也是 9007199254740992
BigInt的提出,解决超过最大整数计算问题, n: 表示超过最大精度的运算
9007199254740991n + 1n // => 结果是 9007199254740992n
9007199254740991n + 4n // => 结果是 9007199254740995n
function getType(obj) {
const lowerCaseTheFirstLetter = (str) => str[0].toLowerCase() + str.slice(1);
const type = typeof obj;
if (type !== 'object') {
return type;
}
return lowerCaseTheFirstLetter(
Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1')
);
}
getType([]); // "array"
getType('123'); // "string"
getType(null); // "null"
getType(undefined); // "undefined"
getType(); // "undefined"
getType(function () {}); // "function"
getType(/123/g); // "regExp"
getType(new Date()); // "date"
getType(new Map()); // "map"
getType(new Set()); // "set"
padding-bottom: constant( safe-area-inset-bottom); /* 兼容 iOS < 11.2 */
padding-bottom: env( safe-area-inset-bottom); /* 兼容 iOS >= 11.2 */
注意:env() 跟 constant() 需要同时存在,而且顺序不能换
@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
.iphone-x {
padding-bottom: constant(safe-area-inset-bottom);
padding-bottom: env(safe-area-inset-bottom);
}
}
非x 系列设备,距离底部距离
@supports (bottom: constant(safe-area-inset-bottom)) or (bottom: env(safe-area-inset-bottom)) {
.iphone-x {
padding-bottom: calc(10rpx + constant(safe-area-inset-bottom));
padding-bottom: calc(10rpx + env(safe-area-inset-bottom));
}
}
正如官网所描述的那样:dom-to-image 可以将任意dom节点转换为用JavaScript编写的矢量(SVG)或(PNG或JPEG)图像。
import domtoimage from 'dom-to-image';
var node = document.getElementById('my-node');
domtoimage.toPng(node)
.then(function (dataUrl) {
var img = new Image();
img.src = dataUrl;
document.body.appendChild(img);
})
.catch(function (error) {
console.error('oops, something went wrong!', error);
});
createImg() {
Toast.loading({
duration: 10*1000,
message: "资料生成中...",
forbidClick: true
});
const node = document.getElementById("sheet-dom-id");
const scale = window.devicePixelRatio
console.log("node:", node);
domtoimage
.toPng(node, {
height: node.offsetHeight * scale,
width: node.offsetWidth * scale,
style: {
transform: `scale(${scale})`,
transformOrigin: 'top left',
width: `${node.offsetWidth}px`,
height: `${node.offsetHeight}px`
}
})
.then(dataUrl => {
console.log("dataUrl:", dataUrl);
const img = new Image();
img.src = dataUrl;
img.style.width = "100%"
document.getElementById("sheet-show-container").appendChild(img);
})
.catch(function(error) {
console.error("oops, something went wrong!", error);
})
.finally(()=>{
Toast.clear()
})
}
生成后的图片可以 ,设置宽度100%,这样不会出现滚动的情况
通过 cavas的方式 把图片进行压缩
/**
* 压缩base64 图片
* @param {*} quality 压缩系数0-1之间
*/
export const compressBase64Img = ({quality=0.6,base64Img}) => {
return new Promise((revose,reject)=>{
const newImage = new Image()
newImage.src = base64Img
newImage.setAttribute("crossOrigin", 'Anonymous')
newImage.onload = function () {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext("2d")
canvas.width = this.width
canvas.height = this.height
ctx.clearRect(0, 0, canvas.width, canvas.height)
ctx.drawImage(this, 0, 0, canvas.width, canvas.height)
const newBase64 = canvas.toDataURL("image/jpeg", quality)
revose(newBase64)
}
newImage.onerror = function () {
reject('图片加载出错')
}
})
}
作为开发者,当然是在不断的追求技术上的造诣,不断的沉底自己的技术;
走技术可能是条死路,因为你不可能玩到天花板级别,所以你怎么办?
今天的升职答辩,领导的一些问题,值得去反思
既然领导这样提要求了,为何不去了解上游领导的需求?帮他们更好的实现?这样不更好?更有话语权?
2022-06-24 周五
// 监听 storage 变化
window.addEventListener('storage', (e)=>{
console.log('e:',e)
if (e.key === 'xxxx') {
const params = JSON.parse(e.newValue);
}
});
window.localStorage.setItem('xxxx',JSON.stringify({
name:'1111',
age:'18'
}))
今天组内同学发现了个问题,代码如下:
{
0 && <div>xxxx<div>
}
这种短路操作符写法,如果第一个为 假,则返回 第一个值,所以页面就会渲染 0
react 中的 jsx 是一个 表达式,当采用 短路写法的时候 如果的一个 值为 0 为假,则 会返回 0
a && b ,如果a 我假,则返回 a
a && b ,如果b 我假,则返回 b
数组,最好 list.length>0 && <>xxxx</>
数字, 最好 String(a) && <>xxxx</>
字符串为空,就渲染空,可以不做处理
对象 总为真
描述: 可以使用变量的形式 使用 css 属性值,变量声明大小写敏感
:root{
--theme-color: #4d4e53;
}
body {
--color: #7F583F;
}
div{
background-color: var(--theme-color)
color: var(--color)
}
div{
background-color: var(--theme-color, #FFFFFF)
}
:root {
--primary-color: red;
--logo-text: var(--primary-color);
}
需要注意的问题是:变量值只能用作属性值,不能用作属性名
.foo {
--side: margin-top;
/* 无效 */
var(--side): 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);
}
// parentEl代表父元素,也就是设置了overflow为可滚动的元素
// childEl代表需要滚动到父元素正中间的直接子元素
// 水平滚动
let x = childEl.offsetLeft - parentEl.clientWidth + parentEl.clientWidth/2 + childEl.clientWidth/2;
parentEl.scrollTo({
left: x,
behavior: "smooth",
});
// 垂直滚动
let y = childEl.offsetTop - parentEl.clientHeight + parentEl.clientHeight/2 + childEl.clientHeight/2;
parentEl.scrollTo({
top: y,
behavior: "smooth",
});
/*隐藏滚动条 */
::-webkit-scrollbar{width: 0;height: 0;color: transparent; dislay:none;}
我们可能会碰到一些这种场景,就是根据对象的键值对来处理逻辑的需求
通常,我会用 Object.keys
或者 Object.values
但是这两个方法只能迭代出 键的数组 或值的数组
Object.entries 有个优点就是可以迭代出 键值对数组
const oj = {
name:'jslin',
age:'16',
sex:'男',
bag:'xxx',
0:'xxxx'
}
Object.entries(oj)
实践中,我们可以用 这个键值对数组更快捷高效的去完成特殊场景需求
如:
Object.entries(oj).map(([key,val])=>{
console.log('key:',key,'val:',val)
})
Object.entries(oj).forEach(([key,val])=>{
console.log('key:',key,'val:',val)
})
for(const [key,val] of Object.entries(oj)){
console.log('key:',key,'val:',val)
}
/**
* Base64编码转换成blob, (data:image/png;base64,xxxx)
* @param {*} base64
* @return {*}
*/
export function base64ToBlob(base64) {
const parts = base64.split(';base64,')
const contentType = parts[0].split(':')[1] // image/png
const raw = atob(parts[1]) // base64数据
const rawLength = raw.length
const uInt8Array = new Uint8Array(rawLength)
for (let i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i)
}
const blobFile = new Blob([uInt8Array], {
type: contentType,
})
return new File([blobFile],`${new Date().getTime()}.${contentType.replace(/image\//g,'')}`,{
type: contentType,
})
}
export function uploadImage(file) {
const formData = new FormData()
formData.append('file', file)
formData.append('xxx', 'xxx') //接口入参
return request('xxxxx', formData)
}
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.