昨天经理下班前要求我实现拖拽布局,那最基本的就要用JS来实现一个元素的拖拽效果,并且可以通过<input>标签来定义各种属性。设计思路,首先要实现元素的拖拽。
一、定义一个HTML
因为需要绑定未来元素,所以把DIV放到了一个共有的DIV中。
<div class="vb-move-container">
<div class="vb-container vb-can-do" style="top:10px">
<div class="vb-demo" style="background: #f60;"></div>
<div class="vb-option">
X轴<input type="text" class="vb-x">
y轴<input type="text" class="vb-y">
宽<input type="text" class="vb-width">
高<input type="text" class="vb-height">
</div>
二、拖拽代码的实现
通过Jquery的on方法实现未来元素绑定,给所有vb-container增加“mousedown”(鼠标按下)事件。
$(function(){
$(".vb-move-container").on("mousedown",".vb-container",function(e){
})
然后我们需要让通过鼠标在点击的时候,移动的距离clientX和clientY得到应该给当前div位移的距离
$(function(){
$(".vb-move-container").on("mousedown",".vb-container",function(e){
var ele = $(this);
ele.css('position','absolute');
var disX = e.clientX-ele.position().left;
var disY = e.clientY-ele.position().top;
$(document).on("mousemove",function(e){
ele.css("left",e.clientX-disX);
ele.css("top",e.clientY-disY);
getXY(ele);
changeDivTB(ele);
$(document).on("mouseup",function(){
$(document).off();
})
到这里,DIV就可以开始移动了,并且如果你添加一个DIV
<button οnclick="add()">添加</button>
function add(){
let str = `
<div class="vb-container" style="top:50%;left:45%;">
<div class="vb-demo" style="background: #f60;"></div>
<div class="vb-option vb-option-top vb-option-right">
X轴<input type="text" class="vb-x">
y轴<input type="text" class="vb-y">
宽<input type="text" class="vb-width">
高<input type="text" class="vb-height">
</div>`;
$(".vb-move-container").append(str);
}
就可以实现新增的DIV来移动了。
三、增加<input>改变div属性(位置和大小)的功能
1、我们需要在DIV初始化出现的时候,就要获取到对应的值,首先定义一个方法,我这里用的getXY,因为宽高属性是后来才加进去的。方法名不太合适。
function getXY(ele){
var div = ele.children(".vb-demo");
var option = ele.children(".vb-option");
option.children(".vb-x").val(ele.position().left); //距离左侧距离
option.children(".vb-y").val(ele.position().top); //距离顶部距离
option.children(".vb-height").val(div.height()); //高度
option.children(".vb-width").val(div.width()); //
}
这里的ele是一个“vb-container”的JQuery对象。
2、我们需要给这些<input>绑定change方法,我们继续在初始化写mousedown的后面添加一些方法绑定,因为这些元素也都可能是未来元素:
$(".vb-move-container").on("change",".vb-x",function(){
changeDiv(this,"left");
$(".vb-move-container").on("change",".vb-y",function(){
changeDiv(this,"top");
$(".vb-move-container").on("change",".vb-height",function(){
changeDiv(this,"height","body");
$(".vb-move-container").on("change",".vb-width",function(){
changeDiv(this,"width","body");
$(".vb-container").each(function(){ //调用上面的方法,给一开始就在页面中的div赋值
getXY($(this));
});
他们全部调用了一个changeDiv的方法,这个方法是根据传入的参数,给div赋值。因为左右的距离是给container赋值的(所有都要跟着它一起走),而宽、高是要给真正显示的div(“vb-demo”)赋值的,所以我们需要再传入一个body,来确定到底是给谁赋值。而changeDiv的方法如下:
function changeDiv(ele,type,option){
let div;
if(option == "body"){
div = $(ele).parent().prev();
}else{
div = $(ele).parent().parent();
div.css(type,$(ele).val()+"px");
}
这样修改数据的工作就完成了。当然,我们还需要在移动的时候,输入框中单数据也要对应修改,就只需要在mousemove中也调用getXY方法即可。
四、vb-option(设置栏)不可以出界
当拖动数据栏的时候,会出现数据栏出界的情况,导致无法修改数据。解决办法是通过判断“数据栏”边界的位置,来调换数据栏的位置。
首先我们设置了四种css
.vb-option-top{
bottom:-70px;
.vb-option-bottom{
top:140px;
.vb-option-left{
left:-120px;
.vb-option-right{
left:120px;
}
然后给div中的vb-option后面再添加vb-option-top、vb-option-right(表示在右上角,也可以根据自己喜好添加)
<div class="vb-option vb-option-top vb-option-right">
X轴<input type="text" class="vb-x">
y轴<input type="text" class="vb-y">
宽<input type="text" class="vb-width">
高<input type="text" class="vb-height">
</div>
然后就是在鼠标移动(mousemove)方法里增加一下判断。因为代码较多,所以我又单独写了一个方法
$(document).on("mousemove",function(e){
ele.css("left",e.clientX-disX);
ele.css("top",e.clientY-disY);
getXY(ele); //随着移动获取数据
changeDivTB(ele); //判断option的位置
})
function changeDivTB(ele){
var opt = ele.children(".vb-option");
var top = ele.position().top + opt.position().top;
var left = ele.position().left+opt.position().left;
var bodyWidth = $(window).width();
var bodyHeight = $(window).height();
if(top<0){ //判断上边界
opt.removeClass("vb-option-top");
opt.removeClass("vb-option-bottom");
opt.addClass("vb-option-bottom");
if((top+opt.height())>bodyHeight){ //判断右边是否超出
opt.removeClass("vb-option-top");
opt.removeClass("vb-option-bottom");
opt.addClass("vb-option-top");
if(left<0){ //判断左边界
opt.removeClass("vb-option-left");
opt.removeClass("vb-option-right");
opt.addClass("vb-option-right");
if((left+opt.width())>bodyWidth){ //判断右边界
opt.removeClass("vb-option-left");
opt.removeClass("vb-option-right");
opt.addClass("vb-option-left");
}
这样,我们元素拖拽的功能就实现了。因为第一次写博客,思路可能比较混乱,写的不太好。最后贴上完整代码:
HTML:
<!DOCTYPE html>
<html lang="en">
<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>
<script src="node_modules/jquery/dist/jquery.min.js"></script>
<script src="js/main.js"></script>
<style>
.vb-container{
position: absolute;
cursor: move;
.vb-demo{
position: absolute;
border-radius: 50%;
width:200px;
height: 200px;
.vb-option{
position: absolute;
width: 200px;
.vb-option-top{
bottom:-70px;
.vb-option-bottom{
top:140px;
.vb-option-left{
left:-120px;
.vb-option-right{
left:120px;
</style>
</head>
<button οnclick="add">添加</button>
<div class="vb-move-container">
<div class="vb-container vb-can-do" style="top:10px">
<div class="vb-demo" style="background: #f60;"></div>
<div class="vb-option vb-option-top vb-option-right">
X轴<input type="text" class="vb-x">
y轴<input type="text" class="vb-y">
宽<input type="text" class="vb-width">
高<input type="text" class="vb-height">
</body>
</html>
javascript:
$(function(){
$(".vb-move-container").on("mousedown",".vb-container",function(e){
var ele = $(this);
ele.css('position','absolute');
var disX = e.clientX-ele.position().left;
var disY = e.clientY-ele.position().top;
$(document).on("mousemove",function(e){
ele.css("left",e.clientX-disX);
ele.css("top",e.clientY-disY);
getXY(ele);
changeDivTB(ele);
$(document).on("mouseup",function(){
$(document).off();
$(".vb-move-container").on("change",".vb-x",function(){
changeDiv(this,"left");
$(".vb-move-container").on("change",".vb-y",function(){
changeDiv(this,"top");
$(".vb-move-container").on("change",".vb-height",function(){
changeDiv(this,"height","body");
$(".vb-move-container").on("change",".vb-width",function(){
changeDiv(this,"width","body");
$(".vb-container").each(function(){
getXY($(this));
function getXY(ele){
var div = ele.children(".vb-demo");
var option = ele.children(".vb-option");
option.children(".vb-x").val(ele.position().left);
option.children(".vb-y").val(ele.position().top);
option.children(".vb-height").val(div.height());
option.children(".vb-width").val(div.width());
function changeDiv(ele,type,option){
let div;
if(option){
div = $(ele).parent().prev();
}else{
div = $(ele).parent().parent();
div.css(type,$(ele).val()+"px");
function changeDivTB(ele){
var opt = ele.children(".vb-option");
var top = ele.position().top + opt.position().top;
var left = ele.position().left+opt.position().left;
var bodyWidth = $(window).width();
var bodyHeight = $(window).height();
if(top<0){
opt.removeClass("vb-option-top");
opt.removeClass("vb-option-bottom");
opt.addClass("vb-option-bottom");
if((top+opt.height())>bodyHeight){
opt.removeClass("vb-option-top");
opt.removeClass("vb-option-bottom");
opt.addClass("vb-option-top");
if(left<0){
opt.removeClass("vb-option-left");
opt.removeClass("vb-option-right");
opt.addClass("vb-option-right");
if((left+opt.height())>bodyWidth){
opt.removeClass("vb-option-left");
opt.removeClass("vb-option-right");
opt.addClass("vb-option-left");
function add(){
let str = `
<div class="vb-container" style="top:50%;left:45%;">
<div class="vb-demo" style="background: #f60;"></div>
<div class="vb-option vb-option-top vb-option-right">
X轴<input type="text" class="vb-x">
y轴<input type="text" class="vb-y">
宽<input type="text" class="vb-width">
高<input type="text" class="vb-height">
</div>`;
$(".vb-move-container").append(str);
$(".vb-container").each(function(){
getXY($(this));
android可拖拽view android可拖拽的悬浮窗
项目中需要实现一个状态显示的悬浮框,要求可以设置两种模式:拖动模式和不可拖动模式。实现效果图如下:实现步骤:1.首先要设置该悬浮框的基本属性:/**
* 显示弹出框
* @param context
@SuppressWarnings("WrongConstant")
public static void showPopupWind