问题
OK it's getting awkward, already searched and tried for about 5 hours and I'm just running in circles...
The scenario is easy: It's the header image of a user profile, it can be dragged into an position and then the top position of the image get's saved into a DB.
Thanks to Beetroot-Beetroot's "containment: 'parent'" I am down to this piece of code, which actually reacts as I want it to! Except for one big problem. The Picture just jumps either to the top or the bottom. There is no smooth scrolling? If I change the 'parent' to -'parent' it scrolls nicely but... the containment of course isn't there anymore. Help? :D
The JS
$(function(){
$(".headerimage").css('cursor','s-resize');
$(".headerimage").draggable({ containment: 'parent', scroll: false, axis: "y", stop: function(event, ui) {
var data = "profileheaderposition="+ui.position.top;
var destination = "/modules/users/profile/save.php";
get_data(data, destination, function(test){
notice(test);
});
}
});
});
So and last but not least the Header is included like that:
<div class="<?php if ($user->id == $profileuser->id) echo "changer"; ?> ui-corner-all" id="profileheader" style="overflow: hidden; width: 650px; height: 260px; position:relative;">
<?php if($profile->profileheader){
$size = getimagesize($profile->profileheader);
?>
<img id="" class="draggable headerimage" style="position: absolute; top: <?php echo $profile->profileheaderposition; ?>px;" src="<?php echo $profile->profileheader; ?>" alt="profileheader" width="650" />
As I said hours of googling weren't giving any results - and if i wouldn't save the results it would work just fine but oh well...
-- Edit --
Right now I am about to cry out -.- I've set up a bounty on this one and the tools for helping me ain jsfiddle but an guest account on my webpage which is: http://www.animize.de
There you can log on to the page with the Username: Gast and the pw gast - Click on the top right on the name (gast) and you'll see the profile - there you can move the headerpicture - and of course it should behave in another way than it does - help :(
回答1:
Try this fiddle.
I added an if-statement to the drag
event which checks the current positioning of the image and sets the current top position into ui.position.top
if the condition returns true so the draggable event does not increase or decrease the top position while hitting the boundaries of the div. This way you can keep the position properties of your div's.
回答2:
Ivan,
It's hard to see why the code should be in a named function wrapper. Unless dragability needs to be turned on/off, then .draggable()
just needs to be invoked once in a $(function(){...});
structure.
It's also hard to see why you would need to write static data from php into javascript. There should be nothing about the draggable image that javascript/jQuery cannot discover for itself by enquiring the DOM, and even then it's not clear why this might be necessary.
I would expect to see something like this :
$(function() {
$(".headerimage").draggable({
containment: 'parent',
scroll: false,
axis: "y",
stop: function(event, ui) {
$.ajax(
url: "/modules/users/profile/save.php",
data: "profileheaderposition=" + ui.position.top,
success: function() {
//do something here to indicate that the new position has been successfully saved
}
);
}
});
});
回答3:
See this fiddle for my solution to this. I also handled left and right dragging, which is not necessary for your case at this time but could be useful in future if you plan to use an image greater than its parent. In your case your image is same width as its parent so I added a threshold
param to let vertical dragging be used without being canceled by the right and left boundaries being hit.
I also added some css for grab
and grabbing
cursors, so to get a cursor effect similar to when you drag a pdf around, unfortunately the support for this cursors is somewhat broken in some browsers(IE and chrome in my tests) but firefox is showing them right.
Pasting my code here to prevent from a future fiddle broken link.
HTML:
<br><br><br><br><br><br><br>
<div class="ui-widget-content" style="padding:10px;">
<div class="picturecontainer" style="overflow: hidden; position: relative; width: 650px; height: 150px; border: 1px solid #888;">
<img style="position: absolute;" class="headerimage ui-corner-all" src="http://www.animize.de/modules/users/profile/images/profileheader/header_3722386791348526090.jpg" />
</div>
</div>
CSS:
.headerimage {
cursor:hand;
cursor:grab;
cursor:-moz-grab;
cursor:-webkit-grab;
}
.grabbing {
cursor:grabbing !important;
cursor:-moz-grabbing !important;
cursor:-webkit-grabbing !important;
}
JAVASCRIPT:
var container = $(".picturecontainer");
var childimage = $(".headerimage");
childimage.draggable({ scroll: false, start:function(event,ui) {
childimage.addClass('grabbing');
}, stop: function(event, ui) {
childimage.removeClass('grabbing');
},drag: function(event,ui) {
//left and right threshold
//to ease draggin images that have same width as container
threshold = 20;//pixels
ltop = childimage.offset().top -1 > container.offset().top;
lbottom = childimage.offset().top + childimage[0].offsetHeight
<= container.offset().top + container[0].offsetHeight;
lleft = childimage.offset().left > container.offset().left + threshold;
lright = childimage.offset().left + childimage[0].offsetWidth <
container.offset().left + container[0].offsetWidth - threshold;
if (ltop || lbottom || lleft || lright) {
$(this).data("draggable").cancel();
if (ltop) {
$(this).offset({ top: $(this).parent().offset().top+1});
} else if (lbottom) {
newtop = container.offset().top + container[0].offsetHeight
- childimage[0].offsetHeight;
$(this).offset({ top: newtop+1});
} else if (lleft) {
newleft = container.offset().left;
$(this).offset({ left: newleft});
} else if (lright) {
newleft = container.offset().left + container[0].offsetWidth;
- childimage[0].offsetWidth;
$(this).offset({ left: newleft});
}
}
}
}).parent().bind('mouseout',function() {
childimage.trigger('mouseup');
});
回答4:
I am using this code in my project and it is working fine. I used the solution from QQping and i just did a small change to make the image to move left and right as well. I hope it helps..
http://jsfiddle.net/UAgDA/266/
//Moving left and right
if(ui.position.left >= 0)
{
ui.position.left = 0;
}
else if(ui.position.left <= x1 - x2)
{
ui.position.left = x1 - x2;
}
Cheers
回答5:
I dont think you need to contain it inside parent
or else you wont be able to drag it upwards outside the parent
boundary
Alternatively , jQuery ui provides containment inside two coordinates.
Try this code,
HTML
<div class="picturecontainer" style="overflow: hidden; position: relative; width: 650px; height: 150px; border: 1px solid #888;">
<img class="headerimage" src="http://www.animize.de/modules/users/profile/images/profileheader/header_3722386791348526090.jpg" />
</div>
JS
$(function() {
var img = $(".headerimage");
img.css('cursor', 's-resize');
var x1 = img.parent().width() - img.width();
var y1 = img.parent().height() - img.height();
$(".headerimage").draggable({
containment: [x1,y1,0,0],
scroll: false,
axis: "y",
stop: function(event, ui) {
}
});
});
Demo
来源:https://stackoverflow.com/questions/12575573/jquery-draggable-image-with-saved-position