• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Kod JS mający na celu stworzyć i przesuwać <div> nie działa

Object Storage Arubacloud
+1 głos
312 wizyt
pytanie zadane 25 października 2021 w JavaScript przez Jcob2222 Początkujący (480 p.)

Witajcie! Mam problem z kodem JS służącym do przesuwania <div>. Mianowicie chodzi o to, że najzwyczajniej w świecie kod nie działa. Mam pewną teorię dlaczego ale nie wiem jak to naprawić. Chodzi o to, że prawdopodobnie kod JS wykonuje się przed utworzeniem <div> przez co później kod JS nie jest w stanie wykryć tego div'a i nie jest w stanie przypisać mu marginesów. Jeśli się mylę to poprawcie mnie. CSS nie wstawiam, jedyne co dodam to, że ustawiłem position na absolute. Oto kod JS:

 

function addDiv(){
	let div = document.createElement('div');
	div.classList.add('blok_test');
	div.innerHTML = "<div id='mydivheader'><img class='obrazek' id='blok_polecen' src='blok_polecen.png'></div>";
	document.getElementById("sandbox_h").appendChild(div);
		
}

const el = document.querySelector(".blok_test");

el.addEventListener("mousedown", mousedown);



function mousedown(e){
	window.addEventListener("mousemove", mousemove);
	window.addEventListener("mouseup", mouseup);
	
	let prevX = e.clientX;
	let prevY = e.clientY;
	
	function mousemove(e){
		let newX = prevX - e.clientX;
		let newY = prevY - e.clientY;
		
		const rect = el.getBoundingClientRect();
		
		el.style.left = rect.left - newX + "px";
		el.style.top = rect.top - newY + "px";
		
		prevX = e.clientX;
		prevY = e.clientY;
	}
	
	function mouseup(){
		window.removeEventListener('mousemove', mousemove);
		window.removeEventListener('mouseup', mouseup);
	}
}

Kod HTML: 

<!DOCTYPE html>

<html lang="pl-PL">
	<head>
		<meta charset="utf-8">
		<title>JSBlock</title>
		<link rel="stylesheet" href="style.css">
	</head>
	<body>
		
		<div class="head_container">
			<div class="top_options_bar">
				<div class="top_options_bar_top">
					
					<div class="dropdown">
						<button class="dropbtn">Plik</button>
						<div class="dropdown-content">
							<a href="#">test1</a>
							<a href="#">test2</a>
							<a href="#">test3</a>
						</div>
					</div>
				
					<div class="dropdown">
						<button class="dropbtn">Edycja</button>
						<div class="dropdown-content">
							<a href="#">test1</a>
							<a href="#">test2</a>
							<a href="#">test3</a>
						</div>
					</div>
				
					<div class="dropdown">
						<button class="dropbtn">Schematy</button>
						<div class="dropdown-content">
							<a href="#">test1</a>
							<a href="#">test2</a>
							<a href="#">test3</a>
						</div>
					</div>
					
					<div class="dropdown">
						<button class="dropbtn">Ustawienia</button>
						<div class="dropdown-content">
							<a href="#">test1</a>
							<a href="#">test2</a>
							<a href="#">test3</a>
						</div>
					</div>
					
					<div class="dropdown">
						<button class="dropbtn">Pomoc</button>
						<div class="dropdown-content">
							<a href="#">test1</a>
							<a href="#">test2</a>
							<a href="#">test3</a>
						</div>
					</div>
					
				</div>
			</div>
			<div class="left_options_bar">
			
			</div>
			<div class="sandbox" id="sandbox_h">
				<button class="onclick" onclick="addDiv()">Dodaj element</button>
				<!--<div class='blok_test'><div id='mydivheader'><img class='obrazek' id='blok_polecen' src='blok_polecen.png'></div></div>-->
			</div>
			
			<script type="text/javascript" src="main.js"></script>
		</div>
	</body>
</html>

 

2 odpowiedzi

0 głosów
odpowiedź 25 października 2021 przez VBService Ekspert (252,660 p.)

Tu masz bład

const el = document.querySelector(".blok_test");

próbujesz "złapać" element, który w kodzie jest "zakomentowany"

<div class="sandbox" id="sandbox_h">
                <button class="onclick" onclick="addDiv()">Dodaj element</button>
                <!--<div class='blok_test'><div id='mydivheader'><img class='obrazek' id='blok_polecen' src='blok_polecen.png'></div></div>-->
            </div>
<!--<div class='blok_test'> ... -->

 

komentarz 25 października 2021 przez Jcob2222 Początkujący (480 p.)
Nie, sorry za wprowadzenie w błąd, element zakomentowany faktycznie działa, ale służył tylko i wyłącznie do testów, o czym nie wspomniałem, więc przepraszam. Problem jest w tym że stworzony element w JS poprzez createElement nie chce się przesuwać.
komentarz 26 października 2021 przez VBService Ekspert (252,660 p.)
edycja 26 października 2021 przez VBService

Zrobiłem na "klik" ( click - łapie, mousemove - przesuwa, click - puszcza ) 

.obrazek {
  position: fixed;
}
.mouse-down {
  box-shadow: 0 0 4px 4px gray; 
}
var moved_element_offsetLeft = 0,
    moved_element_offsetTop = 0, 
    mousedown = false,
    moved_element;

