独书先生 Menu

HTML通用组件模板:自定义checkbox样式

需求

原生的checkbox样式很单一,常常需要自定义样式

方式一

使用label关联input[checkbox],input隐藏,label覆盖input显示,设置label选中前后的样式即可。

HTML:

<div class="cbk-tubiao-con">
  <input id="pro-1" class="cbk-tubiao" type="checkbox" />
  <label for="pro-1"></label>
</div>

CSS:

/*自定义checkbox*/
.cbk-tubiao-con>label:before {
    margin-top:-2px;
}
.cbk-tubiao-con {
    height:20px;
    position:relative;
}
.cbk-tubiao-con>label {
    line-height:20px;
}
.cbk-tubiao-con>label:before {
    box-sizing:border-box;
    display:inline-block;
    content:"";
    width:24px;
    height:24px;
    border-radius:50%;
    background:url("http://p31rkzyhv.bkt.clouddn.com/unchoose.png") no-repeat;
    background-size:100%;
    position:absolute;
    top:0;
    left:0;
}
input.cbk-tubiao {
    width:24px;
    height:24px;
    visibility:hidden;
    vertical-align:middle;
}
.cbk-tubiao-con input.cbk-tubiao:checked + label:before {
    content:"";
    background:url("http://p31rkzyhv.bkt.clouddn.com/choose.png") no-repeat;
    text-align: center;
}

把css中的background换成自己的图片即可

方式二

我们用react演示

tsx组件

import React, { useState } from "react";
import styles from "./Checkbox.module.css";

interface Props {
  className?: string;
  onChange?: (state: boolean) => void;
  style?: React.CSSProperties;
  children?: React.ReactNode;
  checked?: boolean;
}

export const Checkbox: React.FC<Props> = ({
  className,
  onChange,
  children,
  style = {},
  checked,
}) => {
  let [checkedState, setCheckedState] = useState(checked || false);

  const handleChange = () => {
    onChange(!checkedState);
    setCheckedState(!checkedState);
  };

  return (
    <label className={styles.container}>
      {children}
      <input type="checkbox" onChange={handleChange} checked={checkedState} />
      <span className={styles.checkmark}></span>
    </label>
  );
};

对应的样式

