Webkit and Jquery Draggable Jumping

Webkit and jQuery draggable jumping

This is a result of draggable's reliance on the jquery offset() function and offset()'s use of the native js function getBoundingClientRect(). Ultimately this is an issue with the jquery core not compensating for the inconsistencies associated with getBoundingClientRect(). Firefox's version of getBoundingClientRect() ignores the css3 transforms (rotation) whereas chrome/safari (webkit) don't.

here is an illustration of the issue.

A hacky workaround:

replace following in jquery.ui.draggable.js


//The element's absolute position on the page minus margins
this.offset = this.positionAbs = this.element.offset();

with


//The element's absolute position on the page minus margins
this.offset = this.positionAbs = { top: this.element[0].offsetTop,
left: this.element[0].offsetLeft };

and finally a monkeypatched version of your jsbin.

Restricting jQuery-ui Draggable to drag up only, within a given area

I found a few issues with the above method, mostly having to do with using position:fixed; and using both top and bottom for repositioning.

I know its not perfect, but this is what I came up with...

jsFiddle

// repel down animation 
var previousScroll = 0;
var scroll = function () {
var currentScroll = $(this).scrollTop();
var z = $(window).scrollTop();
var wh = $(window).height();
var onScreen = wh - 1100 + 'px';
if (currentScroll > previousScroll && $('#repel').css('top') > onScreen) {
//down scroll code
$("#repel").removeClass("climb");
$("#repel").addClass("repel").delay(400).css('top', '+=3px');
}
if (currentScroll > previousScroll && $('#repel').css('top') <= onScreen) {
//down scroll code
$("#repel").addClass("repel");
}
if (z < 10) {
$("#containment-wrapper").css({
height: "1800px"
});
}
if (z > 10) {
$("#containment-wrapper").css({
height: "2000px"
});
} else {
// no- upscroll animation/code
}
previousScroll = currentScroll;
// fade in word bubble
if (z > 1350) {
$('.go').fadeIn('slow');

} else {
$('.go').fadeOut('slow');
}
};

$(document).ready(scroll);
$(window).scroll(scroll);

//remove animation when finished
$("#repel").on('animationend webkitAnimationEnd oanimationend MSAnimationEnd', function () {
$('#repel').removeClass('repel');
});
//bounce back to top of page when clicked
$('.go').click(function () {
$('html, body').animate({
scrollTop: 0
}, 'slow');
$("#repel").removeClass("repel");
$("#repel").css('top', '-850px').addClass("climb").delay(2100).queue(function (next) {
$(this).removeClass("climb");
next();
});

});

// drag Up, but not down
$('#repel').draggable({
axis: "y",
containment: "#containment-wrapper",
scroll: true,
scrollSensitivity: 25,
scrollSpeed: 25,
addClasses: false
});
$('#repel').mousemove(function () {
var z = $(window).scrollTop();
var o = $('#repel').offset().top;
var h = $('#repel').height();
$("#containment-wrapper").css({
top: o + h -2000
});
if (z < 10) {
$("#containment-wrapper").css({
top: -850
});
} else {
$("#containment-wrapper").css({
top: o + h -2000
});
}
});

jQuery UI draggable makes elements ignore translate3d transform

At the moment, your absolutely positioned elements are positioned relative to the transformed element since it establishes a new local coordinate system (see https://www.w3.org/TR/css3-transforms/#transform-rendering)
and none of the other near by parents do.

So unlike what you think, the yellow bar on top of orange bar is not hidden by blue bar overlapping it. It's not visible on top of orange bar because all the yellow bars are actually at the top of the blue bar, since they are positioned relative to the transformed parent.

The moment you apply draggable(), the immediate parent <div> of these bars gets position:relative (establishing a new coordinate system) hence the bars positions relative to them, which is why orange box's top bar appears on top of it (till now it was on top of the transformed parent).


From what I understood you want the box on top to hide the bar of the box below it, which can be achieved by giving the bars a lower z-index and setting a high z-index via the zIndex property of draggable. This property sets an z-index only while the item is being dragged. Hence the lower z-index we applied to bars won't affect during dragging. As soon as we finish dragging and draggable loses this higher z-index, the lower z-index of the bar takes effect.

You can test this by overlapping the orange box with the blue box in demo.

$(document).ready(function() {

$('.draggable').draggable({

zIndex: 1

})

});
#container {

transform-style: preserve-3d;

transform: translateY(20px);

}

.draggable {

width: 90px;

height: 90px;

}

img {

width: 90px;

height: 90px;

transform: translate3d(0, 0, 50px)

}

.bar {

position: absolute;

top: -10px;

width: 90px;

height: 10px;

z-index: -1;

background-color: yellow;

transform: translate3d(0, 0, 25px)

}

#blue img {

background-color: blue;

}

#orange img {

background-color: orange;

}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.js"></script>

<div id="container">

<div id="blue" class="draggable">

<div class="bar"></div>

<img>

</div>

<div id="orange" class="draggable">

<div class="bar"></div>

<img>

</div>

</div>

fixed position + draggable in Webkit

Problem solved! :) it was due a bug of Chrome.

you can not use "-webkit-transform" together with position fixed in webkit Browser.

for further information, show here

How do I stop List Items from jumping when dragging in chrome?

Seems like an issue where Chrome is treating default css properties differently than Firefox. You can pass an option to Selectable to add a class to the placeholder - that allows you to easily style that placeholder:

$(function() {
$( "#sortable1, #sortable2" ).sortable({
connectWith: ".timeline_content",
placeholder: "timeline-placeholder"
}).disableSelection();
});

The following style (although a bit weird) worked for me:

.timeline-placeholder {
display: inline !important;
padding: 0 99px;
width: 2px;
}

I generally dislike the need to use !important / limit its use, but default behavior of the placeholder is to be set to display: block which needed to be overriden.

edit: I found one solution to your problem, but not the cause - would be interested to see if anyone knows what property or combination of properties is causing that.



Related Topics



Leave a reply



Submit