| 
	| 
	
	| 
		
	| 
			
			 
			
				13.10.2023, 11:27
			
			
			
		 |  
	| 
		
			
			| Кандидат Javascript-наук       |  | 
					Регистрация: 20.09.2011 
						Сообщений: 147
					 
		
 |  |  
	| 
				Скролл дива при перетаскивании в нем элементов
			 Здравствуйте 
Есть див с id "dragContainer", в котором динамически создается список li. Список можно перетаскивать мышью. 
При перетаскивании элемента li вверх/вниз, нужно начать скроллить див, если li перемещен за пределы высоты дива. 
На данный момент скролл работает медленнее, чем перетаскивается элемент. 
Пожалуйста, помогите. 
JS выполняется не в браузере, а в гаджете Windows. Вот видео - https://youtube.com/shorts/P1FI2xN2Trk 
var Drag = {
	obj : null,
	init : function(obj){
		obj.onmousedown	= Drag.start;
		obj.style.pixelTop = 0;
		obj.onDragStart = new Function();
		obj.onDragEnd = new Function();
		obj.onDrag = new Function();
	},
	start : function(e){
		Drag.obj = this;
		e = Drag.fixE(e);
		Drag.obj.lastMouseY = e.clientY;
		document.onmousemove = Drag.drag;
		document.onmouseup = Drag.end;
		return false;
	},
	drag : function(e){
		e = Drag.fixE(e);
		var ey	= e.clientY;
		var y = parseInt(Drag.obj.style.pixelTop);
		var ny = parseInt(y + ey - Drag.obj.lastMouseY);
		Drag.obj.style.pixelTop = ny;
		Drag.obj.style.pixelLeft = 15;
		Drag.obj.lastMouseY	= ey;
		Drag.obj.onDrag(ny, Drag.obj);
		// скролл------------------------------------------------------------------------------------------
		dragContainerHeight = document.getElementById("dragContainer").offsetHeight;
		
		if (dragContainerHeight < Drag.obj.lastMouseY){
			document.getElementById("dragContainer").scrollTop = Drag.obj.lastMouseY - dragContainerHeight;
		}
		// ------------------------------------------------------------------------------------------------
		return false;
	},
	end : function(){
		document.onmousemove = null;
		document.onmouseup = null;
		Drag.obj.onDragEnd(Drag.obj);
		Drag.obj = null;
	},
	fixE : function(e){
		if (typeof e == 'undefined') e = window.event;
		return e;
	}
};
			
			
	
			
			
			
			
			
				  |  |  
	| 
		
	| 
			
			 
			
				13.10.2023, 22:10
			
			
			
		 |  
	| 
		
			|  | Профессор       |  | 
					Регистрация: 03.02.2020 
						Сообщений: 2,777
					 
		
 |  |  
	| 
	
 
	| Сообщение от sashgera |  
	| На данный момент скролл работает медленнее, чем перетаскивается элемент. |  
	
 Скролл работает с той скоростью, с которой может. 
Просто надо поменять логику скролла. 
Скролить окно надо не в том случае, когда мышь двигается, а когда нижняя граница перетаскиваемого элемента достигла нижней границы элемента в котором производится скролл, независимо от того, движется мышь или нет. Главное, что бы кнопка мыши была нажата.  
Оставить курсор мыши в пределах окна вы все равно не сможете. Это общесистемный ресурс и браузеру он не подчиняется. Если мышь двигается, то будет двигаться и курсор. |  |  
	| 
		
	| 
			
			 
			
				15.10.2023, 01:53
			
			
			
		 |  
	| 
		
			
			| Кандидат Javascript-наук       |  | 
					Регистрация: 20.09.2011 
						Сообщений: 147
					 
		
 |  |  
	| 
voraa
	
 
	| Сообщение от voraa   |  
	| Скролить окно надо не в том случае, когда мышь двигается, а когда нижняя граница перетаскиваемого элемента достигла нижней границы элемента в котором производится скролл |  
	
 , начал делать, но возникли проблемы, которые не могу решить. Не поможете?
 
- если полоса прокрутки равна 0, все хорошо - скролл начинается когда перетаскиваемый элемент достиг нижней границы дива 
- если полоса прокрутки больше нуля, проблема - при начале перетаскивания элемента, полоса прокрутки из начального положения уменьшается на растояние, которое равно: от текущего положения перетаскиваемого элемента до нижней границы дива 
- если перетаскивать снизу вверх - скролл начинается сразу, а не когда элемент достигает верхней части дива
 