/* The container */
.container {
  position: relative;
  padding: 0 1em 0 1.4em;
  cursor: pointer;
  font-size: 16px;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

/* Hide the browser's default checkbox */
.container input {
  position: absolute;
  opacity: 0;
  cursor: pointer;
  height: 0;
  width: 0;
}

/* Create a custom checkbox */
.checkmark {
  position: absolute;
  top: 0;
  left: 0;
  height: 1.1em;
  width: 1.1em;
  background-color: gray;
}

/* On mouse-over, add a grey background color */
.container:hover input ~ .checkmark {
  background-color: lightgary;
}

/* When the checkbox is checked, add a blue background */
.container input:checked ~ .checkmark {
  background-color: #2196f3;
}

/* Create the checkmark/indicator (hidden when not checked) */
.checkmark:after {
  content: "";
  position: absolute;
  display: none;
}

/* Show the checkmark when checked */
.container input:checked ~ .checkmark:after {
  display: block;
}

/* Style the checkmark/indicator */
.container .checkmark:after {
  left: 0.4em;
  top: 0.1em;
  width: 0.3em;
  height: 0.7em;
  border: solid white;
  border-width: 0 0.1em 0.1em 0;
  -webkit-transform: rotate(45deg);
  -moz-transform: rotate(45deg);
  transform: rotate(45deg);
}

Uncaught TypeError: (intermediate value)(intermediate value).push is not a function

问题

vue cli3 + element-ui , 使用vue ui 界面工具打包(build) 项目,运行打包完成的项目时候控制台报错:

chunk-vendors.js:1 Uncaught TypeError: (intermediate value)(intermediate value).push is not a function at chunk-vendors.js:1 (anonymous) @ chunk-vendors.js:1

bootstrap:141 Uncaught TypeError: Cannot read property 'bind' of undefined at bootstrap:141 at bootstrap:151

分析

项目内通过静态资源目录(public)引入了另一个打包好的vue工程(1.这个工程是当前项目的前置依赖 2. 这个工程打包好的js是无chunks且不带hash值的,但是当前工程js是有chunks且带hash值的),把静态引入的工程去掉,就不会报那个错了,分析可能是静态工程和现有工程的打包方式冲突了.

百度一波没有解决方案,google一波省时省力,看到vue官方论坛有类似问题,参考

https://forum.vuejs.org/t/error-when-loading-vue-on-a-webpage-that-uses-webpack-3/48955

解决方案

vue.config.js中配置去除chunks即可暂时解决这个问题

chainWebpack: config => { 
  config.optimization.delete('splitChunks') 
}

js按值传递和按引用传递的区别 | 坑点提示

1.概念

按值传递: 函数内参数的值被改变,不影响外部的变量
按引用传递: 函数内参数的值被改变,影响外部的变量

2.例子

(1)按值传递

var a = 1;
function foo(x) {
x = 2;
}
foo(a);
console.log(a); // 仍为1, 未受x = 2赋值所影响

(2)按引用传递

var obj = {x : 1};
function foo(o) {
    o.x = 3;
}
foo(obj);
console.log(obj.x); // 3, 被修改了!

3.坑点提示

var foo = {name:'foo'};
function test(o){
   o = {name:'bar'};  
}
test(foo);
console.log(foo.name); // 'foo',没有被修改

分析

本来foo传入test方法,是可以在方法内部修改foo的属性的,但是在内部直接对形参o重新赋值了一个新的对象{name:’bar’},而对象赋值给o其实是赋值这个对象的地址,等于是把形参o的地址引用链接到了{name:’bar’},而此次赋值之前o是链接到外部foo对象上的,此操作等于是断开了o与foo对象的关系,所以并没有对foo造成修改。
所以,要想修改foo内部属性值,必须使用上述按引用传递的例子,使用 对象.属性 = 'XXX'的方式,如:o.name = 'bar'

参考自:https://www.cnblogs.com/QingChengFE/p/4543608.html,感谢!

npm常用命令及踩坑指南

记录常用的npm命令,不定期更新,欢迎继续关注

windows环境下:

1. 安装npm包

npm install jquery --save

2. 更新一个npm包

npm update jquery --save

3. 删除一个包

npm uninstall jquery --save

4. 安装指定版本的npm包

npm install jquery@2.2.4 --save

扩展: 如何区分–save 和–save–dev?

5. npm更新到最新

npm install npm@latest -g

6. npm降低版本

npm install npm@4 -g

7. 快速删除node_modules

npm install rimraf -g
rimraf node_modules

8. 报错:Node Sass could not find a binding for your current environment: Windows 64-bit with Node.js 8.x 如何处理?

npm rebuild node-sass
npm update

9. 报错:npm ERR! Error: EPERM: operation not permitted, rename 如何处理?

管理员模式运行cmd即可

10.使用淘宝镜像

  1. 临时使用
npm --registry https://registry.npm.taobao.org install koa
  1. 持久使用
npm config set registry https://registry.npm.taobao.org
  1. 通过cnpm
npm install -g cnpm --registry=https://registry.npm.taobao.org

11. 使用官方镜像

npm config set registry https://registry.npmjs.org/

12. 查看npm源地址

npm config get registry

更多npm技巧:
上传发布npm包步骤

js比较Map集合取值和Array循环取值的速度差异

问题

js新的数据类型Map集合,具有数组和对象的优点,不清楚Map的同学,先移步 ES6之Map的用法
但是在使用set方法取值的时候,是否比使用数组的循环取值要快呢?理论上来说,直接取key/value是高性能的,如果在不探究深层次js解析机制的情况下,我们可以通过简单的测试函数来打印出Map取值和for循环的性能比较。

代码

let arr=[];
let arrLength = arr.length = 10000;
for(let i=0;i<arrLength;i++){
    arr[i] = i //arr为一个长度为10000的数组,0-10000
}

let m = new Map()
for(let j=0;j<arrLength;j++){
    m.set(arr[j],arr[j])//m为一个长度为10000的Map集合,key:0-10000,value:0-10000
}



//以下开始比较运行时间/
let rs = arrLength-1;
//取10000次的Map,统计时间
console.time();
for(let c=0;c<arrLength;c++){
    m.get(rs)
}

console.timeEnd();

//取10000次的arr,统计时间
console.time();
for(let c=0;c<arrLength;c++){
    arr.some((c,i,a)=>{ //数组只能用
        return  i == rs
    })
}
console.timeEnd();

结果

default: 1.3701171875ms
default: 3215.39013671875ms

分析

可以看到,Array.some在最大的循环次数下,比Map取值满了2000多倍;
实际工作场景中,取随机key的情况下,也有大概100倍至200倍的速度差异;
即使每次数组取得第一个元素不用“循环”,也有10倍的性能差异,将上述代码中let rs = arrLength-1;改成 let rs = 0;即可体验到。

而且在现在流行各大前端框架中,Map集合是可以被循环渲染到HTML模板中的,类似于 let item of items 此种用法一样对Map集合有效,所以可以放心使用。

原文:https://appsoftea.com/zh/javascript-map-set-vs-array-loop/

npm –save和–save–dev 的区别

npm安装npm包: npm install jquery –save npm安装包到测试环境后缀用加–save-dev,仅生产环境用–save: npm install expose-loader –save-dev –save会把包安装在局部目录的名字和版本号存到package.json中,利于项目分享后,其他人也能快速通过npm install安装你的开发依赖,快速运行项目 npm install X:

  • 会把X包安装到node_modules目录中
  • 不会修改package.json
  • 之后运行npm install命令时,不会自动安装X

npm install X –save:

  • 会把X包安装到node_modules目录中
  • 会在package.json的dependencies属性下添加X
  • 之后运行npm install命令时,会自动安装X到node_modules目录中
  • 之后运行npm install –production或者注明NODE_ENV变量值为production时,会自动安装msbuild到node_modules目录中

npm install X –save-dev:

  • 会把X包安装到node_modules目录中
  • 会在package.json的devDependencies属性下添加X
  • 之后运行npm install命令时,会自动安装X到node_modules目录中
  • 之后运行npm install –production或者注明NODE_ENV变量值为production时,不会自动安装X到node_modules目录中

使用原则: 运行时需要用到的包使用–save,否则使用–save-dev。

js颜色改变深浅 判断浅色自动加深

需求

工作中的需求,动态获取页面中的一个颜色值,应用到另一个元素的背景上,这样保持页面元素的颜色搭配比较统一。

难点

颜色值可以用户任意定义的,但是应用元素的文字字体颜色是固定白色的,这样如果用户定义的是浅色,那么应用元素的背景设置为浅色这个元素的文字就会看不清楚,如下

文字内容

方案

为了白色文字可以看清楚,考虑把浅色背景统一加深处理,已是深色不处理
Continue reading…

Webpack采坑记录 (一)

背景

本系列文章记录在使用webpack中遇到的坑点,包含网友的解决方案,以及个性化的配置,仅用作参考。

Tips: 据我所知,webpack各个版本与其他不同版本的npm包搭配不同,实际采用的配置也不同,所以所有的设置仅针对个人开发环境,本文会尽量提供详细的开发配置,力争做到充分实践、上手即用,降低学习成本。

正文从这里开始

最近项目采用vue-cli 2 + webpack 3的开发环境,新版本的vue脚手架和webpack配置已有诸多不同,不在本文的讨论范围,往谅解。
Continue reading…