Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #1 (permalink)  
Старый 29.06.2014, 23:18
Интересующийся
Отправить личное сообщение для desertFox Посмотреть профиль Найти все сообщения от desertFox
 
Регистрация: 29.08.2013
Сообщений: 20

Как правильно рассчитать координаты курсора мышки
Добрый вечер.

При наведении мышки на маленькую картинку появляется блок с увеличенной картинкой:

// При наведении на объект
function photoOn(ell, e){
  var newDivPh = document.createElement('div');
  document.body.appendChild(newDivPh);
  newDivPh.id = 'newDivPh';
  var newImg = document.createElement('img');
  newDivPh.appendChild(newImg);
  newImg.setAttribute('alt', '');
  newImg.setAttribute('src', ell);
  newImg.id = 'newImg';
  var event = (window.event) ? window.event : e;
  if(newDivPh.offsetHeight >= window.innerHeight) {
	newDivPh.style.top = (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop)+5 + 'px';
  } else if (event.clientY + newDivPh.offsetHeight > window.innerHeight) {
	newDivPh.style.top = (event.clientY - newDivPh.offsetHeight - 1 + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop) + 'px';
  } else {
	newDivPh.style.top = (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop)+5 + 'px';
  }
  
  newDivPh.style.left = (event.clientX - newDivPh.offsetWidth - 7 + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft) + 'px';
}
// При движении по объекту
function photoMove(e){
  var newDivPh = document.getElementById('newDivPh');
  var event = (window.event) ? window.event : e;
  if(newDivPh.offsetHeight >= window.innerHeight) {
	newDivPh.style.top = (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop)+5 + 'px';
  } else if (event.clientY + newDivPh.offsetHeight > window.innerHeight) {
	newDivPh.style.top = (event.clientY - newDivPh.offsetHeight - 1 + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop) + 'px';
  } else {
	newDivPh.style.top = (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop)+5 + 'px';
  }
  
  newDivPh.style.left = (event.clientX - newDivPh.offsetWidth - 7 + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft) + 'px';
}
// При убирании курсора с объекта
function photoOff(){
  var newDivPh = document.getElementById('newDivPh');
  newDivPh.parentNode.removeChild(newDivPh);
}


разметка HTML:
<a href='#' onmouseover="javascript:photoOn('/bigfoto.jpg', event);" onmousemove="photoMove(event)" onmouseout="javascript:photoOff();"><img src='/smallfoto.jpg' alt='' /></a>


Большую картинку вывожу слева:


Код нашёл в интернете и часть переделал под себя, но видимо *криво переделал* и код работает не корректно. Большая картинка сначала появляется справа и заходит за границы браузера, а уже потом перелетает в левую часть. Аналогичная ситуация и по оси "y". Это конечно происходит за доли секунд, но всё равно *скачки* заметны.

Вот такие дела). Как исправить чтобы большая картинка сразу грузилась с нужными координатами?

Последний раз редактировалось desertFox, 29.06.2014 в 23:26.
Ответить с цитированием
  #2 (permalink)  
Старый 29.06.2014, 23:26
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,072

desertFox,
картинке-то нужно время чтоб подгрузится
Ответить с цитированием
  #3 (permalink)  
Старый 30.06.2014, 01:22
Интересующийся
Отправить личное сообщение для desertFox Посмотреть профиль Найти все сообщения от desertFox
 
Регистрация: 29.08.2013
Сообщений: 20

Сообщение от рони Посмотреть сообщение
desertFox,
картинке-то нужно время чтоб подгрузится
сделал так:
// При наведении на объект
function photoOn(ell, e){
  var newDivPh = document.createElement('div');
  document.body.appendChild(newDivPh);
  newDivPh.id = 'newDivPh';
  var newImg = document.createElement('img');
  newDivPh.appendChild(newImg);
  newImg.setAttribute('alt', '');
  newImg.setAttribute('src', ell);
  newImg.id = 'newImg';
  var event = (window.event) ? window.event : e;
  newDivPh.onLoad = function () {
	  if(newDivPh.offsetHeight >= window.innerHeight) {
		newDivPh.style.top = (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop)+5 + 'px';
	  } else if (event.clientY + newDivPh.offsetHeight > window.innerHeight) {
		newDivPh.style.top = (event.clientY - newDivPh.offsetHeight - 1 + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop) + 'px';
	  } else {
		newDivPh.style.top = (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop)+5 + 'px';
	  }
	  
	  newDivPh.style.left = (event.clientX - newDivPh.offsetWidth - 7 + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft) + 'px';
	}
}


