Своя реализация Drag and Drop

194
25 июля 2018, 12:10

Задание: Реализовать собственный Drag and Drop

Условия:

  • Не использовать каких либо библиотек, кроме JQuery
  • Не использовать стандартную реализацию Drag and Drop в JQuery

Проблема:

Элемент при перетаскивании перекрывает собой событие контейнера hover, из за этого невозможно сделать проверку, находится ли курсор мыши над контейнером.

var divBoxes = $('#boxes'); 
var divBoxLeft = divBoxes.find('.box-left'); 
var divBoxRight = divBoxes.find('.box-right'); 
 
var divOperations = $('#operations'); 
var buttonCreateItem = divOperations.find('.button-create-item'); 
var buttonClearLeftBox = divOperations.find('.button-clear-left-box'); 
var buttonClearRightBox = divOperations.find('.button-clear-right-box'); 
 
$(buttonCreateItem).click(function() { 
  let newItem = $('<div class="item"></div>'); 
 
  let width = 50; 
  let height = 50; 
 
  var isPermittedDropped; 
 
  function itemDrag(e) { 
    newItem.addClass('dragged'); 
    newItem.css({ 
      position: 'absolute', 
      top: e.clientY - height / 2, 
      left: e.clientX - width / 2 
    }); 
 
    $(divBoxRight).hover( 
      function() { 
        isPermittedDropped = true; 
        $('hover-info').text("Hover"); 
 
      }, 
      function() { 
        isPermittedDropped = false; 
        $('hover-info').text("No hover"); 
      }); 
  } 
 
  function itemDrop(e) { 
    if (isPermittedDropped) 
      divBoxRight.append($(divBoxLeft).find('.item.dragged')); 
 
    $('html').off('mousemove', itemDrag); 
    $(divBoxRight).off('mouseenter mouseleave'); 
 
    newItem.removeClass('dragged'); 
    newItem.css({ 
      position: 'static', 
      top: '', 
      left: '' 
    }); 
  } 
 
  newItem.mousedown(function() { 
    $('html').on('mousemove', itemDrag); 
  }); 
  newItem.mouseup(itemDrop); 
 
  let red = Math.random() * 255; 
  let green = Math.random() * 255; 
  let blue = Math.random() * 255; 
  let alpha = 0.25 + Math.random() * (1 - 0.25); 
 
  newItem.css({ 
    backgroundColor: 'rgba(' + red + ', ' + green + ', ' + blue + ', ' + alpha + ')' 
  }); 
 
  divBoxLeft.append(newItem); 
}); 
$(buttonClearLeftBox).click(function() { 
  divBoxLeft.empty(); 
}); 
$(buttonClearRightBox).click(function() { 
  divBoxRight.empty(); 
});
.container { 
  max-width: 1300px; 
  margin: 25px auto; 
  text-align: center; 
} 
 
#boxes, 
#operations { 
  display: flex; 
  flex-wrap: wrap; 
  justify-content: center; 
  user-select: none; 
} 
 
#boxes [class^='box'] { 
  display: flex; 
  flex-wrap: wrap; 
  flex-grow: 1; 
  justify-content: center; 
  align-content: flex-start; 
  overflow-y: auto; 
  max-width: 200px; 
  height: 200px; 
  margin: 10px; 
  padding: 5px; 
  border: solid 3px #CCC; 
  background-color: #FFF; 
} 
 
#boxes [class^='box'] .item { 
  width: 50px; 
  height: 50px; 
  margin: 5px; 
  box-sizing: border-box; 
  border: solid 1px #CCC; 
} 
 
#operations [class^='button'] { 
  width: 250px; 
  height: 30px; 
  margin: 10px; 
  border: solid 1px #CCC; 
  background-color: aqua; 
} 
 
#operations [class^='button']:hover { 
  border-width: 0px; 
  background: linear-gradient(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.15)), #0FF; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div class="container"> 
  <div id="boxes"> 
    <div class="box-left"></div> 
    <div class="box-right"></div> 
  </div> 
  <div id="operations"> 
    <button class="button-create-item">Создать элемент</button> 
    <button class="button-clear-left-box">Очистить левый контейнер</button> 
    <button class="button-clear-right-box">Очистить правый контейнер</button> 
  </div> 
  <div class="hover-info">No hover</div> 
</div>

Answer 1

Ответ: Заменить проверку события hover на проверку координат мыши.

var divBoxes = $('#boxes'), 
  divBoxLeft = divBoxes.find('.box-left'), 
  divBoxRight = divBoxes.find('.box-right'); 
 