// переменная dragContainer - див, в котором находятся элементы
// переменная myElem - перетаскиваемый элемент
if (myElem.offsetTop > (dragContainer.offsetHeight + dragContainer.offsetTop)){
  dragContainer.scrollTop = (myElem.offsetHeight + myElem.offsetTop) - (dragContainer.offsetHeight + dragContainer.offsetTop);
}
			
			
	
			
			
			
			
			
				  |  |  
	| 
		
	| 
			
			 
			
				15.10.2023, 09:26
			
			
			
		 |  
	| 
		
			|  | Профессор       |  | 
					Регистрация: 03.02.2020 
						Сообщений: 2,777
					 
		
 |  |  
	| Нет. Не помогу.Нужен весь код, что бы разбираться, что там происходит и иметь возможность тестировать.
 Но я смутно представляю, что такое "гаджет" в виндовс 7, какой там js, да и 7 у меня нет.
 |  |  
	| 
		
	| 
			
			 
			
				16.10.2023, 10:15
			
			
			
		 |  
	| 
		
			|  | Профессор       |  | 
					Регистрация: 03.02.2020 
						Сообщений: 2,777
					 
		
 |  |  
	| А почему не использовать обычный нативный drag n drp?Там проблем со скроллингом нет - все делается автоматически.
 Хоть и не полностью он поддерживается даже в старых IE
 |  |  
	| 
		
	| 
			
			 
			
				16.10.2023, 11:27
			
			
			
		 |  
	| 
		
			
			| Кандидат Javascript-наук       |  | 
					Регистрация: 20.09.2011 
						Сообщений: 147
					 
		
 |  |  
	| voraa, я уже пробовал что-то типа этого - https://stackoverflow.com/questions/...nding-on-mouse  но ничего не получилось, для работы в старых ie менял метод addEventListener на attachEvent |  |  
	| 
		
	| 
			
			 
			
				16.10.2023, 23:47
			
			
			
		 |  
	| 
		
			
			| Кандидат Javascript-наук       |  | 
					Регистрация: 20.09.2011 
						Сообщений: 147
					 
		
 |  |  
	| Rise, первое, что я пытался сделать, это подключить jquery. Но при подключении гаджет перестает работать |  |  
	| 
		
	| 
			
			 
			
				17.10.2023, 07:53
			
			
			
		 |  
	| 
		
			|  | Профессор       |  | 
					Регистрация: 03.02.2020 
						Сообщений: 2,777
					 
		
 |  |  
	| 
	
 
	| Сообщение от sashgera |  
	| Но при подключении гаджет перестает работать |  
	
 У вас там $ используется для каких то других целей. 
Используйте jQuery.noConflict()
https://api.jquery.com/jquery.noconflict/ |  |  
	| 
		
	| 
			
			 
			
				18.10.2023, 13:22
			
			
			
		 |  
	| 
		
			
			| Кандидат Javascript-наук       |  | 
					Регистрация: 20.09.2011 
						Сообщений: 147
					 
		
 |  |  
	| Скролл при перетаскивании элементов сделал. Скажите, при скролле, расстояние между перетаскиваемым элементом и курсором увеличивается - это нормальное состояние? так и должно быть? Вот видео https://youtube.com/shorts/VbGXOzoyZ_0 
Во вложении файл js с функциями drag, событие скролла отметил комментом |  |  
	| 
		
	| 
			
			 
			
				18.10.2023, 14:43
			
			
			
		 |  
	| 
		
			|  | Профессор       |  | 
					Регистрация: 03.02.2020 
						Сообщений: 2,777
					 
		
 |  |  
	| Ну вообще то скролл должен идти и без движения мыши, когда элемент находится в самом низу или самом верху 
Вот посмотрите пример, подведите элемент просто к самому низу, и остановите мышь так,  что бы нижняя рамка элемента совпадала с низом окна. Мышь не движется, а скрол идет
 
<head>
<style>
body {
  /* Prevent the user selecting text in the example */
  user-select: none;
}
#draggable {
  text-align: center;
  background: white;
}
.dropzone {
  width: 200px;
  height: 20px;
  background: blueviolet;
  margin: 30px 10px;
  padding: 10px;
}
.dropzone.dragover {
  background-color: purple;
}
.dragging {
  opacity: 0.5;
}</style>
</head>
<body>
<div class="dropzone">
  <div id="draggable" draggable="true">This div is draggable</div>
</div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<div class="dropzone"></div>
<script>
let dragged;
/* events fired on the draggable target */
const source = document.getElementById("draggable");
source.addEventListener("drag", (event) => {
  console.log("dragging");
});
source.addEventListener("dragstart", (event) => {
  // store a ref. on the dragged elem
  dragged = event.target;
  // make it half transparent
  event.target.classList.add("dragging");
});
source.addEventListener("dragend", (event) => {
  // reset the transparency
  event.target.classList.remove("dragging");
});
/* events fired on the drop targets */
const targets = document.querySelectorAll(".dropzone");
targets.forEach(target => {
	target.addEventListener(
	  "dragover",
	  (event) => {
		// prevent default to allow drop
		event.preventDefault();
	  },
	  false,
	);
	target.addEventListener("dragenter", (event) => {
	  // highlight potential drop target when the draggable element enters it
	  if (event.target.classList.contains("dropzone")) {
		event.target.classList.add("dragover");
	  }
	});
	target.addEventListener("dragleave", (event) => {
	  // reset background of potential drop target when the draggable element leaves it
	  if (event.target.classList.contains("dropzone")) {
		event.target.classList.remove("dragover");
	  }
	});
	target.addEventListener("drop", (event) => {
	  // prevent default action (open as link for some elements)
	  event.preventDefault();
	  // move dragged element to the selected drop target
	  if (event.target.classList.contains("dropzone")) {
		event.target.classList.remove("dragover");
		event.target.appendChild(dragged);
	  }
	});
});
</script>
</body>
			
			
	
			
			
			
			
			
				  |  |  
 
 
 
 |  |