function addDiv() {
  const div = document.createElement('div');
  div.classList.add('blok_test');
  div.innerHTML = "<div id='mydivheader'><img class='obrazek' id='blok_polecen' src='https://picsum.photos/50/50/?random" + Math.random() * 100 + "'></div>";
  document.getElementById("sandbox_h").appendChild(div);
  div.addEventListener('click', mouseClick, true);
}

function mouseClick(e) {
  if (!mousedown) {
    mousedown = true;
    moved_element = e.target;
    moved_element.classList.add('mouse-down');
    
    const moved_element_rect = e.target.getBoundingClientRect();
    moved_element_offsetLeft = e.clientX - moved_element_rect.left;
    moved_element_offsetTop = e.clientY - moved_element_rect.top;
  } else {
    mousedown = false;
    moved_element.classList.remove('mouse-down');
  }
}
window.addEventListener('mousemove', (e) => {
  if (mousedown) { 
    moved_element.style.left = (e.clientX - moved_element_offsetLeft) + 'px'; 
    moved_element.style.top = (e.clientY - moved_element_offsetTop) + 'px'; 
  } 
}, true); 

 

P.S. Nie miałem czasu, aby "rozgryźć" ustawianie elementów w czasie dodawania (button - "Dodaj element") większej ich ilości. ( np. dodaj element - inline-block, relative. przesuwanie - fixed )

 

komentarz 26 października 2021 przez Jcob2222 Początkujący (480 p.)
Dzięki wielkie, twój kod mi pomógł. A masz pomysł dlaczego po kliknięciu tego diva, div ucieka i kursor jest poza nim?
komentarz 26 października 2021 przez VBService Ekspert (252,660 p.)

Proszę pokaż Twój kod, bo ten kod co Tobie podałem ... działa, bez tego efektu.

1
komentarz 26 października 2021 przez Jcob2222 Początkujący (480 p.)

Dzięki za pomoc, rozwiązałem już ten problem zmieniając to:

const moved_element_rect = e.target.getBoundingClientRect();
moved_element_offsetLeft = e.clientX - moved_element_rect.left;
moved_element_offsetTop = e.clientY - moved_element_rect.top;

na to:

const moved_element_rect = e.target.getBoundingClientRect();
const margines_o = document.getElementById('sandbox_h').getBoundingClientRect();
moved_element_offsetLeft = e.clientX - moved_element_rect.left + margines_o.left;
moved_element_offsetTop = e.clientY - moved_element_rect.top + margines_o.top;

Chodziło o to, że blok "sandbox" nie jest "przyklejony" do lewej krawędzi, czyli ma jakiś margines od lewej, ponieważ znajduje się tam inna sekcja <div>.

0 głosów
odpowiedź 25 października 2021 przez overcq Pasjonat (21,650 p.)
edycja 26 października 2021 przez overcq
const el = document.querySelector(".blok_test");

wykonuje się przed wywołaniem funkcji addDiv, więc wynikiem jest null.

Poza tym w funkcji mousemove obliczasz na wartościach bezwzględnych pozycji wskaźnika jak na wartościach względnych.

function addDiv() {
  let div = document.createElement("div");
  div.classList.add("blok_test");
  div.addEventListener("mousedown", mousedown);
  div.innerHTML =
    "<div id='mydivheader'><img class='obrazek' id='blok_polecen' src='blok_polecen.png' draggable='false'></div>";
  document.getElementById("sandbox_h").appendChild(div);
}
 
function mousedown(e) {
  const el = document.querySelector(".blok_test");
  window.addEventListener("mousemove", mousemove);
  window.addEventListener("mouseup", mouseup);
 
  const rect = el.getBoundingClientRect();
  const diffX = e.clientX - rect.left;
  const diffY = e.clientY - rect.top;
 
  function mousemove(e) {
    el.style.left = e.clientX - diffX + "px";
    el.style.top = e.clientY - diffY + "px";
  }
 
  function mouseup() {
    window.removeEventListener("mousemove", mousemove);
    window.removeEventListener("mouseup", mouseup);
  }
}

I tak działa to nie najlepiej z powodu włączającego się mechanizmu drag&drop przeglądarki internetowej.

komentarz 25 października 2021 przez Jcob2222 Początkujący (480 p.)
A jakiś pomysł jak mimo wszystko rozwiązać ten problem? Może i nie działa najlepiej, ale jednak działa. A jeśli nie to w jaki inny sposób można zrobić przesuwanie dodanego div'a?
komentarz 26 października 2021 przez overcq Pasjonat (21,650 p.)

https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/draggable

Poprawiłem również zawartość bloczka kodu.

 

komentarz 26 października 2021 przez Jcob2222 Początkujący (480 p.)
Dzięki za pomoc!

Podobne pytania

0 głosów
2 odpowiedzi 275 wizyt
pytanie zadane 13 października 2015 w JavaScript przez Shiro Stary wyjadacz (10,300 p.)
+1 głos
2 odpowiedzi 203 wizyt
pytanie zadane 17 czerwca 2020 w JavaScript przez Marak123 Stary wyjadacz (11,190 p.)
0 głosów
2 odpowiedzi 106 wizyt
pytanie zadane 14 listopada 2020 w JavaScript przez Nabuchadonozor Gaduła (3,120 p.)

92,547 zapytań

141,388 odpowiedzi

319,506 komentarzy

61,931 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...