var divOperations = $('#operations'), 
  buttonCreateItem = divOperations.find('.button-create-item'), 
  buttonClearLeftBox = divOperations.find('.button-clear-left-box'), 
  buttonClearRightBox = divOperations.find('.button-clear-right-box'); 
 
var divBoxRightCoords = divBoxRight.offset(), 
  divBoxRightBorderTop = divBoxRightCoords.top, 
  divBoxRightBorderBottom = divBoxRightCoords.top + divBoxRight.height(), 
  divBoxRightBorderLeft = divBoxRightCoords.left, 
  divBoxRightBorderRight = divBoxRightCoords.left + divBoxRight.width(); 
 
$(buttonCreateItem).click(function() { 
  let newItem = $('<div class="item"></div>'); 
 
  let width = 50, 
    height = 50; 
 
  function itemDrag(e) { 
    newItem.addClass('dragged'); 
    newItem.css({ 
      position: 'absolute', 
      top: e.clientY - height / 2, 
      left: e.clientX - width / 2 
    }); 
  } 
 
  function itemDrop(e) { 
    if (e.clientX >= divBoxRightBorderLeft && e.clientX <= divBoxRightBorderRight) 
      if (e.clientY >= divBoxRightBorderTop && e.clientY <= divBoxRightBorderBottom) 
        divBoxRight.append($(divBoxLeft).find('.item.dragged')); 
 
    $('html').off('mousemove', itemDrag); 
 
    newItem.removeClass('dragged'); 
    newItem.css({ 
      position: 'static', 
      top: '', 
      left: '' 
    }); 
  } 
 
  newItem.mousedown(function() { 
    $('html').on('mousemove', itemDrag); 
  }); 
  newItem.mouseup(itemDrop); 
 
  let red = Math.random() * 255, 
    green = Math.random() * 255, 
    blue = Math.random() * 255, 
    alpha = 0.25 + Math.random() * (1 - 0.25); 
 
  newItem.css({ 
    backgroundColor: 'rgba(' + red + ', ' + green + ', ' + blue + ', ' + alpha + ')' 
  }); 
 
  divBoxLeft.append(newItem); 
}); 
$(buttonClearLeftBox).click(function() { 
  divBoxLeft.empty(); 
}); 
$(buttonClearRightBox).click(function() { 
  divBoxRight.empty(); 
});
.container { 
  max-width: 1300px; 
  margin: 25px auto; 
} 
 
#boxes, 
#operations { 
  display: flex; 
  flex-wrap: wrap; 
  justify-content: center; 
  user-select: none; 
} 
 
#boxes [class^='box'] { 
  display: flex; 
  flex-wrap: wrap; 
  flex-grow: 1; 
  justify-content: center; 
  align-content: flex-start; 
  overflow-y: auto; 
  max-width: 420px; 
  height: 420px; 
  margin: 10px; 
  padding: 5px; 
  border: solid 3px #CCC; 
  background-color: #FFF; 
} 
 
#boxes [class^='box'] .item { 
  width: 50px; 
  height: 50px; 
  margin: 5px; 
  box-sizing: border-box; 
  border: solid 1px #CCC; 
} 
 
#operations [class^='button'] { 
  width: 250px; 
  height: 30px; 
  margin: 10px; 
  outline: none; 
  border: solid 1px #CCC; 
  border-radius: 10px; 
  background-color: aqua; 
} 
 
#operations [class^='button']:hover { 
  border-width: 0px; 
  background: linear-gradient(rgba(0, 0, 0, 0.15), rgba(0, 0, 0, 0.15)), #0FF; 
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
<div class="container"> 
  <div id="boxes"> 
    <div class="box-left"></div> 
    <div class="box-right"></div> 
  </div> 
  <div id="operations"> 
    <button class="button-create-item">Создать элемент</button> 
    <button class="button-clear-left-box">Очистить левый контейнер</button> 
    <button class="button-clear-right-box">Очистить правый контейнер</button> 
  </div> 
</div>

READ ALSO
Как сделать чтобы в переменой (а) менялась буква?

Как сделать чтобы в переменой (а) менялась буква?

Как сделать чтобы в переменой (а) менялась буква?

156
Как токенизировать строку

Как токенизировать строку

Решил по надобности понять устройство языков программирования, как всегда начал с лексеров но у меня появилась проблема, я не могу понять...

167
Таймер на Node JS

Таймер на Node JS

Помогите, пожалуйстаПишу бота, есть команда, после ввода которой через 30 секунд должно выполняться действие, помогите написать таймер на Node JS

175
noConflict() не срабатывает

noConflict() не срабатывает

Очень интересная история получается у меня два шаблона страницы к нему подключен следующий код,

155