├── .babelrc
├── .editorconfig
├── .eslintrc.json
├── .gitignore
├── LICENSE
├── README.md
├── package.json
├── src
├── app.js
├── components
│ └── pageMain
│ │ ├── components
│ │ └── ResizeDiv
│ │ │ ├── index.css
│ │ │ └── index.jsx
│ │ └── index.js
└── images
│ ├── bg.jpg
│ ├── favicon_16.ico
│ └── favicon_32.ico
├── template
└── index.html
├── webpack.common.js
├── webpack.dev.js
└── webpack.prod.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["env", "react","stage-0","stage-3"],
3 | "plugins": [
4 | "syntax-dynamic-import"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
15 | [Makefile]
16 | indent_style = tab
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "extends": "airbnb",
4 | "env": {
5 | "browser": true,
6 | "node": true,
7 | "es6": true,
8 | "jest": true
9 | },
10 | "rules": {
11 | "react/prop-types": [0],
12 | "react/no-unused-prop-types":[0],
13 | "react/jsx-filename-extension": [1, { "extensions": [".js",".jsx"] }],
14 | "react/jsx-first-prop-new-line":[0],
15 | "react/no-array-index-key":[0],
16 | "arrow-body-style": [0],
17 | "arrow-parens": [0],
18 | "no-console":"warn",
19 | "jsx-a11y/anchor-is-valid": [0],
20 | "jsx-a11y/click-events-have-key-events": [0],
21 | "jsx-a11y/interactive-supports-focus": [0],
22 | "jsx-a11y/no-static-element-interactions":[0],
23 | "jsx-a11y/no-noninteractive-element-interactions":[0],
24 | "import/prefer-default-export": [0],
25 | "comma-dangle":[0],
26 | "no-underscore-dangle": [0],
27 | "object-curly-newline":[0],
28 | "indent":[0]
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # 排除引用模块
2 | node_modules/
3 |
4 | # 排除vscode配置
5 | .vscode/
6 |
7 | # 排除单元测试覆盖率结果文件夹
8 | coverage/
9 | package-lock.json
10 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 HanZilu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 在React中实现可调整宽高的div #
2 |
3 | 已废弃,更换仓库地址为:
4 |
5 | https://gitee.com/vvjiang/resizeDiv4React
6 |
7 | 原文:
8 |
9 | * 实现高度和宽度可调整
10 | * 按住鼠标拖动水平bar和垂直bar开始调整,鼠标放开或者移出区域停止调整
11 | * 窗口resize时自适应,并且不影响宽高的调整
12 | * 设定宽高上下限,不能使宽高太小或者太大
13 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "webpack-demo",
3 | "version": "1.0.0",
4 | "description": "webpack的使用demo",
5 | "main": "index.js",
6 | "author": "韩子卢",
7 | "license": "MIT",
8 | "private": true,
9 | "devDependencies": {
10 | "babel-core": "6.26.3",
11 | "babel-eslint": "7.2.1",
12 | "babel-loader": "^7",
13 | "babel-plugin-import": "1.6.3",
14 | "babel-plugin-syntax-dynamic-import": "6.18.0",
15 | "babel-polyfill": "6.26.0",
16 | "babel-preset-env": "1.6.1",
17 | "babel-preset-react": "6.24.1",
18 | "babel-preset-stage-0": "6.24.1",
19 | "babel-preset-stage-3": "6.24.1",
20 | "cross-env": "5.1.3",
21 | "css-loader": "0.28.9",
22 | "eslint": "^4.17.0",
23 | "eslint-config-airbnb": "16.1.0",
24 | "eslint-plugin-import": "2.8.0",
25 | "eslint-plugin-jsx-a11y": "6.0.3",
26 | "eslint-plugin-promise": "3.6.0",
27 | "eslint-plugin-react": "7.6.1",
28 | "eslint-plugin-standard": "3.0.1",
29 | "file-loader": "2.0.0",
30 | "html-loader": "0.5.5",
31 | "html-webpack-plugin": "3.2.0",
32 | "identity-obj-proxy": "3.0.0",
33 | "image-webpack-loader": "4.0.0",
34 | "less": "2.7.3",
35 | "less-loader": "4.0.5",
36 | "mini-css-extract-plugin": "0.4.2",
37 | "style-loader": "0.19.1",
38 | "webpack-cli": "3.1.0",
39 | "webpack-dev-server": "^3.7.2",
40 | "webpack-merge": "4.1.4"
41 | },
42 | "scripts": {
43 | "dev": "webpack-dev-server --config webpack.dev.js",
44 | "prod": "cross-env NODE_ENV=production webpack -p --config webpack.prod.js",
45 | "build": "cross-env webpack -p --config webpack.prod.js",
46 | "test": "jest --coverage",
47 | "mock": "json-server --watch mock/db.json"
48 | },
49 | "dependencies": {
50 | "clean-webpack-plugin": "0.1.18",
51 | "prop-types": "15.6.0",
52 | "react": "^16.8.6",
53 | "react-dom": "^16.8.6",
54 | "react-loadable": "5.4.0",
55 | "react-redux": "5.0.6",
56 | "react-router-dom": "4.2.2",
57 | "redux": "3.7.2",
58 | "redux-actions": "2.2.1",
59 | "redux-logger": "3.0.6",
60 | "redux-promise": "0.6.0",
61 | "redux-thunk": "2.3.0",
62 | "underscore": "^1.9.1",
63 | "webpack": "4.19.0"
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/app.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | // import { BrowserRouter as Router, Route } from 'react-router-dom';
4 | import { HashRouter as Router, Route } from 'react-router-dom';
5 | import Loadable from 'react-loadable';
6 |
7 | function Loading() {
8 | return
Loading...
;
9 | }
10 |
11 | const PageMain = Loadable({
12 | loader: () => import('./components/pageMain'),
13 | loading: Loading,
14 | });
15 |
16 |
17 | const App = () => (
18 |
19 |
20 |
21 |
22 |
23 | );
24 |
25 | ReactDOM.render(, document.getElementById('app'));
26 |
--------------------------------------------------------------------------------
/src/components/pageMain/components/ResizeDiv/index.css:
--------------------------------------------------------------------------------
1 |
2 | .container{
3 | margin: 30px;
4 | overflow: hidden;
5 | position: absolute;
6 | top: 0;
7 | left: 0;
8 | bottom: 0;
9 | right: 0;
10 | }
11 |
12 | .content{
13 | position: absolute;
14 | top: 0;
15 | left: 0;
16 | bottom: 0;
17 | right: 0;
18 | min-height: 300px;
19 | }
20 |
21 | .left{
22 | width: 500px;
23 | height: 100%;
24 | float: left;
25 | position: relative;
26 | }
27 |
28 | .left-top{
29 | position: absolute;
30 | top: 0;
31 | bottom: 104px;
32 | width: 100%;
33 | background-color: lightblue;
34 | box-sizing: border-box;
35 | }
36 |
37 | .h-resize{
38 | height: 4px;
39 | width: 100%;
40 | background: #fff;
41 | position: absolute;
42 | bottom: 100px;
43 | z-index: 1;
44 | cursor: row-resize;
45 | user-select: none;
46 | }
47 |
48 | .left-bottom{
49 | position: absolute;
50 | bottom: 0;
51 | width: 100%;
52 | height: 100px;
53 | background-color: lightgreen;
54 | box-sizing: border-box;
55 | }
56 |
57 | .v-resize{
58 | height: 100%;
59 | width: 4px;
60 | position: absolute;
61 | background: #fff;
62 | left: 500px;
63 | z-index: 2;
64 | cursor: col-resize;
65 | user-select: none;
66 | }
67 |
68 | .right{
69 | margin-left: 504px;
70 | background-color: lightsalmon;
71 | height: 100%;
72 | box-sizing: border-box;
73 | }
74 |
75 |
--------------------------------------------------------------------------------
/src/components/pageMain/components/ResizeDiv/index.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import _ from 'underscore'
3 | import styles from './index.css'
4 |
5 | // 可调整宽高的Div
6 | export default class ResizeDiv extends Component {
7 | state = {
8 | isHResize: false,
9 | isVResize: false,
10 | hNum: 100,
11 | vNum: 500,
12 | hNumLimit: 30,
13 | vNumLimit: 30
14 | }
15 |
16 | resizeOffsetInfo = {
17 | clientTop: 0,
18 | clientLeft: 0
19 | }
20 |
21 | leftHeight = 0
22 |
23 | containerWidth = 0
24 |
25 | componentDidMount() {
26 | this.initResizeInfo()
27 | const throttled = _.throttle(() => {
28 | this.initResizeInfo()
29 | }, 200)
30 |
31 | window.onresize = throttled
32 | }
33 | componentWillUnmount() {
34 | window.onresize = null
35 | }
36 |
37 | /**
38 | * 初始化resize信息
39 | */
40 | initResizeInfo = () => {
41 | const hEle = document.getElementById('h_resize_container')
42 | this.resizeOffsetInfo = this.getEleOffset(hEle)
43 | this.leftHeight = hEle.offsetHeight
44 | this.containerWidth = document.getElementById('v_resize_container').offsetWidth
45 |
46 | if (hEle.offsetHeight - this.state.hNum < this.state.hNumLimit) {
47 | this.setState({
48 | hNum: hEle.offsetHeight - this.state.hNumLimit
49 | })
50 | }
51 | if (this.containerWidth - this.state.vNum < this.state.vNumLimit) {
52 | this.setState({
53 | vNum: this.containerWidth - this.state.vNumLimit
54 | })
55 | }
56 | }
57 |
58 | /**
59 | * 获取元素的偏移信息
60 | */
61 | getEleOffset(ele) {
62 | var clientTop = ele.offsetTop
63 | var clientLeft = ele.offsetLeft
64 | let current = ele.offsetParent
65 | while (current !== null) {
66 | clientTop += current.offsetTop
67 | clientLeft += current.offsetLeft
68 | current = current.offsetParent
69 | }
70 | return {
71 | clientTop,
72 | clientLeft,
73 | height: ele.offsetHeight,
74 | width: ele.offsetWidth
75 | }
76 | }
77 |
78 | /**
79 | * 开始拖动水平调整块
80 | */
81 | hResizeDown = () => {
82 | this.setState({
83 | isHResize: true
84 | })
85 | }
86 |
87 | /**
88 | * 拖动水平调整块
89 | */
90 | hResizeOver = (e) => {
91 | const { isHResize, hNum, hNumLimit } = this.state
92 | if (isHResize && hNum >= hNumLimit && (this.resizeOffsetInfo.height - hNum >= hNumLimit)) {
93 | let newValue = this.resizeOffsetInfo.clientTop + this.resizeOffsetInfo.height - e.clientY
94 | if (newValue < hNumLimit) {
95 | newValue = hNumLimit
96 | }
97 | if (newValue > this.resizeOffsetInfo.height - hNumLimit) {
98 | newValue = this.resizeOffsetInfo.height - hNumLimit
99 | }
100 | this.setState({
101 | hNum: newValue
102 | })
103 | }
104 | }
105 |
106 | /**
107 | * 开始拖动垂直调整块
108 | */
109 | vResizeDown = () => {
110 | this.setState({
111 | isVResize: true
112 | })
113 | }
114 |
115 | /**
116 | * 拖动垂直调整块
117 | */
118 | vResizeOver = (e) => {
119 | const { isVResize, vNum, vNumLimit } = this.state
120 | if (isVResize && vNum >= vNumLimit && (this.containerWidth - vNum >= vNumLimit)) {
121 | let newValue = e.clientX - this.resizeOffsetInfo.clientLeft
122 | if (newValue < vNumLimit) {
123 | newValue = vNumLimit
124 | }
125 | if (newValue > this.containerWidth - vNumLimit) {
126 | newValue = this.containerWidth - vNumLimit
127 | }
128 | this.setState({
129 | vNum: newValue
130 | })
131 | }
132 | }
133 |
134 | /**
135 | * 只要鼠标松开或者离开区域,那么就停止resize
136 | */
137 | stopResize = () => {
138 | this.setState({
139 | isHResize: false,
140 | isVResize: false
141 | })
142 | }
143 |
144 | render() {
145 | const hCursor = this.state.isHResize ? 'row-resize' : 'default'
146 | const hColor = this.state.isHResize ? '#ddd' : '#fff'
147 | const vCursor = this.state.isVResize ? 'col-resize' : 'default'
148 | const vColor = this.state.isVResize ? '#ddd' : '#fff'
149 |
150 | return (
151 |
152 |
153 |
155 |
aasd
156 |
157 |
asd
158 |
159 |
160 |
161 | asdas
162 |
163 |
164 |
165 | )
166 | }
167 | }
168 |
--------------------------------------------------------------------------------
/src/components/pageMain/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ResizeDiv from './components/ResizeDiv/index.jsx';
3 |
4 | /**
5 | * 首页
6 | */
7 | class PageMain extends React.Component {
8 | render() {
9 | return (
10 |
11 |
12 |
13 | );
14 | }
15 | }
16 |
17 | export default PageMain
18 |
--------------------------------------------------------------------------------
/src/images/bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vvjiang/resizeDiv4React/3d7e922bf8c9e3f89623a8eb91cf4669b66744f0/src/images/bg.jpg
--------------------------------------------------------------------------------
/src/images/favicon_16.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vvjiang/resizeDiv4React/3d7e922bf8c9e3f89623a8eb91cf4669b66744f0/src/images/favicon_16.ico
--------------------------------------------------------------------------------
/src/images/favicon_32.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/vvjiang/resizeDiv4React/3d7e922bf8c9e3f89623a8eb91cf4669b66744f0/src/images/favicon_32.ico
--------------------------------------------------------------------------------
/template/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 微澜之间
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/webpack.common.js:
--------------------------------------------------------------------------------
1 | const HtmlWebpackPlugin = require('html-webpack-plugin');
2 | const CleanWebpackPlugin = require('clean-webpack-plugin');
3 | const path = require('path');
4 | const webpack = require('webpack');
5 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
6 |
7 | const pathsToClean = [
8 | 'build',
9 | ];
10 |
11 | const isProduction = process.env.NODE_ENV === 'production';
12 |
13 | module.exports = {
14 | entry: {
15 | main: ['babel-polyfill', './src/app.js'],
16 | },
17 | output: {
18 | path: path.resolve(__dirname, 'build'),
19 | filename: '[name].[chunkhash].js',
20 | // 添加 chunkFilename
21 | publicPath: '/',
22 | chunkFilename: '[name].[chunkhash:5].chunk.js',
23 | },
24 | plugins: [
25 | new HtmlWebpackPlugin({
26 | template: './template/index.html',
27 | filename: 'demo.html',
28 | minify: {
29 | collapseWhitespace: true,
30 | },
31 | hash: isProduction,
32 | }),
33 | new MiniCssExtractPlugin({ filename: '[name].[contenthash].css', allChunks: false }),
34 | new CleanWebpackPlugin(pathsToClean),
35 | ],
36 | module: {
37 | rules: [{
38 | test: /\.jsx?$/,
39 | exclude: /(node_modules)/,
40 | use: {
41 | loader: 'babel-loader',
42 | options: {
43 | presets: ['react', 'env', 'stage-0', 'stage-3'],
44 | plugins: [
45 | ['import', { libraryName: 'antd-mobile', style: 'css' }], // `style: true` 会加载 less 文件
46 | ],
47 | },
48 | },
49 | },
50 | {
51 | test: /\.(gif|png|jpe?g|svg)$/i,
52 | use: [{
53 | loader: 'file-loader',
54 | options: {
55 | name: '[name].[ext]',
56 | outputPath: 'images/',
57 | },
58 | },
59 | {
60 | loader: 'image-webpack-loader',
61 | options: {
62 | bypassOnDebug: true,
63 | },
64 | },
65 | ],
66 | },
67 | {
68 | test: /\.html$/,
69 | use: [{
70 | loader: 'html-loader',
71 | options: {
72 | minimize: true,
73 | },
74 | }],
75 | }],
76 | },
77 | };
78 |
--------------------------------------------------------------------------------
/webpack.dev.js:
--------------------------------------------------------------------------------
1 | const merge = require('webpack-merge');
2 | const common = require('./webpack.common.js');
3 | const webpack = require('webpack');
4 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
5 | const { theme } = require('./package.json');
6 |
7 | module.exports = merge(common, {
8 | mode: 'development',
9 | output: {
10 | filename: '[name].[hash].js',
11 | },
12 | devtool: 'source-map',
13 | devServer: {
14 | port: 8787,
15 | open: true,
16 | compress: true,
17 | index: 'demo.html',
18 | },
19 | plugins: [
20 | new webpack.HotModuleReplacementPlugin(),
21 | ],
22 | module: {
23 | rules: [{
24 | test: /\.css$/,
25 | exclude: /node_modules/,
26 | use: [MiniCssExtractPlugin.loader, 'css-loader?modules&sourceMap'],
27 | }, {
28 | test: /\.css$/,
29 | include: /node_modules/,
30 | use: [MiniCssExtractPlugin.loader, 'css-loader?sourceMap'],
31 | },
32 | {
33 | test: /\.less$/,
34 | use: [
35 | MiniCssExtractPlugin.loader,
36 | 'css-loader?modules&sourceMap',
37 | {
38 | loader: 'less-loader',
39 | options: {
40 | modifyVars: theme
41 | }
42 | },
43 | ],
44 | },
45 | ],
46 | },
47 | });
48 |
--------------------------------------------------------------------------------
/webpack.prod.js:
--------------------------------------------------------------------------------
1 | const merge = require('webpack-merge');
2 | const common = require('./webpack.common.js');
3 | const MiniCssExtractPlugin = require('mini-css-extract-plugin');
4 | const webpack = require('webpack');
5 |
6 | module.exports = merge(common, {
7 | mode: 'production',
8 | entry: {
9 | vendor: [
10 | 'react',
11 | 'react-dom',
12 | 'redux',
13 | 'react-router-dom',
14 | 'react-redux',
15 | 'redux-actions',
16 | 'axios'
17 | ],
18 | },
19 | plugins: [
20 | // new webpack.optimize.CommonsChunkPlugin({
21 | // names: ['vendor'],
22 | // minChunks: Infinity,
23 | // filename: 'common.bundle.[chunkhash].js',
24 | // }),
25 | // new webpack.optimize.CommonsChunkPlugin({
26 | // names: ['manifest'],
27 | // filename: 'manifest.bundle.[chunkhash].js',
28 | // }),
29 | new webpack.optimize.RuntimeChunkPlugin({
30 | name: 'manifest'
31 | }),
32 | new MiniCssExtractPlugin({ filename: '[name].[contenthash].css', allChunks: false }),
33 | ],
34 | optimization: {
35 | splitChunks: {
36 | chunks: 'initial',
37 | cacheGroups: { // 这里开始设置缓存的 chunks
38 | default: {
39 | chunks: 'initial', // 必须三选一: "initial" | "all" | "async"(默认就是异步)
40 | minSize: 0, // 最小尺寸,默认0,
41 | minChunks: 2, // 最小 chunk ,默认1
42 | maxInitialRequests: 5, // 最大初始化请求书,默认1
43 | },
44 | vendor: {
45 | chunks: 'initial', // 必须三选一: "initial" | "all" | "async"(默认就是异步)
46 | names: ['vendor'], // 要缓存的 分隔出来的 chunk 名称
47 | priority: 10, // 缓存组优先级
48 | enforce: true,
49 | filename: 'common.bundle.[chunkhash].js',
50 | }
51 | }
52 | },
53 | runtimeChunk: true
54 | },
55 | module: {
56 | rules: [
57 | {
58 | test: /\.css$/,
59 | exclude: /node_modules/,
60 | use: [MiniCssExtractPlugin.loader, 'css-loader?modules'],
61 | }, {
62 | test: /\.css$/,
63 | include: /node_modules/,
64 | use: [MiniCssExtractPlugin.loader, 'css-loader']
65 | },
66 | {
67 | test: /\.less$/,
68 | use: [MiniCssExtractPlugin.loader, 'css-loader?modules', 'less-loader']
69 | },
70 | ],
71 | }
72 | });
73 |
--------------------------------------------------------------------------------