您好我正在尝试在JS中制作拖放功能,它在Firefox中运行良好,但它不适用于Chrome。我认为它与Event Deligation
有关,我附加了我的代码库的link。以下是重现问题的步骤:
以下是代码要点(代码有点大,您可以在Codepen上查看):
JS:
$(function(){
function init(){
var mouseX = 0, // Mouse Position
mouseY = 0,
elmX = 0, // Element Position
elmY = 0,
pillers = $('.pillers'), // Task Container
pillerWidth = $('.pillers:nth-child(1)').width(), // Taks Container width
currentElm; // Current Element
/* When Left Mouse Button is Pressed */
$('.dragable').on('mousedown', function(e){
var temp;
$(this).addClass('rel');
mouseX = e.clientX; // Current Mouse Position and Store it to global variables
mouseY = e.clientY;
temp = +($(this).css('left').slice(0, -2)); // Get Element Position and if it not a number then change it to 0
elmX = null || isNaN(temp) ? 0 : temp;
temp = +($(this).css('top').slice(0, -2));
elmY = null || isNaN(temp) ? 0 : temp;
$(this).css({'z-index':'9999'}); // Increase the Z-Index of the Element so that it wont be overlapped by other element.
currentElm = $(this); // set the current value so that it could be use by mouse move
/* Some Hack for not let heighlight the data(Copied from net) */
document.body.focus();
document.onselectstart = function () { return false; };
$(this).ondragstart = function() { return false; };
return false;
}).on('mouseup',function(e){ // This will be fired when Mouse Button release back
if(currentElm !== null){
currentElm.removeClass('rel').prependTo('.arrived .tasks').css({ // Resetting the Position Object
left: 0,
top: 0
});
currentElm.css({'z-index' : '1'}); // Set Z-Index back to normal value.
currentElm = null; // Finally Set the Current Element to null so that it won't get dragged any more
}
}).on("mousemove", function(e){ // Mouse Move Event .. This is the main part, It will reposition the element with mouse pointer
if(currentElm !== undefined && currentElm !== null){
currentElm.addClass('draged').css({ // This sets the position of div element
left : (elmX + e.clientX - mouseX)+'px',
top : (elmY + e.clientY - mouseY)+'px'
});
/* Set Appropriate Class to Piller to Which The Element is going to be added */
if( e.clientX >= $('.pillers:nth-child(1)').offset().left && e.clientX < ($('.pillers:nth-child(1)').offset().left+pillerWidth) && e.clientY < $('.pillers:nth-child(1)').outerHeight()){
$('.pillers:nth-child(1)').addClass('arrived').siblings('.pillers').removeClass('arrived');
}else if(e.clientX >= $('.pillers:nth-child(2)').offset().left && e.clientX < ($('.pillers:nth-child(2)').offset().left+pillerWidth) && e.clientY < $('.pillers:nth-child(2)').outerHeight()){
$('.pillers:nth-child(2)').addClass('arrived').siblings('.pillers').removeClass('arrived');
}else if(e.clientX >= $('.pillers:nth-child(3)').offset().left && e.clientX < ($('.pillers:nth-child(3)').offset().left+pillerWidth) && e.clientY < $('.pillers:nth-child(3)').outerHeight()){
$('.pillers:nth-child(3)').addClass('arrived').siblings('.pillers').removeClass('arrived');
}else if(e.clientX >= $('.pillers:nth-child(4)').offset().left && e.clientX < ($('.pillers:nth-child(4)').offset().left+pillerWidth) && e.clientY < $('.pillers:nth-child(4)').outerHeight()){
$('.pillers:nth-child(4)').addClass('arrived').siblings('.pillers').removeClass('arrived');
}
}
});
$('a.remove').on('click',function(){
console.log('hey')
$(this).parents('.dragable').remove();
});
$('.add_task_button').on('click',function () {
var place= $(this).closest('.create_task_box'),
titl=place.find('input#title').val(),
disc=place.find('textarea#discription').val(),
time = new Date(),
format = time.toLocaleDateString();
if(titl || disc){
var val = $('.temp').clone(true).removeClass('temp hide').insertBefore(place);
val.find('#TaskHeading').val(titl).end().find('#task-discription').text(disc).end().find('.time').text(format).css({
left: 0,
top: 0
});
}
$('input#title, textarea#discription').val('');
});
$(document).on("click", ".edit", function(){
e.stopPropagation();
if($(this).is('.done')){
$(this).removeClass('done');
$(this).closest('.task-unit').addClass('dragable').find('input, textarea').attr('readonly', 'readonly').addClass('readonly');
}else{
$(this).addClass('done');
var task = $(this).closest('.dragable');
task.removeClass('dragable').find('input, textarea').removeAttr('readonly').removeClass('readonly');
}
});
}
init();
});
我在这里没有提到HTML和CSS部分,因为它会占用大量空间..您可以看到完整的代码Here on Codepen。
如果需要其他任何内容,请告诉我。
答案 0 :(得分:0)
问题是,你有一个带有mousedown
事件的对象(父),在其中有另一个带有click
事件的对象(子)。似乎在Chrome中,第一个事件(mousedown)捕获按钮上的点击。
作为解决方法,您可以执行此操作:
mousedown
事件的函数。mousedown
事件时,mouseover
事件。mouseout
时,将该函数再次绑定到父级。举个例子:
$(".theparent").on("mousedown",function(){
doThings();
});
$(".thechildren").on("click",function(){
alert("Child");
});
$(".thechildren").on("mouseover",function(){
$(this).closest(".theparent").off("mousedown");
console.log("Off");
});
$(".thechildren").on("mouseout",function(){
$(this).closest(".theparent").on("mousedown",doThings);
console.log("on");
});
function doThings(){
alert("Parent");
}
.theparent{
width:200px;
height:100px;
background-color:#3a3a3a;
position:absolute;
}
.thechildren{
position:relative;
background-color:#FF0000;
width:50px;
height:50px;
cursor:pointer;
left:50px;
top:25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="theparent">
<div class="thechildren">Child</div>
</div>