Open yingwinwin opened 4 years ago
import React, { Component } from 'react'
export default class Back extends Component {
render() {
const divStyle = {
'width':'200px',
'height':'200px',
'border':'1px solid #000'
}
return (
<div>
<input type="text" onBlur= {(e)=>{
console.log('blur')
}}/>
<div style={divStyle} onTouchEnd = {(e)=>{
console.log('click')
}}>div</div>
</div>
)
}
}
效果
import React, { Component } from 'react'
export default class Keyboard extends Component {
constructor(){
super();
this.state={
value:'',
arr:[]
}
}
componentDidMount(){
document.onkeyup = (e)=>{
if(e.keyCode === 13){
this.refs.input.blur()
this.setState({
arr:[...this.state.arr,this.state.value],
value:''
})
}
}
}
render() {
return (
<div>
{
this.state.arr.map(item=>{
return <span key={item}>{item}</span>
})
}
<input type="text" ref="input" value={this.state.value} onChange={(e)=>this.setState({value:e.target.value})} />
</div>
)
}
}
效果
import React, { Component } from "react";
export default class index extends Component {
state = {
value: "",
assis: ["123", "高风险", "567", "234"],
};
handleChange = (e) => {
this.setState({
value: e.target.value,
});
};
renderRed = (ele) => {
if (ele) {
const reg = new RegExp(`${this.state.value}`, "g");
let times = 0; // 记录替换的次数
const inputValueSplit = ele.split(reg); // 分割当前的数组
const replaceArr = [];
ele.replace(reg, (...arg) => {
replaceArr.push({ key: arg[0], keyValue: inputValueSplit[times] });
times++;
});
return (
<div>
{replaceArr.map((item, index) => {
return (
<span key={ele + index}>
{item.keyValue && (
/* 未匹配到的内容前面的内容 */
<span style={{ color: "red" }}>{item.keyValue}</span>
)}
{/* 匹配到的内容 */}
<span style={{ color: "blue" }}>{item.key}</span>
</span>
);
})}
{/* 未匹配到的内容 */}
{inputValueSplit[inputValueSplit.length - 1] && (
<span style={{ color: "yellow" }}>
{inputValueSplit[inputValueSplit.length - 1]}
</span>
)}
</div>
);
}
};
renderList = () => {
return this.state.assis.map((item) => (
<li key={item}>{this.renderRed(item)}</li>
));
};
render() {
return (
<div>
<input
value={this.state.value}
onChange={this.handleChange}
type="text"
/>
{
this.state.value && <ul>{this.renderList()}</ul>
}
</div>
);
}
}
效果
// 数组对象去重
let person = [
{id: 0, name: "小明"},
{id: 1, name: "小张"},
{id: 2, name: "小李"},
{id: 3, name: "小孙"},
{id: 1, name: "小周"},
{id: 2, name: "小陈"},
];
let obj = {};
// 方法1
let peon = person.reduce((cur,next) => {
obj[next.id] ? "" : obj[next.id] = true && cur.push(next);
console.log(obj[next.id])
return cur;
},[])
console.log(peon);
let arr = [];
// 方法 2
for(let i = 0 ; i < person.length; i++) {
if(!obj[person[i].id]) {
arr.push(person[i]);
obj[person[i].id] = true;
}
}
console.log(arr)
// 可以阻止浏览器默认的触摸事件
*{
touch-action: none;
}
import React from "react";
import MulitPicker from "./components/MulitPicker";
class App extends React.Component { state = { data: [ { id: "01", value: "北京市", child: [ { id: "00101", value: "北京市", child: [ { id: "000101", value: "东城区", }, { id: "000102", value: "西城区", }, { id: "000103", value: "朝阳区", }, ], }, ], }, { id: "02", value: "天津市", child: [ { id: "00201", value: "天津市", child: [ { id: "000201", value: "和平区", }, { id: "000202", value: "河东区", }, { id: "000203", value: "河西区", }, ], }, ], }, ], };
pca = (pca) => {
console.log(pca);
};
render() {
return
export default App;
- 子组件
```jsx
import React, { Component } from "react";
import "./mulitPicker.css";
export default class MulitPicker extends Component {
state = {
prov: 0, // 省
city: 0, // 市
area: 0, // 区
translateY: [0, 0, 0], // 移动Y
startFinger: 0, // 手指刚开始点击的位置
liHeight: 40, // li的高度
pca: [], // 返回给父组件省市县的数组
};
/* 初始化省市区的值 */
componentDidMount() {
this.getPCA();
}
/**
* @method hanleTouchStart
* @param {object} e window事件对象
* @return {null}
*/
hanleTouchStart = (e) => {
e.preventDefault();
let startFinger = e.changedTouches[0].clientY; //获取初始手指触碰的值
this.setState({
startFinger,
});
};
/**
* @method hanleTouchMove
* @param {object} e window事件对象
* @param {number} idx 触碰的是第几列
* @return {null}
*/
hanleTouchMove = (e, idx) => {
e.preventDefault();
let nowFinger = e.changedTouches[0].clientY; // 获取移动是手指触碰的值
let distance = nowFinger - this.state.startFinger; // 用移动时的位置-开始时候的位置 = 距离
this.setState({
translateY: this.state.translateY.map((item, index) => {
// 如果是当前手指触碰的这列
if (index === idx) {
item += distance; // 就让translateY等于这个距离
}
return item;
}),
});
};
/**
* @method hanleTouchEnd
* @param {object} e window事件对象
* @param {number} idx 触碰的是第几列
* @param {number} len 触碰这一列的数组的长度
* @return {null}
*/
hanleTouchEnd = (e, idx, len) => {
e.preventDefault();
this.setState(
{
translateY: this.state.translateY.map((item, index) => {
// 如果是当前手指触碰的这列
if (index === idx) {
item = item > 0 ? 0 : item; // 大于 0 ,说明用户是滑动的第一列,所以就只能是第一列,否则就是用户滑动的距离
item =
item < (-len + 1) * this.state.liHeight // 如果用户滑动的距离大于最大的数组长度 * 高的话,就让它等于当前的最大高,否则就是它滑动的距离
? (-len + 1) * this.state.liHeight
: item;
/* 求出用户多滑的位置 */
let sub = item % this.state.liHeight;
//如果多滑的位置,小于一半,就让它回到原来的,否则就加一个
if (sub < this.state.liHeight / 2) {
item = item - sub;
} else {
item = item + (this.state.liHeight - sub);
}
}
return item;
}),
},
() => {
this.setPCA(idx); //在回调里调用得到当次的值
}
);
};
/* 确定按钮 */
handleSure = () => {
this.props.pca(this.state.pca); // 给父组件返回值
};
/* 设置省动其他也动 */
setProv = () => {
let temp = [...this.state.translateY];
temp[1] = 0;
temp[2] = 0;
this.setState(
{
prov: Math.abs(this.state.translateY[0]) / 40,
city: 0,
area: 0,
translateY: temp,
},
() => {
this.getPCA();
}
);
};
/* 设置城市动其他也动 */
setCity = () => {
let temp = [...this.state.translateY];
temp[2] = 0;
this.setState(
{
prov: Math.abs(this.state.translateY[0]) / 40,
city: Math.abs(this.state.translateY[1]) / 40,
area: 0,
translateY: temp,
},
() => {
this.getPCA();
}
);
};
/* 设置区的内容 */
setArea = () => {
this.setState(
{
area: Math.abs(this.state.translateY[2]) / 40,
},
() => {
this.getPCA();
}
);
};
/* 设置省市区三省联动 idx为滑动的每一列*/
setPCA = (idx) => {
const setMethod = new Map([
[0, this.setProv],
[1, this.setCity],
[2, this.setArea],
]);
setMethod.get(idx)();
};
/* 得到省市县的值传给父组件 */
getPCA = () => {
const { data } = this.props;
const { prov, city, area } = this.state;
let p = data[prov].value;
let c = data[prov].child[city].value;
let a = data[prov].child[city].child[area].value;
this.setState({
pca: [p, c, a],
});
};
/**
* @method hanleTouchEnd
* @param {object} data 父组件传过来的转换后的值
* @param {number} p 传过来省的数组的位置
* @param {number} c 传过来市的数组的位置
* @return {null}
*/
renderPickerCol = (data, p, c) => {
if (!data) return;
let prov = data;
let city = data[p].child;
let area = data[p].child[c].child;
return [prov, city, area].map((item, idx) => (
<ul
key={idx}
className="picker-ulCol"
style={{
transform: `translate3d(0, ${this.state.translateY[idx]}px, 0)`,
transition: `transform 0.2s ease-out`,
}}
onTouchStart={(e) => this.hanleTouchStart(e)}
onTouchMove={(e) => this.hanleTouchMove(e, idx)}
onTouchEnd={(e) => this.hanleTouchEnd(e, idx, item.length)}
>
<li className="picker-list"></li>
<li className="picker-list"></li>
{this.renderPickerList(item)}
<li className="picker-list"></li>
<li className="picker-list"></li>
</ul>
));
};
renderPickerList = (item) => {
return item.map((ele) => (
<li key={ele.id} className="picker-list">
{ele.value}
</li>
));
};
render() {
return (
<div className="picker-wrap">
<div className="picker-title">
<div className="picker-cancel">取消</div>
<div className="picker-sure" onClick={this.handleSure}>
确定
</div>
</div>
<div className="picker-content">
{this.renderPickerCol(
this.props.data,
this.state.prov,
this.state.city
)}
<div className="picker-mid"></div>
</div>
</div>
);
}
}
ul li { list-style: none; }
.picker-wrap { width: 100%; height: 250px;
.picker-title { position: relative; width: 100%; height: 50px; display: flex; justify-content: space-between; padding: 0 20px; box-sizing: border-box; line-height: 50px; z-index: 3; }
.picker-content { display: flex; position: relative; .picker-ulCol { flex: 1; height: 200px; z-index: 2;
.picker-list {
height: 40px;
line-height: 40px;
text-align: center;
z-index: 2;
}
}
.picker-mid {
position: absolute;
top: 80px;
width: 100%;
height: 40px;
border-bottom: 1px solid #ccc;
border-top: 1px solid #ccc;
z-index: 1;
}
} }
![image](https://user-images.githubusercontent.com/55273635/82153016-8958c000-9897-11ea-84a6-4cabb0805bb8.png)
点击一下出现❌,再点击一次删除
效果