Чего-то не получается, и на картинку "onload" аналогично пробовал - newImg.onLoad
Ответить с цитированием
  #4 (permalink)  
Старый 30.06.2014, 01:27
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,072

desertFox, src меняют после того как обьявили load -- load дополнительно проверяют может уже был
Ответить с цитированием
  #5 (permalink)  
Старый 30.06.2014, 01:38
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,072

desertFox,
да и лучше макет бы вам сделать.
Ответить с цитированием
  #6 (permalink)  
Старый 30.06.2014, 02:00
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,072

desertFox, и что не так?
<!DOCTYPE HTML>

<html>

<head>
<style type="text/css">
a{
  display:inline-block;
  float:right;
}

#newDivPh{
  position:absolute;
  visibility:hidden;
  padding:0px;
  margin:0px;
  z-index:300;
  background-color:#ffffff;
  background-image:url("./images/spinner.gif");
  background-repeat:no-repeat;
  background-position:center;
  -moz-border-radius:5px;
  -webkit-border-radius:5px;
  border-radius:5px;
  border:#FFFFFF 6px solid;
  border-bottom-width:2px;
}

#newDivPh img{
  padding:0px;
  margin:0px;
  -moz-border-radius:5px;
  -webkit-border-radius:5px;
  border-radius:5px;
}

body{
  background:#DDDDDD;
}
</style>
  <title>Untitled</title>
  <script>
    // При наведении на объект
function photoOn( e ,ell){
  var newDivPh = document.createElement('div');
  document.body.appendChild(newDivPh);
  newDivPh.id = 'newDivPh';
  var newImg = document.createElement('img');
  newDivPh.appendChild(newImg);
  newImg.setAttribute('alt', '');

  newImg.id = 'newImg';
  var event = (window.event) ? window.event : e;
  newImg.onload = function () {
	  if(newDivPh.offsetHeight >= window.innerHeight) {
		newDivPh.style.top = (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop)+5 + 'px';
	  } else if (event.clientY + newDivPh.offsetHeight > window.innerHeight) {
		newDivPh.style.top = (event.clientY - newDivPh.offsetHeight - 1 + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop) + 'px';
	  } else {
		newDivPh.style.top = (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop)+5 + 'px';
	  }

	  newDivPh.style.left = (event.clientX - newDivPh.offsetWidth - 7 + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft) + 'px';
      newDivPh.style.visibility = 'visible';
  }
    newImg.setAttribute('src', ell);
    newImg.complete && newImg.onload();
}
// При движении по объекту
function photoMove(e){
  var newDivPh = document.getElementById('newDivPh');
  var event = (window.event) ? window.event : e;
  if(newDivPh.offsetHeight >= window.innerHeight) {
	newDivPh.style.top = (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop)+5 + 'px';
  } else if (event.clientY + newDivPh.offsetHeight > window.innerHeight) {
	newDivPh.style.top = (event.clientY - newDivPh.offsetHeight - 1 + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop) + 'px';
  } else {
	newDivPh.style.top = (event.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop)+5 + 'px';
  }

  newDivPh.style.left = (event.clientX - newDivPh.offsetWidth - 7 + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft) + 'px';
}
// При убирании курсора с объекта
function photoOff(){
  var newDivPh = document.getElementById('newDivPh');
  newDivPh.parentNode.removeChild(newDivPh);
}

  </script>
</head>

<body>
<a href='#' onmouseover="javascript:photoOn( event,'http://learn.javascript.ru/files/tutorial/browser/events/gallery/img2-lg.jpg');" onmousemove="photoMove(event)" onmouseout="javascript:photoOff();"><img src='http://learn.javascript.ru/files/tutorial/browser/events/gallery/img2-thumb.jpg' alt='' /></a>
</body>

