本文主要是模拟 jquery ui 提供的 resizable,draggable 功能。
使用 jQuery UI 创建 resizable,draggable 仪表盘
由于 jquery-ui.css 和 jquery-ui.js 两个文件太大,提供的功能太多,如果仅仅是需要最简单的 resiable 和 draggable 功能,引入 jquery-ui 还设计到跟现有框架的集成问题,甚至会引起一些性能问题。
基于此,可以尝试着自己来实现这些功能:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.ui-icon {
display: inline-block;
vertical-align: middle;
margin-top: -.25em;
position: relative;
text-indent: -99999px;
overflow: hidden;
background-repeat: no-repeat;
}
.ui-resizable-handle {
position: absolute;
font-size: 0.1px;
display: none;
-ms-touch-action: none;
touch-action: none;
}
.ui-widget-content:hover > .ui-resizable-handle {
display: block;
}
.ui-resizable-s {
cursor: s-resize;
height: 7px;
width: 100%;
bottom: -5px;
left: 0;
}
.ui-resizable-e {
cursor: e-resize;
width: 7px;
right: -5px;
top: 0;
height: 100%;
}
.ui-resizable-se {
cursor: se-resize;
width: 12px;
height: 12px;
right: 0px;
bottom: 0px;
background-image: "resize.png";
}
.ui-icon {
width: 16px;
height: 16px;
}
.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
.ui-icon, .ui-widget-content .ui-icon {
background-image: url("images/ui-icons_444444_256x240.png");
}
</style>
</head>
<body style="background-color: rgb(253, 238, 238);">
<div id="container" style="width:1000px; height:600px; margin:100px; border-color: black;border-style: solid;">
</div>
<script src="./jquery-3.4.1.min.js""></script>
<script>
function Grid(elementId){
this.id = elementId;
this.el = $("#"+elementId);
this.dragging = null;
this.resizing = null;
this.top = this.el.offset().top;
this.widgets = [];
}
Grid.prototype.init = function(){
let dragging = this.dragging;
let resizing = this.resizing;
this.el.on("mousedown", ".ui-widget-content", function(e){
console.log("mousedown widget");
let el = $(this);
let position = el.position();
dragging = {
offsetX: e.clientX - position.left,
offsetY: e.clientY - position.top,
el: el,
};
})
this.el.on("mousedown", ".ui-resizable-handle", function(e){
e.stopPropagation();
console.log("mousedown handler");
let el = $(this);
let horizontal = el.hasClass("ui-resizable-e");
let vertical = el.hasClass("ui-resizable-s");
let both = el.hasClass("ui-resizable-se");
let widget = $(el.parent()[0]);
let position = widget.position();
widget.data("left", position.left);
widget.data("top", position.top);
resizing = {
left: position.left,
top:position.top,
horizontal: horizontal||both,
vertical: vertical||both,
el: widget
};
})
this.el.mousemove(function(e){
if(resizing){
console.log("resizing");
let widget = resizing;
let width = (e.clientX - widget.left)+"px";
let height = (e.clientY - widget.top)+"px";
if(widget.horizontal){
widget.el.css("width", width);
}
if(widget.vertical){
widget.el.css("height", height);
}
return;
}
if(dragging){
console.log("dragging")
let el = dragging.el;
el.css("position", "absolute");
el.css("left", `${e.clientX - dragging.offsetX}px`);
el.css("top", `${e.clientY - dragging.offsetY}px`);
}
})
this.el.mouseup(function(){
console.log("off mousemove");
resizing = null;
dragging = null;
})
}
Grid.prototype.addWidget = function(id, style){
let widgets = this.el.children(".ui-widget-content");
$(widgets).each(i=>{
let w = $(widgets[i]);
let top = w.position().top + Number.parseInt(w.css("height"));
if(this.top < top) {
this.top = top + 10;
}
})
this.el.append(`
<div id="${id}" class="ui-widget-content" style="${style};top:${this.top}px">
<div class="ui-resizable-handle ui-resizable-e" style="z-index: 90;"></div>
<div class="ui-resizable-handle ui-resizable-s" style="z-index: 90;"></div>
<div class="ui-resizable-handle ui-resizable-se ui-icon ui-icon-gripsmall-diagonal-se" style="z-index: 90;"></div>
</div>
`);
}
let grid = new Grid("container");
grid.init();
grid.addWidget("1", "position:absolute;width:300px;height:60px;background-color: gray;");
grid.addWidget("2", "position:absolute;width:300px;height:60px;background-color: gray;");
grid.addWidget("3", "position:absolute;width:300px;height:60px;background-color: gray;");
</script>
</body>
</html>
ui-icons_444444_256x240.png