我最近一直在使用UI,我真的很想使用Flexbox CSS来控制布局。我需要一种方法来制作我可以排序和拖动的盒子。
我首先尝试了 jQueryUI的可排序,但它似乎并不适用于flexbox。 它确实排序,但我认为它在新位置的可放置时会出现一些计算误差吗?或者我做错了。 无论哪种方式,我都会提供我的代码和JSFiddle,这样你就可以看到自己的怪异。我正在寻找的行为是很好的干净的可放置占位符,并且对齐就像jQueryUI的例子一样。 测试图例上的点击和拖动。同时尝试将最左边的项目拖到最右边。
如何解决这个问题,以便它可以与Flexbox一起使用?
JSFiddle:https://jsfiddle.net/95pv6cn2/5/
将此与jQueryUI以及它应该如何操作(https://jqueryui.com/sortable/#placeholder)
进行比较HTML
<body>
<div class="header">
<div class="logo">Sample Login System</div>
<div class="logoutarea">
<div class="loggedInAs">Logged in as (joe).</div>
<div class="logout">Logout</div>
</div>
</div>
<div class="content">
<div class="actionarea" id="sortable">
<div class="statusset">
<fieldset>
<legend>Status:</legend>
<div class="startbtn" status="off">Start Taking Calls/Text</div>
<div class="callstatusarea">
<span class="callstatusheader">Call/Text Status:</span>
<span class="status" status="free">Free</span>
</div>
</fieldset>
</div>
<div class="textmessageset">
<fieldset>
<legend>Send Outbound Text Message:</legend>
<div class="inputline sendtextfrom">
<div class="label">Send Text From:</div>
<select class="fromselect">
<option value="+19998887777">+19998887777</option>
<option value="+16665554444">+16665554444</option>
</select>
</div>
<div class="inputline sendtextto">
<div class="label">Send Text To:</div>
<input class="phoneinput sendtexttoinput" type="text" placeholder="To Phone Number..."/>
</div>
<div class="inputline sendtextresponsebackto">
<div class="label">Response Number: </div>
<input class="phoneinput sendtextresponsebackinput" type="text" placeholder="Your Phone Number..." title="(If no response back number given or response back number known to be busy in the system, then the system will automatically determine who to send text to)"/>
</div>
<div class="inputline sendtextwithmessage">
<div class="label">With Message:</div>
<textarea class="sendtextwithmessage_textarea" placeholder="Enter text message here..."></textarea>
</div>
<div class="inputline sendtextwithpicture">
<div class="label">Media URL:</div>
<input class="sendtextpictureurlinput" type="text" placeholder="http://a.com/image.jpg"/>
</div>
<button class="sendtextbtn">Send Outbound Text</button>
</fieldset>
</div>
<div class="otherset">
<fieldset>
<legend>Some Other Random Set:</legend>
Here is some text
</fieldset>
</div>
<div class="callset">
<fieldset>
<legend>Start Outbound Call:</legend>
<div class="inputline sendcallfrom">
<div class="label">Caller ID From:</div>
<select class="fromcalleridselect">
<option value="+19998887777">+19998887777</option>
<option value="+16665554444">+16665554444</option>
</select>
</div>
<div class="inputline sendcallto">
<div class="label">Send Call To:</div>
<input class="phoneinput sendcalltoinput" type="text" placeholder="To Phone Number..."/>
</div>
<div class="inputline andMyPhone">
<div class="label">Initiate To My Phone:</div>
<input class="phoneinput initiatecalltomyphoneinput" type="text" placeholder="My Phone Number..."/>
</div>
<button class="inputline startoutboundcallbtn">Start Outbound Call</button>
</fieldset>
</div>
</div>
</div>
<div class="footer">
© 2017 Sample Company LLC
</div>
</body>
CSS
/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
/**
* 1. Set default font family to sans-serif.
* 2. Prevent iOS and IE text size adjust after device orientation change,
* without disabling user zoom.
*/
html {
font-family: sans-serif;
/* 1 */
-ms-text-size-adjust: 100%;
/* 2 */
-webkit-text-size-adjust: 100%;
/* 2 */
}
/**
* Remove default margin.
*/
body {
margin: 0;
}
/* HTML5 display definitions
========================================================================== */
/**
* Correct `block` display not defined for any HTML5 element in IE 8/9.
* Correct `block` display not defined for `details` or `summary` in IE 10/11
* and Firefox.
* Correct `block` display not defined for `main` in IE 11.
*/
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
main,
menu,
nav,
section,
summary {
display: block;
}
/**
* 1. Correct `inline-block` display not defined in IE 8/9.
* 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
*/
audio,
canvas,
progress,
video {
display: inline-block;
/* 1 */
vertical-align: baseline;
/* 2 */
}
/**
* Prevent modern browsers from displaying `audio` without controls.
* Remove excess height in iOS 5 devices.
*/
audio:not([controls]) {
display: none;
height: 0;
}
/**
* Address `[hidden]` styling not present in IE 8/9/10.
* Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.
*/
[hidden],
template {
display: none;
}
/* Links
========================================================================== */
/**
* Remove the gray background color from active links in IE 10.
*/
a {
background-color: transparent;
}
/**
* Improve readability of focused elements when they are also in an
* active/hover state.
*/
a:active,
a:hover {
outline: 0;
}
/* Text-level semantics
========================================================================== */
/**
* Address styling not present in IE 8/9/10/11, Safari, and Chrome.
*/
abbr[title] {
border-bottom: 1px dotted;
}
/**
* Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
*/
b,
strong {
font-weight: bold;
}
/**
* Address styling not present in Safari and Chrome.
*/
dfn {
font-style: italic;
}
/**
* Address variable `h1` font-size and margin within `section` and `article`
* contexts in Firefox 4+, Safari, and Chrome.
*/
h1 {
font-size: 2em;
margin: 0.67em 0;
}
/**
* Address styling not present in IE 8/9.
*/
mark {
background: #ff0;
color: #000;
}
/**
* Address inconsistent and variable font size in all browsers.
*/
small {
font-size: 80%;
}
/**
* Prevent `sub` and `sup` affecting `line-height` in all browsers.
*/
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sup {
top: -0.5em;
}
sub {
bottom: -0.25em;
}
/* Embedded content
========================================================================== */
/**
* Remove border when inside `a` element in IE 8/9/10.
*/
img {
border: 0;
}
/**
* Correct overflow not hidden in IE 9/10/11.
*/
svg:not(:root) {
overflow: hidden;
}
/* Grouping content
========================================================================== */
/**
* Address margin not present in IE 8/9 and Safari.
*/
figure {
margin: 1em 40px;
}
/**
* Address differences between Firefox and other browsers.
*/
hr {
box-sizing: content-box;
height: 0;
}
/**
* Contain overflow in all browsers.
*/
pre {
overflow: auto;
}
/**
* Address odd `em`-unit font size rendering in all browsers.
*/
code,
kbd,
pre,
samp {
font-family: monospace, monospace;
font-size: 1em;
}
/* Forms
========================================================================== */
/**
* Known limitation: by default, Chrome and Safari on OS X allow very limited
* styling of `select`, unless a `border` property is set.
*/
/**
* 1. Correct color not being inherited.
* Known issue: affects color of disabled elements.
* 2. Correct font properties not being inherited.
* 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
*/
button,
input,
optgroup,
select,
textarea {
color: inherit;
/* 1 */
font: inherit;
/* 2 */
margin: 0;
/* 3 */
}
/**
* Address `overflow` set to `hidden` in IE 8/9/10/11.
*/
button {
overflow: visible;
}
/**
* Address inconsistent `text-transform` inheritance for `button` and `select`.
* All other form control elements do not inherit `text-transform` values.
* Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
* Correct `select` style inheritance in Firefox.
*/
button,
select {
text-transform: none;
}
/**
* 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
* and `video` controls.
* 2. Correct inability to style clickable `input` types in iOS.
* 3. Improve usability and consistency of cursor style between image-type
* `input` and others.
*/
button,
html input[type="button"],
input[type="reset"],
input[type="submit"] {
-webkit-appearance: button;
/* 2 */
cursor: pointer;
/* 3 */
}
/**
* Re-set default cursor for disabled elements.
*/
button[disabled],
html input[disabled] {
cursor: default;
}
/**
* Remove inner padding and border in Firefox 4+.
*/
button::-moz-focus-inner,
input::-moz-focus-inner {
border: 0;
padding: 0;
}
/**
* Address Firefox 4+ setting `line-height` on `input` using `!important` in
* the UA stylesheet.
*/
input {
line-height: normal;
}
/**
* It's recommended that you don't attempt to style these elements.
* Firefox's implementation doesn't respect box-sizing, padding, or width.
*
* 1. Address box sizing set to `content-box` in IE 8/9/10.
* 2. Remove excess padding in IE 8/9/10.
*/
input[type="checkbox"],
input[type="radio"] {
box-sizing: border-box;
/* 1 */
padding: 0;
/* 2 */
}
/**
* Fix the cursor style for Chrome's increment/decrement buttons. For certain
* `font-size` values of the `input`, it causes the cursor style of the
* decrement button to change from `default` to `text`.
*/
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button {
height: auto;
}
/**
* 1. Address `appearance` set to `searchfield` in Safari and Chrome.
* 2. Address `box-sizing` set to `border-box` in Safari and Chrome.
*/
input[type="search"] {
-webkit-appearance: textfield;
/* 1 */
box-sizing: content-box;
/* 2 */
}
/**
* Remove inner padding and search cancel button in Safari and Chrome on OS X.
* Safari (but not Chrome) clips the cancel button when the search input has
* padding (and `textfield` appearance).
*/
input[type="search"]::-webkit-search-cancel-button,
input[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
/**
* Define consistent border, margin, and padding.
*/
fieldset {
border: 1px solid #c0c0c0;
margin: 0 2px;
padding: 0.35em 0.625em 0.75em;
}
/**
* 1. Correct `color` not being inherited in IE 8/9/10/11.
* 2. Remove padding so people aren't caught out if they zero out fieldsets.
*/
legend {
border: 0;
/* 1 */
padding: 0;
/* 2 */
}
/**
* Remove default vertical scrollbar in IE 8/9/10/11.
*/
textarea {
overflow: auto;
}
/**
* Don't inherit the `font-weight` (applied by a rule above).
* NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
*/
optgroup {
font-weight: bold;
}
/* Tables
========================================================================== */
/**
* Remove most spacing between table cells.
*/
table {
border-collapse: collapse;
border-spacing: 0;
}
td,
th {
padding: 0;
}
/* Main.Less */
.header {
height: 20px;
background: #1e5799;
/* Old browsers */
background: -moz-linear-gradient(top, #1e5799 0%, #2989d8 50%, #207cca 51%, #7db9e8 100%);
/* FF3.6-15 */
background: -webkit-linear-gradient(top, #1e5799 0%, #2989d8 50%, #207cca 51%, #7db9e8 100%);
/* Chrome10-25,Safari5.1-6 */
background: linear-gradient(to bottom, #1e5799 0%, #2989d8 50%, #207cca 51%, #7db9e8 100%);
/* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#1e5799', endColorstr='#7db9e8', GradientType=0);
/* IE6-9 */
text-align: left;
padding: 20px;
color: white;
font-weight: bold;
display: flex;
display: -webkit-flex;
-webkit-align-items: space-around;
align-items: space-around;
}
.footer {
height: 20px;
background: #b3dced;
/* Old browsers */
background: -moz-linear-gradient(top, #b3dced 0%, #29b8e5 50%, #bce0ee 100%);
/* FF3.6-15 */
background: -webkit-linear-gradient(top, #b3dced 0%, #29b8e5 50%, #bce0ee 100%);
/* Chrome10-25,Safari5.1-6 */
background: linear-gradient(to bottom, #b3dced 0%, #29b8e5 50%, #bce0ee 100%);
/* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#b3dced', endColorstr='#bce0ee', GradientType=0);
/* IE6-9 */
text-align: center;
padding: 5px;
}
.logoutarea {
width: 100%;
display: flex;
display: -webkit-flex;
-webkit-align-items: space-around;
align-items: space-around;
text-align: right;
flex-direction: row;
-webkit-justify-content: flex-end;
justify-content: flex-end;
}
.loggedInAs {
-webkit-align-self: center;
align-self: center;
}
.logout {
text-align: right;
cursor: pointer;
padding-left: 30px;
-webkit-align-self: center;
align-self: center;
}
.logout:hover {
color: blue;
}
.logo {
width: 100%;
align-self: center;
-webkit-align-self: center;
}
.error {
color: blue;
}
/* Sticky Footer */
body {
display: flex;
min-height: 100vh;
flex-direction: column;
}
.content {
flex: 1;
}
/* End Sticky Footer */
.startbtn {
display: inline-box;
width: 200px;
cursor: pointer;
text-align: center;
}
.startbtn[status="off"] {
background: #34d960;
background-image: -webkit-linear-gradient(top, #34d960, #139e54);
background-image: -moz-linear-gradient(top, #34d960, #139e54);
background-image: -ms-linear-gradient(top, #34d960, #139e54);
background-image: -o-linear-gradient(top, #34d960, #139e54);
background-image: linear-gradient(to bottom, #34d960, #139e54);
-webkit-border-radius: 28;
-moz-border-radius: 28;
border-radius: 28px;
text-shadow: 1px 1px 3px #666666;
font-family: Arial;
color: #ffffff;
font-size: 20px;
padding: 10px 20px 10px 20px;
text-decoration: none;
}
.startbtn[status="on"] {
background: #e62020;
background-image: -webkit-linear-gradient(top, #e62020, #bd1b1b);
background-image: -moz-linear-gradient(top, #e62020, #bd1b1b);
background-image: -ms-linear-gradient(top, #e62020, #bd1b1b);
background-image: -o-linear-gradient(top, #e62020, #bd1b1b);
background-image: linear-gradient(to bottom, #e62020, #bd1b1b);
-webkit-border-radius: 28;
-moz-border-radius: 28;
border-radius: 28px;
text-shadow: 1px 1px 3px #666666;
font-family: Arial;
color: #ffffff;
font-size: 20px;
padding: 10px 20px 10px 20px;
text-decoration: none;
}
.startbtn:hover[status="off"] {
background: #58a862;
background-image: -webkit-linear-gradient(top, #58a862, #2d472d);
background-image: -moz-linear-gradient(top, #58a862, #2d472d);
background-image: -ms-linear-gradient(top, #58a862, #2d472d);
background-image: -o-linear-gradient(top, #58a862, #2d472d);
background-image: linear-gradient(to bottom, #58a862, #2d472d);
text-decoration: none;
}
.startbtn:hover[status="on"] {
background: #de2a3c;
background-image: -webkit-linear-gradient(top, #de2a3c, #4d2323);
background-image: -moz-linear-gradient(top, #de2a3c, #4d2323);
background-image: -ms-linear-gradient(top, #de2a3c, #4d2323);
background-image: -o-linear-gradient(top, #de2a3c, #4d2323);
background-image: linear-gradient(to bottom, #de2a3c, #4d2323);
text-decoration: none;
}
.callstatusheader {
font-weight: bold;
color: black;
}
.callstatusarea {
font-size: 18px;
padding: 10px;
text-align: left;
}
.callstatusarea .status {
padding-left: 10px;
}
.callstatusarea .status[status="free"] {
color: green;
}
.callstatusarea .status[status="busy"] {
color: red;
}
.callstatusarea .unbusy[status="free"] {
display: none;
font-size: 12px;
cursor: pointer;
padding-left: 20px;
}
.callstatusarea .unbusy[status="busy"] {
display: inline;
font-size: 12px;
cursor: pointer;
padding-left: 20px;
}
.callstatusarea .unbusy:hover {
font-size: 12px;
cursor: pointer;
padding-left: 20px;
color: blue;
}
.actionarea {
display: flex;
flex-wrap: wrap;
}
.actionarea .label {
display: inline-block;
width: 125px;
}
.actionarea input {
padding: 5px;
margin: 5px;
}
.actionarea select {
margin-left: 5px;
}
.actionarea textarea {
padding: 5px;
margin: 5px;
}
.actionarea button {
margin-top: 10px;
}
.actionarea legend {
cursor: pointer;
}
.actionarea .inputline {
margin: 5px;
display: flex;
align-items: center;
}
.actionarea .textmessageset {
display: flex;
padding: 5px;
max-width: 500px;
}
.actionarea .callset {
display: flex;
padding: 5px;
max-width: 500px;
}
.actionarea .otherset {
display: flex;
padding: 5px;
max-width: 500px;
}
.actionarea .statusset {
display: flex;
padding: 5px;
max-width: 500px;
}
.ui-state-highlight {
width: 50px;
}
/*# sourceMappingURL=main.css.map */
的JavaScript
$(document).ready(function(){
//@JA - Logout Fuction
$( "#sortable" ).sortable({
placeholder: "ui-state-highlight"
});
$( "#sortable" ).disableSelection();
});
答案 0 :(得分:5)
使用一些可排序的事件处理程序来创建一个&#34; ghost&#34;元素代替您正在移动的元素。这有助于保持弹性计算。
示例:https://jsfiddle.net/CRHain88/vv636vj4/
$(document).ready(function() {
//@JA - Logout Fuction
// Create a reusable spacer element. I added a background
// style to give indication that there was once something
// there. If you're going to style it with more complex
// design, consider making it have it's own class.
var placeholderElement = jQuery('<div style="background-color: #eee;"></div>');
$("#sortable").sortable({
placeholder: "ui-state-highlight",
// Add it before the element you're dragging.
// This assumes that you can only ever drag one element at a time.
activate: function(event, ui) {
placeholderElement.insertBefore(ui.item[0]);
// Explicitly set the height and width to preserve
// flex calculations
placeholderElement.width(ui.item[0].offsetWidth);
placeholderElement.height(ui.item[0].offsetHeight);
},
// Remove it when you're done dragging.
deactivate: function() {
placeholderElement.remove();
}
});
$("#sortable").disableSelection();
});
答案 1 :(得分:1)
jQuery可排序DOES可以处理这样的水平列表,但是要激活该行为,它将查找项目为float: left|right;
,display: inline;
或display: table-cell;
。这是在jQuery UI 1.12.1中进行检查的地方
_isFloating: function( item ) {
return ( /left|right/ ).test( item.css( "float" ) ) ||
( /inline|table-cell/ ).test( item.css( "display" ) );
},
我对您的代码应用了float: left;
,我认为它现在的表现要好一些:
https://jsfiddle.net/1s24xpzu/
这不是一个漂亮的解决方案,因为我们基本上只是在欺骗jQuery,并且可能会产生意想不到的浮动结果。但是我认为它至少对我的用例有用。
答案 2 :(得分:0)
对于那些像我这样偶然发现的人:
我的用例是我想对在flexbox行内排序的项目列表进行排序。我尝试了上面的解决方案,但他们什么也没做。我还尝试将浮点数添加到第一个元素(因为它可以检测到),但这并没有太大帮助。
我所做的是更改isFloat
函数(请注意,应将其称为isHorizontalSort
),如下所示:
_isFloating: function( item ) {
return ( /left|right/ ).test( item.css( "float" )) ||
( /inline|table-cell/ ).test( item.css( "display" )) ||
(
( /flex/ ).test( item.parent().css( "display" )) && ( /row|row-reverse/ ).test( item.parent().css( "flex-direction" ) )
)
},
因此它检测子项是否在水平flexbox内(flex方向是行还是行反向)。我也将tolerance
选项设置为pointer
,这似乎能带来最佳效果。
这是一个codepen:https://codepen.io/edgolub/pen/RzGgWZ