</html>

Последний раз редактировалось рони, 30.06.2014 в 10:53.
Ответить с цитированием
  #7 (permalink)  
Старый 30.06.2014, 07:47
Интересующийся
Отправить личное сообщение для desertFox Посмотреть профиль Найти все сообщения от desertFox
 
Регистрация: 29.08.2013
Сообщений: 20

Цитата:
desertFox,
да и лучше макет бы вам сделать.
я не знаю чего это и зачем)

Цитата:
desertFox, и что не так?
координаты медленно высчитываются), а вернее не верно, так как не определена ширина блока newDivPh, поэтому тему так и назвал "как правильно рассчитать.."

если ставить жёсткие размеры то всё нормально, но жёсткие размеры блока newDivPh не подходят, поэтому использую newDivPh.offsetHeight, newDivPh.offsetWidth

у меня сейчас ерунда в коде, сначала грузится объект по одним координатам, а потом по мере изменения размера блока (загрузки картинки) высчитываются новые координаты, вот поэтому и *прыгает картинка*

надо сначала загрузить картинку а потом рассчитать координаты с учётом полученных размеров, я это изначально знал, но не знаю как правильно это сделать
Ответить с цитированием
  #8 (permalink)  
Старый 30.06.2014, 08:09
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,072

desertFox,
макет это то что в посте выше -- если здесь на форуме у вас всё работает смотрите разницу этого кода и вашего
Ответить с цитированием
  #9 (permalink)  
Старый 30.06.2014, 08:50
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,072

desertFox,
добавлено пока картинка незагружена div visibility: hidden;
Ответить с цитированием
  #10 (permalink)  
Старый 30.06.2014, 10:23
Интересующийся
Отправить личное сообщение для desertFox Посмотреть профиль Найти все сообщения от desertFox
 
Регистрация: 29.08.2013
Сообщений: 20

спасибо, здесь нормально работает,

но у меня снова без изменений,

в браузере опера вместо прыжков наблюдается ещё такая картина:



белая неполная полоса вокруг картинки это был padding: 4px; блока newDivPh,

при повторном наведение всё нормально, белая полоса полностью окружает картинку и картинка расположена слева как и нужно,

после чистки кеша в браузере снова при первом наведение либо прыгает, либо на треть зависает (в опере, скриншот выше)

пробовал без padding: 4px; тоже самое, пока оставил просто полоску вокруг картинки (border)

сейчас стили такие:
#newDivPh{
	position:absolute;
	/*visibility: hidden;*/
	z-index: 300;
	background-color: #ffffff;
	background-image: url("./images/spinner.gif");
    background-repeat: no-repeat;
	background-position: center;
	-moz-border-radius:5px;
	-webkit-border-radius:5px;
	border-radius:5px;
	box-shadow: 0 0 5px #777777;
	-moz-box-shadow: 0 0 5px #777777;
	-webkit-box-shadow: 0 0 5px #777777;
	min-width: 100px;
	min-height: 100px;
	max-width: 408px;
	max-height: 308px;
}

 #newDivPh img{
  border: 4px solid #fff;
  max-width: 400px !important;
  max-height: 300px !important;
  -moz-border-radius:5px;
  -webkit-border-radius:5px;
  border-radius:5px;
}


стиль visibility убрал, так как при наведении некоторые картинки вообще перестали показываться

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

один только бордер видно:

Последний раз редактировалось desertFox, 30.06.2014 в 10:55.
Ответить с цитированием
Ответ



Опции темы Искать в теме
Искать в теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Как вы относитесь к наркоманам? Maxmaxmaximus7 Оффтопик 7 05.02.2014 13:29
Событие click как правильно? piraids jQuery 9 20.08.2013 13:01
Пасоны, как правильно парсить параметры? megaupload Оффтопик 15 05.05.2013 14:44
Как правильно прицепить обработку события slowklg Events/DOM/Window 6 15.03.2012 16:20
Как правильно очистить maxlength в input? Маэстро Events/DOM/Window 10 22.06.2011 18:14