JQuery: 可拖动 div 的 z-index 排序
JQuery: z-index ordering with draggable divs
在下面的代码中我有:
- 点击相应按钮时弹出的div
- 如果你拖动它们,(最后一个)活动对象应该在顶部
目前,我的代码无法按预期工作,因为最后一个活动元素被置于最前面。我正在尝试创建一个可扩展的解决方案,稍后可以有大约五个或更多按钮,内容不同。
另外,有没有办法让 div 在显示它们的按钮附近弹出?如果我在点击之前拖动按钮,距离有点大。
我目前的尝试是这样的:
$(function() {
/* Combine on ready logic into one place */
$("#button-one").draggable({
stack: 'div',
containment: "body"
});
$("#content-one").draggable({
stack: 'div',
containment: "body"
});
/* Hide all trip elements except for first */
$('.trip', '#content-one').not(':first').hide();
});
$('#button-one').on('mouseup', function() {
if (!$(this).hasClass('ui-draggable-dragging')) {
$("#content-one").toggle();
}
});
$('#content-one').on('mouseup', function() {
/* Reuse same logic in #button mouseup handler */
if (!$(this).hasClass('ui-draggable-dragging')) {
/*
If content element if not dragging, treat mouse up as conclusion
of click event and rotate visibility of trip elements like this
*/
let trip = $('.trip:visible', '#content-one');
let next = trip.next().length === 0 ? $('.trip:first', '#content-one') : trip.next();
trip.hide();
next.show();
}
});
$(function() {
$("#button-two").draggable({
stack: 'div',
containment: "body"
});
});
$('#button-two').on('mouseup', function() {
if (!$(this).hasClass('ui-draggable-dragging')) {
// your click function
$("#content-two").toggle();
}
});
$(function() {
$("#content-two").draggable({
stack: 'div',
containment: "body"
});
});
body,
html {
position: absolute;
padding: 0;
margin: 0;
width: 100%;
overflow-x: hidden;
overflow-y: inherit;
cursor: default;
}
#content {
max-width: 100vw;
height: 150vh;
}
#one {
left: 5%;
top: 5%;
position: absolute;
}
#button-one {
width: 100px;
height: 100px;
background-color: cyan;
position: absolute;
}
#content-one {
display: none;
cursor: all-scroll;
top: 10%;
left: 10%;
position: absolute;
top: 20px;
left: 20px;
}
.trip {
width: 200px;
height: 200px;
background-color: blue;
color: white;
}
#two {
left: 15%;
top: 15%;
position: absolute;
}
#button-two {
width: 100px;
height: 100px;
background-color: darkgrey;
position: absolute;
}
#content-two {
display: none;
cursor: all-scroll;
position: absolute;
top: 20px;
left: 20px;
width: 200px;
height: 200px;
background-color: green;
color: white;
}
<div id="content">
<div id="one">
<div id="button-one">Button 1</div>
<div id="content-one">
<div class="trip">div 1</div>
<div class="trip">div 2</div>
<div class="trip">div 3</div>
</div>
</div>
<div id="two">
<div id="button-two">Button 2</div>
<div id="content-two">Hey</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
<script src="https://raw.githubusercontent.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js"></script>
感谢您的帮助! :)
基于 - 经过一些修改,我会这样做:
- 使用
data-*
属性存储目标内容选择器ID
- 使用
Event.clientX
/ Y - 获取点击坐标
- 使用
.css({left: X, top: Y})
放置您的内容
- 将所有元素放在同一个父元素中以解决问题
z-indexing
并帮助 stack: '.draggable',
完成工作
jQuery($ => {
const $drag = $('.draggable').draggable({
stack: '.draggable',
containment: 'body'
});
// Fix out-of-containment glitch
$($drag.draggable('option').containment).on('mouseleave', () => $drag.trigger('mouseup'));
let z = 10; // Contents zIndex (will increment on content toggle)
$('.button').on('click', function(ev) {
if ($(this).hasClass('ui-draggable-dragging')) return;
$($(this).data('content')).css({left: ev.clientX, top: ev.clientY, zIndex: ++z}).toggle();
});
$('.content').on('click', function() {
const $trip = $(this).find('.trip'), tripL = $trip.length;
this._count |= 0;
$trip.eq(++this._count % tripL).show().siblings($trip).hide();
});
});
html,
body {
height: 100%;
margin: 0;
}
body {
background-color: grey;
}
.button {
width: 30vh;
height: 30vh;
background-color: cyan;
}
.content {
width: 45vh;
height: 45vh;
display: none;
cursor: all-scroll;
position: absolute;
background-color: blue;
color: white;
}
.trip~.trip {
display: none;
}
[data-content="#content-two"] {background: aquamarine;}
#content-two {background: fuchsia;}
<div class="button draggable" data-content="#content-one">Toggle one</div>
<div class="content draggable" id="content-one">
<div class="trip">ONE 1</div>
<div class="trip">ONE 2</div>
<div class="trip">ONE 3</div>
</div>
<div class="button draggable" data-content="#content-two">Toggle two</div>
<div class="content draggable" id="content-two">
<div class="trip">TWO 1</div>
<div class="trip">TWO 2</div>
</div>
<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
<script src="https://raw.githubusercontent.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js"></script>
为了实现您所追求的订单行为,我建议对您的 HTML 结构进行一些更改。你想要的目标是 "flat" HTML 结构,这样可拖动元素(即那些当前嵌套在 #one
和 #two
中的元素)可以相对于彼此(即包含element/DIV)。
完成后,您可以使用 draggable()
上的 start
事件挂钩来设置 "currently on top" 的元素。一个简单的方法是引入一个 CSS class 来设置 z-index
属性.
要将可拖动对象放置在被单击的按钮附近,您可以使用 JQuerys position()
方法获取被单击按钮的 top/left 坐标。然后,您可以将它们直接传递给可拖动元素的 css()
方法,如下所示:
/* Position of this button */
const position = $(buttonElement).position();
/* Position target near the button with slight offset */
draggableElement.css({
left : position.left + 10,
top : position.top + 10
});
对您的代码进行以下修改应该可以解决问题:
/*
Helper function assigns the element as "top most" element
relative to other elements
*/
function setToTop(element) {
var zIndexMax = 0;
$('.content, .button').each(function(i, elem) {
var zIndex = Number.parseInt($(elem).css('z-index'));
zIndex = Number.isNaN(zIndex) ? 0 : zIndex;
zIndexMax = Math.max(zIndexMax, zIndex);
});
element.css({
zIndex: zIndexMax + 1
});
}
$(function() {
/* Prevent drag from continuing after mouse leaves document */
$(document).mouseleave(function() {
$(document).trigger("mouseup")
});
$(".content, .button").draggable({
helper: "original",
containment: "body",
start: function(event, ui) {
/*
ui.helper is the element that we're starting to drag
*/
setToTop(ui.helper);
}
});
$('.trip').not(':first').hide();
});
$('.button').on('mouseup', function() {
/* Cause clicked button to come to front */
setToTop($(this));
if (!$(this).hasClass('ui-draggable-dragging')) {
var toggleTarget = $(".content" + $(this).data("target"));
toggleTarget.toggle();
if (toggleTarget.is(':visible')) {
/* Cause newly toggled element to be visible on top */
setToTop(toggleTarget);
/* Position of this button */
const position = $(this).position();
/* Position target near the button with slight offset */
toggleTarget.css({
left: position.left + 10,
top: position.top + 10
});
}
}
});
$('.content').on('mouseup', function() {
if (!$(this).hasClass('ui-draggable-dragging')) {
let trip = $('.trip:visible', this);
let next = trip.next().length === 0 ? $('.trip:first', this) : trip.next();
trip.hide();
next.show();
}
});
body,
html {
position: absolute;
padding: 0;
margin: 0;
width: 100%;
overflow-x: hidden;
overflow-y: inherit;
cursor: default;
}
#content {
max-width: 100vw;
height: 150vh;
}
.content {
display: none;
cursor: all-scroll;
position: absolute;
top: 20px;
left: 20px;
width: 200px;
height: 200px;
background-color: green;
color: white;
}
.content.one {
top: 10%;
left: 10%;
}
.content.two {
background-color: green;
color: white;
}
.trip {
width: 200px;
height: 200px;
background-color: blue;
color: white;
}
.button {
width: 100px;
height: 100px;
position: absolute;
}
#two {
left: 15%;
top: 15%;
background-color: darkgrey;
}
#one {
left: 5%;
top: 5%;
background-color: cyan;
}
<div id="content">
<div id="one" class="button" data-target=".one">Button 1</div>
<div id="two" class="button" data-target=".two">Button 2</div>
<div class="content two">Hey</div>
<div class="content one">
<div class="trip">div 1</div>
<div class="trip">div 2</div>
<div class="trip">div 3</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
<script src="https://raw.githubusercontent.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js"></script>
更新
要防止鼠标在拖动过程中离开文档后继续出现故障拖动行为,您可以这样做:
/*
Helper function assigns the element as "top most" element
relative to other elements
*/
function setToTop(element) {
var zIndexMax = 0;
$('.content, .button').each(function(i, elem) {
var zIndex = Number.parseInt($(elem).css('z-index'));
zIndex = Number.isNaN(zIndex) ? 0 : zIndex;
zIndexMax = Math.max(zIndexMax, zIndex);
});
element.css({
zIndex: zIndexMax + 1
});
}
在下面的代码中我有:
- 点击相应按钮时弹出的div
- 如果你拖动它们,(最后一个)活动对象应该在顶部
目前,我的代码无法按预期工作,因为最后一个活动元素被置于最前面。我正在尝试创建一个可扩展的解决方案,稍后可以有大约五个或更多按钮,内容不同。
另外,有没有办法让 div 在显示它们的按钮附近弹出?如果我在点击之前拖动按钮,距离有点大。
我目前的尝试是这样的:
$(function() {
/* Combine on ready logic into one place */
$("#button-one").draggable({
stack: 'div',
containment: "body"
});
$("#content-one").draggable({
stack: 'div',
containment: "body"
});
/* Hide all trip elements except for first */
$('.trip', '#content-one').not(':first').hide();
});
$('#button-one').on('mouseup', function() {
if (!$(this).hasClass('ui-draggable-dragging')) {
$("#content-one").toggle();
}
});
$('#content-one').on('mouseup', function() {
/* Reuse same logic in #button mouseup handler */
if (!$(this).hasClass('ui-draggable-dragging')) {
/*
If content element if not dragging, treat mouse up as conclusion
of click event and rotate visibility of trip elements like this
*/
let trip = $('.trip:visible', '#content-one');
let next = trip.next().length === 0 ? $('.trip:first', '#content-one') : trip.next();
trip.hide();
next.show();
}
});
$(function() {
$("#button-two").draggable({
stack: 'div',
containment: "body"
});
});
$('#button-two').on('mouseup', function() {
if (!$(this).hasClass('ui-draggable-dragging')) {
// your click function
$("#content-two").toggle();
}
});
$(function() {
$("#content-two").draggable({
stack: 'div',
containment: "body"
});
});
body,
html {
position: absolute;
padding: 0;
margin: 0;
width: 100%;
overflow-x: hidden;
overflow-y: inherit;
cursor: default;
}
#content {
max-width: 100vw;
height: 150vh;
}
#one {
left: 5%;
top: 5%;
position: absolute;
}
#button-one {
width: 100px;
height: 100px;
background-color: cyan;
position: absolute;
}
#content-one {
display: none;
cursor: all-scroll;
top: 10%;
left: 10%;
position: absolute;
top: 20px;
left: 20px;
}
.trip {
width: 200px;
height: 200px;
background-color: blue;
color: white;
}
#two {
left: 15%;
top: 15%;
position: absolute;
}
#button-two {
width: 100px;
height: 100px;
background-color: darkgrey;
position: absolute;
}
#content-two {
display: none;
cursor: all-scroll;
position: absolute;
top: 20px;
left: 20px;
width: 200px;
height: 200px;
background-color: green;
color: white;
}
<div id="content">
<div id="one">
<div id="button-one">Button 1</div>
<div id="content-one">
<div class="trip">div 1</div>
<div class="trip">div 2</div>
<div class="trip">div 3</div>
</div>
</div>
<div id="two">
<div id="button-two">Button 2</div>
<div id="content-two">Hey</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
<script src="https://raw.githubusercontent.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js"></script>
感谢您的帮助! :)
基于
- 使用
data-*
属性存储目标内容选择器ID - 使用
Event.clientX
/ Y - 获取点击坐标 - 使用
.css({left: X, top: Y})
放置您的内容 - 将所有元素放在同一个父元素中以解决问题
z-indexing
并帮助stack: '.draggable',
完成工作
jQuery($ => {
const $drag = $('.draggable').draggable({
stack: '.draggable',
containment: 'body'
});
// Fix out-of-containment glitch
$($drag.draggable('option').containment).on('mouseleave', () => $drag.trigger('mouseup'));
let z = 10; // Contents zIndex (will increment on content toggle)
$('.button').on('click', function(ev) {
if ($(this).hasClass('ui-draggable-dragging')) return;
$($(this).data('content')).css({left: ev.clientX, top: ev.clientY, zIndex: ++z}).toggle();
});
$('.content').on('click', function() {
const $trip = $(this).find('.trip'), tripL = $trip.length;
this._count |= 0;
$trip.eq(++this._count % tripL).show().siblings($trip).hide();
});
});
html,
body {
height: 100%;
margin: 0;
}
body {
background-color: grey;
}
.button {
width: 30vh;
height: 30vh;
background-color: cyan;
}
.content {
width: 45vh;
height: 45vh;
display: none;
cursor: all-scroll;
position: absolute;
background-color: blue;
color: white;
}
.trip~.trip {
display: none;
}
[data-content="#content-two"] {background: aquamarine;}
#content-two {background: fuchsia;}
<div class="button draggable" data-content="#content-one">Toggle one</div>
<div class="content draggable" id="content-one">
<div class="trip">ONE 1</div>
<div class="trip">ONE 2</div>
<div class="trip">ONE 3</div>
</div>
<div class="button draggable" data-content="#content-two">Toggle two</div>
<div class="content draggable" id="content-two">
<div class="trip">TWO 1</div>
<div class="trip">TWO 2</div>
</div>
<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
<script src="https://raw.githubusercontent.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js"></script>
为了实现您所追求的订单行为,我建议对您的 HTML 结构进行一些更改。你想要的目标是 "flat" HTML 结构,这样可拖动元素(即那些当前嵌套在 #one
和 #two
中的元素)可以相对于彼此(即包含element/DIV)。
完成后,您可以使用 draggable()
上的 start
事件挂钩来设置 "currently on top" 的元素。一个简单的方法是引入一个 CSS class 来设置 z-index
属性.
要将可拖动对象放置在被单击的按钮附近,您可以使用 JQuerys position()
方法获取被单击按钮的 top/left 坐标。然后,您可以将它们直接传递给可拖动元素的 css()
方法,如下所示:
/* Position of this button */
const position = $(buttonElement).position();
/* Position target near the button with slight offset */
draggableElement.css({
left : position.left + 10,
top : position.top + 10
});
对您的代码进行以下修改应该可以解决问题:
/*
Helper function assigns the element as "top most" element
relative to other elements
*/
function setToTop(element) {
var zIndexMax = 0;
$('.content, .button').each(function(i, elem) {
var zIndex = Number.parseInt($(elem).css('z-index'));
zIndex = Number.isNaN(zIndex) ? 0 : zIndex;
zIndexMax = Math.max(zIndexMax, zIndex);
});
element.css({
zIndex: zIndexMax + 1
});
}
$(function() {
/* Prevent drag from continuing after mouse leaves document */
$(document).mouseleave(function() {
$(document).trigger("mouseup")
});
$(".content, .button").draggable({
helper: "original",
containment: "body",
start: function(event, ui) {
/*
ui.helper is the element that we're starting to drag
*/
setToTop(ui.helper);
}
});
$('.trip').not(':first').hide();
});
$('.button').on('mouseup', function() {
/* Cause clicked button to come to front */
setToTop($(this));
if (!$(this).hasClass('ui-draggable-dragging')) {
var toggleTarget = $(".content" + $(this).data("target"));
toggleTarget.toggle();
if (toggleTarget.is(':visible')) {
/* Cause newly toggled element to be visible on top */
setToTop(toggleTarget);
/* Position of this button */
const position = $(this).position();
/* Position target near the button with slight offset */
toggleTarget.css({
left: position.left + 10,
top: position.top + 10
});
}
}
});
$('.content').on('mouseup', function() {
if (!$(this).hasClass('ui-draggable-dragging')) {
let trip = $('.trip:visible', this);
let next = trip.next().length === 0 ? $('.trip:first', this) : trip.next();
trip.hide();
next.show();
}
});
body,
html {
position: absolute;
padding: 0;
margin: 0;
width: 100%;
overflow-x: hidden;
overflow-y: inherit;
cursor: default;
}
#content {
max-width: 100vw;
height: 150vh;
}
.content {
display: none;
cursor: all-scroll;
position: absolute;
top: 20px;
left: 20px;
width: 200px;
height: 200px;
background-color: green;
color: white;
}
.content.one {
top: 10%;
left: 10%;
}
.content.two {
background-color: green;
color: white;
}
.trip {
width: 200px;
height: 200px;
background-color: blue;
color: white;
}
.button {
width: 100px;
height: 100px;
position: absolute;
}
#two {
left: 15%;
top: 15%;
background-color: darkgrey;
}
#one {
left: 5%;
top: 5%;
background-color: cyan;
}
<div id="content">
<div id="one" class="button" data-target=".one">Button 1</div>
<div id="two" class="button" data-target=".two">Button 2</div>
<div class="content two">Hey</div>
<div class="content one">
<div class="trip">div 1</div>
<div class="trip">div 2</div>
<div class="trip">div 3</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.7.2.min.js"></script>
<script src="https://code.jquery.com/ui/1.8.21/jquery-ui.min.js"></script>
<script src="https://raw.githubusercontent.com/furf/jquery-ui-touch-punch/master/jquery.ui.touch-punch.min.js"></script>
更新
要防止鼠标在拖动过程中离开文档后继续出现故障拖动行为,您可以这样做:
/*
Helper function assigns the element as "top most" element
relative to other elements
*/
function setToTop(element) {
var zIndexMax = 0;
$('.content, .button').each(function(i, elem) {
var zIndex = Number.parseInt($(elem).css('z-index'));
zIndex = Number.isNaN(zIndex) ? 0 : zIndex;
zIndexMax = Math.max(zIndexMax, zIndex);
});
element.css({
zIndex: zIndexMax + 1
});
}