{"id":18735238,"url":"https://github.com/biaochenxuying/split","last_synced_at":"2026-03-18T00:46:18.151Z","repository":{"id":96706884,"uuid":"163089633","full_name":"biaochenxuying/split","owner":"biaochenxuying","description":"js 实现上下拖动改变父 div 的高度，左右上下拖动动态分割孩子 div 的宽高 ","archived":false,"fork":false,"pushed_at":"2019-10-24T10:22:05.000Z","size":47,"stargazers_count":48,"open_issues_count":0,"forks_count":10,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-12T19:13:17.687Z","etag":null,"topics":["arrow","javascript","jquery","split"],"latest_commit_sha":null,"homepage":" https://biaochenxuying.github.io/split/index.html","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/biaochenxuying.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-12-25T14:32:25.000Z","updated_at":"2025-03-08T18:55:32.000Z","dependencies_parsed_at":null,"dependency_job_id":"903d17e8-af90-4d64-8347-42457dc12ecc","html_url":"https://github.com/biaochenxuying/split","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/biaochenxuying/split","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biaochenxuying%2Fsplit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biaochenxuying%2Fsplit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biaochenxuying%2Fsplit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biaochenxuying%2Fsplit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/biaochenxuying","download_url":"https://codeload.github.com/biaochenxuying/split/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/biaochenxuying%2Fsplit/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262344251,"owners_count":23296466,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arrow","javascript","jquery","split"],"created_at":"2024-11-07T15:16:11.525Z","updated_at":"2026-03-18T00:46:18.098Z","avatar_url":"https://github.com/biaochenxuying.png","language":"JavaScript","readme":"\n![](https://upload-images.jianshu.io/upload_images/12890819-b26f439121646da3.jpg?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n# 1. 需求\n\n实现父 div 里面 左右，上下动态分割 div，并上下改变父 div 的高度，并且宽和高都是按百分比（如图） 。\n\n![](https://upload-images.jianshu.io/upload_images/12890819-afc3e32ece5f4c2b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n# 2. 实现原理\n\n## 2.1 父布局\n\n```\n\u003cdiv class='hj-wrap'\u003e\n        \u003cdiv class=\"arrow\"\u003e\u003c/div\u003e\n    \u003c/div\u003e\n```\n\n- 首先一个父 div 为 hj-wrap，相对定位 。\n- 一个改变父 div 高度的 arrow，用于上下拖动 , 不能占有位置，所以要绝对定位，并定位到最右下角。\n- 上下拖动的 arrow，当上拖动时，arrow 的父 div 的高度变小，当下拖动时，arrow 的父 div 的高度变大。\n\n# 2.2 横向布局\n\n```\n\u003cdiv class='hj-wrap'\u003e\n        \u003cdiv class=\"hj-transverse-split-div\"\u003e\n            横 向\n            \u003clabel class=\"hj-transverse-split-label\"\u003e\u003c/label\u003e\n        \u003c/div\u003e\n        \u003cdiv class=\"hj-transverse-split-div\"\u003e横 向 2\n            \u003clabel class=\"hj-transverse-split-label\"\u003e\u003c/label\u003e\n        \u003c/div\u003e\n        \u003cdiv class=\"hj-transverse-split-div\"\u003e横 向 3\n            \u003clabel class=\"hj-transverse-split-label\"\u003e\u003c/label\u003e\n        \u003c/div\u003e\n        \u003cdiv class=\"hj-transverse-split-div\"\u003e横 向 4\n            \u003clabel class=\"hj-transverse-split-label\"\u003e\u003c/label\u003e\n        \u003c/div\u003e\n        \u003cdiv class=\"hj-transverse-split-div\"\u003e横 向 5\n        \u003c/div\u003e\n        \u003cdiv class=\"arrow\"\u003e\u003c/div\u003e\n    \u003c/div\u003e\n```\n \n- 每一个横向的 div 为 hj-transverse-split-div 并相对定位，里面有一个拖动改变左右的 label 为 hj-transverse-split-label ，不能占有位置，所以要绝对定位，并定位到最右边并高为 100%，最后一个横向的 div 不用 hj-transverse-split-label 。\n- 拖动改变左右的 label 时，向左时，label 的父 div 的宽变小，label 的父 div 相邻的 右边的 div 宽度变大。\n\n# 2.3 竖向布局\n\n```\n\u003cdiv class='hj-wrap verticals'\u003e\n        \u003cdiv class=\"hj-vertical-split-div\"\u003e上\n            \u003clabel class=\"hj-vertical-split-label\"\u003e\u003c/label\u003e\n        \u003c/div\u003e\n        \u003cdiv class=\"hj-vertical-split-div\"\u003e中\n            \u003clabel class=\"hj-vertical-split-label\"\u003e\u003c/label\u003e\n        \u003c/div\u003e\n        \u003cdiv class=\"hj-vertical-split-div\"\u003e下\u003c/div\u003e\n        \u003cdiv class=\"arrow\"\u003e\u003c/div\u003e\n    \u003c/div\u003e\n```\n \n- 每一个横向的 div 为 hj-vertical-split-div 并相对定位，里面有一个拖动改变左右的 label 为 hj-vertical-split-label ，不能占有位置，所以要绝对定位，并定位到最下边并宽为 100%，最后一个竖向的 div 不用再放 hj-vertical-split-label 的 label 。\n- 拖动改变上下的 label 时，向上时，label 的父 div 的高度变小，label 的父 div 相邻的下边的 div 高度变大。\n\n# 3. js 实现\n\n代码：\n\n```\n/**\n * name:   split.js\n * author:  biaochen\n * date:    2018-12-26\n *\n */\n$(function() {\n    //鼠标横向、竖向、和改变父高度的上下 操作对象\n    var thisTransverseObject, thisVerticalObject, thisArrowObject;\n    //文档对象\n    var doc = document;\n    //横向分割栏\n    var transverseLabels = $(\".hj-wrap\").find(\".hj-transverse-split-label\");\n    //竖向分割栏\n    var verticalLabels = $(\".hj-wrap\").find(\".hj-vertical-split-label\");\n    // 改变父高度的 箭头 div\n    var parentArrow = $(\".hj-wrap\").find(\".arrow\");\n\n    // 设置宽\n    function setWidth(type) {\n        if (type === \"init\") {\n            var length = $(\".hj-wrap\").length;\n            if (length \u003e 0) {\n                for (var i = 0; i \u003c length; i++) {\n                    var width = $($(\".hj-wrap\")[i])[0].offsetWidth;\n                    var hjDivNums = $($(\".hj-wrap\")[i]).children(\".hj-transverse-split-div\");\n                    // var defaultWidth = Math.floor(100 / hjDivNums.length);\n                    var defaultWidth = Math.floor(width / hjDivNums.length);\n                    $($(\".hj-wrap\")[i])\n                        .children(\".hj-transverse-split-div\")\n                        .width(defaultWidth + \"px\");\n                    // .width(defaultWidth + \"%\");\n                }\n            }\n        } else {\n            // 设置百分比\n            var transverseDivs = $(\".hj-transverse-split-div\")\n            var widthLength = transverseDivs.length\n            for (var i = 0; i \u003c widthLength; i++) {\n                var width = $(transverseDivs[i]).width();\n                var parentWidth = $(transverseDivs[i])\n                    .parent()\n                    .width();\n                var rate = (width / parentWidth) * 100 + \"%\";\n                $(transverseDivs[i]).css({ width: rate });\n            }\n        }\n    }\n\n    // 设置高\n    function setHeight(type) {\n        if (type === \"init\") {\n            var verticalsParentDivs = $(\".verticals\");\n            var parentLengths = verticalsParentDivs.length;\n            for (var i = 0; i \u003c parentLengths; i++) {\n                var parentHeight = $(verticalsParentDivs[i]).height();\n                var childrenNum = $(verticalsParentDivs[i]).children(\n                    \".hj-vertical-split-div\"\n                ).length;\n                var defaultHeight = Math.floor(parentHeight / childrenNum);\n                // var rate = Math.floor((height / parentHeight)* 100)  + '%'\n                var defaultHeight = Math.floor(100 / childrenNum);\n                $(verticalsParentDivs[i])\n                    .children(\".hj-vertical-split-div\")\n                    .height(defaultHeight + \"%\");\n                // .height(defaultHeight + \"px\");\n            }\n        } else {\n            // 设置百分比\n            var verticalsDivs = $(\".hj-vertical-split-div\");\n            var heightLength = verticalsDivs.length;\n            for (var i = 0; i \u003c heightLength; i++) {\n                var height = $(verticalsDivs[i]).height();\n                var parentHeight = $(verticalsDivs[i])\n                    .parent()\n                    .height();\n                var rate = (height / parentHeight) * 100 + \"%\";\n                $(verticalsDivs[i]).css({ height: rate });\n            }\n        }\n    }\n\n    setWidth('init')\n    setHeight(\"init\");\n\n    //定义一个对象\n    function PointerObject() {\n        this.el = null; //当前鼠标选择的对象\n        this.clickX = 0; //鼠标横向初始位置\n        this.clickY = 0; //鼠标竖向初始位置\n        this.transverseDragging = false; //判断鼠标可否横向拖动\n        this.verticalDragging = false; //判断鼠标可否竖向拖动\n    }\n    //横向分隔栏绑定事件\n    transverseLabels.bind(\"mousedown\", function(e) {\n        thisTransverseObject = new PointerObject();\n        thisTransverseObject.transverseDragging = true; //鼠标可横向拖动\n        thisTransverseObject.el = this;\n        thisTransverseObject.clickX = e.pageX; //记录鼠标横向初始位置\n    });\n\n    //竖向分隔栏绑定事件\n    verticalLabels.bind(\"mousedown\", function(e) {\n        //console.log(\"mousedown\");\n        thisVerticalObject = new PointerObject();\n        thisVerticalObject.verticalDragging = true; //鼠标可竖向拖动\n        thisVerticalObject.el = this;\n        thisVerticalObject.clickY = e.pageY; //记录鼠标竖向初始位置\n    });\n    //上下绑定事件\n    parentArrow.bind(\"mousedown\", function(e) {\n        //console.log(\"mousedown\");\n        thisArrowObject = new PointerObject();\n        // thisArrowObject.transverseDragging = true; //鼠标可横向拖动\n        thisArrowObject.verticalDragging = true; //鼠标可竖向拖动\n        thisArrowObject.el = this;\n        thisArrowObject.clickY = e.pageY; //记录鼠标竖向初始位置\n    });\n\n    doc.onmousemove = function(e) {\n        //鼠标横向拖动\n        if (thisTransverseObject != null) {\n            if (thisTransverseObject.transverseDragging) {\n                var changeDistance = 0;\n                if (thisTransverseObject.clickX \u003e= e.pageX) {\n                    //鼠标向左移动\n                    changeDistance =\n                        Number(thisTransverseObject.clickX) - Number(e.pageX);\n                    if (\n                        $(thisTransverseObject.el)\n                        .parent()\n                        .width() -\n                        changeDistance \u003c\n                        20\n                    ) {} else {\n                        $(thisTransverseObject.el)\n                            .parent()\n                            .width(\n                                $(thisTransverseObject.el)\n                                .parent()\n                                .width() - changeDistance\n                            );\n                        $(thisTransverseObject.el)\n                            .parent()\n                            .next()\n                            .width(\n                                $(thisTransverseObject.el)\n                                .parent()\n                                .next()\n                                .width() + changeDistance\n                            );\n                        thisTransverseObject.clickX = e.pageX;\n                        $(thisTransverseObject.el).offset({ left: e.pageX });\n                    }\n                } else {\n                    //鼠标向右移动\n                    changeDistance =\n                        Number(e.pageX) - Number(thisTransverseObject.clickX);\n                    if (\n                        $(thisTransverseObject.el)\n                        .parent()\n                        .next()\n                        .width() -\n                        changeDistance \u003c\n                        20\n                    ) {} else {\n                        $(thisTransverseObject.el)\n                            .parent()\n                            .width(\n                                $(thisTransverseObject.el)\n                                .parent()\n                                .width() + changeDistance\n                            );\n                        $(thisTransverseObject.el)\n                            .parent()\n                            .next()\n                            .width(\n                                $(thisTransverseObject.el)\n                                .parent()\n                                .next()\n                                .width() - changeDistance\n                            );\n                        thisTransverseObject.clickX = e.pageX;\n                        $(thisTransverseObject.el).offset({ left: e.pageX });\n                    }\n                }\n                $(thisTransverseObject.el).width(2);\n            }\n        }\n        //鼠标竖向拖动\n        if (thisVerticalObject != null) {\n            if (thisVerticalObject.verticalDragging) {\n                var changeDistance = 0;\n                if (thisVerticalObject.clickY \u003e= e.pageY) {\n                    //鼠标向上移动\n                    changeDistance = Number(thisVerticalObject.clickY) - Number(e.pageY);\n                    if (\n                        $(thisVerticalObject.el)\n                        .parent()\n                        .height() -\n                        changeDistance \u003c\n                        20\n                    ) {} else {\n                        $(thisVerticalObject.el)\n                            .parent()\n                            .height(\n                                $(thisVerticalObject.el)\n                                .parent()\n                                .height() - changeDistance\n                            );\n                        $(thisVerticalObject.el)\n                            .parent()\n                            .next()\n                            .height(\n                                $(thisVerticalObject.el)\n                                .parent()\n                                .next()\n                                .height() + changeDistance\n                            );\n                        thisVerticalObject.clickY = e.pageY;\n                        $(thisVerticalObject.el).offset({ top: e.pageY });\n                    }\n                } else {\n                    //鼠标向下移动\n                    changeDistance = Number(e.pageY) - Number(thisVerticalObject.clickY);\n                    if (\n                        $(thisVerticalObject.el)\n                        .parent()\n                        .next()\n                        .height() -\n                        changeDistance \u003c\n                        20\n                    ) {} else {\n                        $(thisVerticalObject.el)\n                            .parent()\n                            .height(\n                                $(thisVerticalObject.el)\n                                .parent()\n                                .height() + changeDistance\n                            );\n                        $(thisVerticalObject.el)\n                            .parent()\n                            .next()\n                            .height(\n                                $(thisVerticalObject.el)\n                                .parent()\n                                .next()\n                                .height() - changeDistance\n                            );\n                        thisVerticalObject.clickY = e.pageY;\n                        $(thisVerticalObject.el).offset({ top: e.pageY });\n                    }\n                }\n                $(thisVerticalObject.el).height(2);\n            }\n        }\n        // 改变父的 高度\n        if (thisArrowObject != null) {\n            //鼠标竖向拖动\n            if (thisArrowObject.verticalDragging) {\n                var changeDistance = 0;\n                if (thisArrowObject.clickY \u003e= e.pageY) {\n                    //鼠标向上移动\n                    changeDistance = Number(thisArrowObject.clickY) - Number(e.pageY);\n                    if (\n                        $(thisArrowObject.el)\n                        .parent()\n                        .height() -\n                        changeDistance \u003c\n                        50\n                    ) {} else {\n                        $(thisArrowObject.el)\n                            .parent()\n                            .height(\n                                $(thisArrowObject.el)\n                                .parent()\n                                .height() - changeDistance\n                            );\n                        thisArrowObject.clickY = e.pageY;\n                        $(thisArrowObject.el).offset({ bottom: e.pageY });\n                    }\n                } else {\n                    //鼠标向下移动\n                    changeDistance = Number(e.pageY) - Number(thisArrowObject.clickY);\n                    $(thisArrowObject.el)\n                        .parent()\n                        .height(\n                            $(thisArrowObject.el)\n                            .parent()\n                            .height() + changeDistance\n                        );\n                    thisArrowObject.clickY = e.pageY;\n                    $(thisArrowObject.el).offset({ bottom: e.pageY });\n                }\n                $(thisArrowObject.el).height(10);\n            }\n        }\n    };\n\n    $(doc).mouseup(function(e) {\n        setHeight(\"setHeight\");\n        setWidth(\"setWidth\");\n        // 鼠标弹起时设置不能拖动\n        if (thisTransverseObject != null) {\n            thisTransverseObject.transverseDragging = false;\n            thisTransverseObject = null;\n        }\n        if (thisVerticalObject != null) {\n            thisVerticalObject.verticalDragging = false;\n            thisVerticalObject = null;\n        }\n        if (thisArrowObject != null) {\n            thisArrowObject.verticalDragging = false;\n            thisArrowObject = null;\n        }\n\n        e.cancelBubble = true;\n    });\n});\n```\n\n# 4. 完整代码与效果\n\n效果图：\n\n![split.gif](https://upload-images.jianshu.io/upload_images/12890819-6a8ad52065c229c4.gif?imageMogr2/auto-orient/strip)\n\n项目地址：[https://github.com/biaochenxuying/split](https://github.com/biaochenxuying/split)\n效果体验地址：[ https://biaochenxuying.github.io/split/index.html](https://biaochenxuying.github.io/split/index.html)\n\n初始代码是从网上来的，不过网上的并不完整，父 div 的高也不能改变，并且孩子的宽高并不是百分比的，布局也并不合理，所以修改成这样子。\n\n# 5. 最后 \n\n![](https://upload-images.jianshu.io/upload_images/12890819-f8665293cc8d0dcf.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)\n\n如果您觉得本项目和文章不错或者对你有所帮助，请给个星吧，你的肯定就是我继续创作的最大动力。\n\n\u003c!-- 笔者经常在这里 BB：\n\n![全栈修炼](https://upload-images.jianshu.io/upload_images/12890819-9399d149e09f638e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240) --\u003e\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbiaochenxuying%2Fsplit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbiaochenxuying%2Fsplit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbiaochenxuying%2Fsplit/lists"}