Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Выборка элементов querySelectorAll (https://javascript.ru/forum/events/71107-vyborka-ehlementov-queryselectorall.html)

Nlk 27.12.2017 14:54

Nexus,
Допустим у меня сайта длиной 100%, мне нужно чтобы пользователь при прокручиваниии смог прокрутить весь сайт с начала до конца за 4 скрола.

Может как то так, только на js
window.scrollTop() + body.height() / 25

рони 27.12.2017 15:01

Цитата:

Сообщение от Nlk
100%

:-? может 400% ?

Nlk 27.12.2017 15:44

рони,
Извиняюсь, что ввёл в заблуждение излишней информацией. Перефразирую так, в независимости от длины моего сайта, мне нужно чтобы я его мог проскролить за четыре события скролом. Подобное можно реализовать?

Nexus 27.12.2017 16:18

Nlk, что-то типа этого (Не довел до ума)?
https://jsfiddle.net/xu9swjj6/2/

Nlk 27.12.2017 17:07

Nexus,
очень помогли. Спасибо.

Nlk 30.12.2017 20:15

Здравствуйте!
Хочу поздравить всех с наступающим Новым Годом!

Скажите пожалуйста, не даёт мне покоя одно событие, почему отображение данных по координатам 'скрола' в разных браузерах отображается по разному. И как это исправить?

Отлавливал 'скрол' с помощью данного выражения:
let scrolled = window.pageYOffset || document.documentElement.scrollTop;

document.getElementById('test_1').innerHTML = scrolled + 'px - Происходящий scroll';
document.getElementById('test_2').innerHTML = lastScrolled + 'px - Предыдущий scroll';

К примеру, результат при первом 'скроле' в Chrome:
100px - Происходящий scroll
0px - Предыдущий scroll ------------------------ ?

К примеру, результат при первом 'скроле' в Firefox:
114px - Происходящий scroll
113px - Предыдущий scroll ---------------------- ?

рони 30.12.2017 21:09

Цитата:

Сообщение от Nlk
почему отображение данных по координатам 'скрола' в разных браузерах отображается по разному.

нет стандарта на сколько пикселей крутить
Цитата:

Сообщение от Nlk
И как это исправить?

отменить scroll и добавить свой.
но возможно, вы не там траншею копать собрались:)

рони 30.12.2017 21:14

Nlk,
https://learn.javascript.ru/mousewheel

Nlk 30.12.2017 23:08

Уточнение по заданному вопросу
 
Цитата:

Сообщение от рони (Сообщение 474038)
нет стандарта на сколько пикселей крутить

Постараюсь переформулировать.
Меня не смущает отсутствие стандарта по длине 'скрола' у разных браузеров. Дело в том, что к примеру в браузере Chrome при одном прокручивании страницы у меня происходит одно событие, а в Firefox за один 'скрол' целых шесть.

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

рони 30.12.2017 23:15

Цитата:

Сообщение от Nlk
в Firefox за один 'скрол' целых шесть.

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

рони 30.12.2017 23:20

Nlk,
может сделать рефакторинг, вернутся к минимальному макету и сформулировать задачу по новой, возможно дверь где-то рядом.

Nlk 31.12.2017 17:27

Цитата:

Сообщение от рони (Сообщение 474053)
Nlk,
может сделать рефакторинг, вернутся к минимальному макету и сформулировать задачу по новой, возможно дверь где-то рядом.

Спасибо.

Ребята, подскажите пожалуйста. Очень долго уже ломаю голову)
Проблема данного кода в том, что в некоторых браузерах, при единождом 'скроле' страницы, происходит сразу несколько событий. Поясню, в приведённом ниже коде при прокручивании страницы, должен активироваться последующийся блок кораллового цвета. Но в некоторых браузерах, при первом же 'скроле', у нас сразу активируется последний блок. По причине того, что за один 'скрол', класс .active успевает назначиться сразу всем последующим блокам, и остановиться на последнем.

<!DOCTYPE html><head><meta charset="UTF-8"><style>

body {min-height: 200vh;}
.page {height: 25vh; width: 100%; background: gray; border: 2px solid white;}
.active {background: coral;}

</style></head><body>
	
<section class="page"></section>
<section class="page"></section>
<section class="page"></section>
<section class="page"></section>

<script>'use strict';

window.addEventListener("DOMContentLoaded", function() {
	document.addEventListener("scroll", eventScroll);
	const pages = document.querySelectorAll(".page");
	let lastScrolled = 0;
	function showPage() {
		[].forEach.call(pages, function(el, i) {
			i == pageIndex ? el.classList.add("active") : el.classList.remove("active");
		});
	}
	let pageIndex = 0;
	showPage();
	function eventScroll() {
		let scrolled = window.pageYOffset || document.documentElement.scrollTop;
		if (scrolled < lastScrolled) {
			--pageIndex;
		} else {
			++pageIndex;
		};
		pageIndex < 0 && (pageIndex = 0);
		pageIndex > pages.length - 1 && (pageIndex = pages.length - 1);
		showPage();
		lastScrolled = scrolled;
	}
});

</script></body></html>

рони 31.12.2017 18:45

Цитата:

Сообщение от Nlk
Поясню, в приведённом ниже коде при прокручивании страницы, должен активироваться последующийся блок кораллового цвета.

как и прежде туманно ... может вам нужен блок который ближе всего к верхней части окна?
ссылка снова на плавный скролл при нажатии на кнопки клавиатуры(вниз, вверх)

рони 31.12.2017 18:55

Nlk,
<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><style>

body {min-height: 200vh;}
.page {height: 25vh; width: 100%; background: gray; border: 2px solid white;}
.active {background: coral;}

</style></head><body>

<section class="page"></section>
<section class="page"></section>
<section class="page"></section>
<section class="page"></section>

<script>
window.addEventListener("DOMContentLoaded", function() {
  document.addEventListener("scroll", eventScroll);
  var pages = document.querySelectorAll(".page");
  function showPage(pageIndex) {
    [].forEach.call(pages, function(el, i) {
      i === pageIndex ? el.classList.add("active") : el.classList.remove("active");
    });
  }
  function eventScroll() {
    for (var i = 0; i < pages.length; i++) {
      if (0 < pages[i].getBoundingClientRect().top) {
        break;
      }
    }
    showPage(i);
  }
  eventScroll()
});
</script></body></html>

Nlk 31.12.2017 19:46

рони,
Заработало в Firefox, спасибо. Правда в Opera иногда прокручивает, но суть понятна спасибо большое, буду пробовать.

рони 31.12.2017 19:52

Nlk,
if (-100 < pages[i].getBoundingClientRect().top) эксперементируйте. :)

Nlk 03.01.2018 04:32

рони,
скажите пожалуйста, в приведённом ниже коде, помимо добавления класса к определённому элементу, можно ещё добавить другой класс к его двум соседним элементам справа и слева, используя методы nextElementSibling и previousElementSibling?

function showPage() {
		[].forEach.call(pages, function(el, i) {
			i == pageIndex ? el.classList.add("active") && el.nextElementSibling.classList.add("new") : el.classList.remove("active");
		});
	}

рони 03.01.2018 09:29

Nlk,
добавить можно, но как правильно отменить не знаю, алгоритм нужен или два цикла, первый для отмены всех классов второй для установки
function showPage() {
    [].forEach.call(pages, function(el, i, p) {
        el.classList.remove("active");
        el.classList.remove("new");
    });

    [].forEach.call(pages, function(el, i, p) {
     if(i == pageIndex ) {
        el.classList.add("active");
        el.nextElementSibling && el.nextElementSibling.classList.add("new");
        el.previousElementSibling  && el.previousElementSibling.classList.add("new");
        /* или так
           p[i-1] &&  p[i-1].classList.add("new");
           p[i+1] &&  p[i+1].classList.add("new");

         */
     }
    });
}

Nlk 03.01.2018 19:31

рони,
огромное вам спасибо. Извините что так часто обращаюсь к вам за помощью.
Но я снова с просьбой, когда я искал решение, касаемо уменьшения количества событий на один 'скрол' в браузере Mozilla. То натолкнулся на материал, про функцию debounce, которая не позволяет обработчику события выполниться более одного раза в заданный промежуток времени. Могу ли я проецировать это к своему коду и как?

В интернете мне попался такой пример, но я не понимаю как могу его использовать:
// Returns a function, that, as long as it continues to be invoked, will not
// be triggered. The function will be called after it stops being called for
// N milliseconds. If `immediate` is passed, trigger the function on the
// leading edge, instead of the trailing.
function debounce(func, wait, immediate) {
	var timeout;
	return function() {
		var context = this, args = arguments;
		var later = function() {
			timeout = null;
			if (!immediate) func.apply(context, args);
		};
		var callNow = immediate && !timeout;
		clearTimeout(timeout);
		timeout = setTimeout(later, wait);
		if (callNow) func.apply(context, args);
	};
};

// Usage
var myEfficientFn = debounce(function() {
	// All the taxing stuff you do
}, 250);
window.addEventListener('resize', myEfficientFn);

рони 03.01.2018 19:45

Nlk,
var myEfficientFn = debounce(eventScroll, 250);
document.addEventListener("scroll", myEfficientFn );

Nlk 03.01.2018 21:04

рони,
спасибо. Работает)

Nlk 09.01.2018 13:42

Ребята, объясните пожалуйста, почему так получается что при наведении курсора на область с position:fixed и прокручивании, страница остаётся неподвижной. А при наведении курсора в любую другую область сайта при скроле всё нормально прокручивается.

Nexus 09.01.2018 13:48

Nlk, можно пример?
https://jsfiddle.net/uyh6exyj/

Nlk 09.01.2018 15:06

В коде приведённом ниже скрыт скролл страницы, это нужно оставить.

Nexus 09.01.2018 15:10

Nlk,
Пожалуйста, отформатируйте свой код!

Для этого его можно заключить в специальные теги: js/css/html и т.п., например:
[js]
... ваш код...
[/js]


О том, как вставить в сообщение исполняемый javascript и html-код, а также о дополнительных возможностях форматирования - читайте http://javascript.ru/formatting.

Nlk 09.01.2018 15:29

Извиняюсь, поправил.

<!DOCTYPE html><html lang="ru"><head><meta charset="UTF-8"><style>
* {
	padding: 0;
	margin: 0;
	box-sizing: border-box;
}
html, body{
	min-height: 100%;
}
body{
	overflow: hidden;
}
.wrap {
	overflow-y: scroll;
	width: calc(100% + 9px);
	position: absolute;
        top: 0;
        bottom: 0;
        right: 0;
        left: 0;
}
.page {
	height: 100vh; 
	width: 100%; 
}
.active {
	position: fixed; 
	top: 0;
	height: 100px;
}


.page:nth-of-type(1) {background-color:#cccccc;}
.page:nth-of-type(2) {background-color:#afafaf;}
.page:nth-of-type(3) {background-color:#737373;}
.page:nth-of-type(4) {background-color:#404040;}

</style></head><body>
	
	
<section class="wrap">
	<section class="page active"></section>
	<section class="page"></section>
	<section class="page"></section>
	<section class="page"></section>
</section>
	
</body></html>

Nlk 10.01.2018 16:25

Альтернативное решение использовать position:sticky, правда его поддержка браузерами не так хороша.

Nexus 10.01.2018 16:31

Nlk, в какой ситуации потребовалось растягивать блок с контентом на весь экран и его потомка фиксировать сверху?

Nlk 10.01.2018 17:05

Nexus,
Full Page Slider, реализация может и своеобразная, но вопрос лишь в этом моменте.

Nexus 10.01.2018 17:08

Nlk, не проще просто растянуть высоту обертки, отказавшись от её абсолютного позиционирования?

Nlk 10.01.2018 17:59

Nexus,
Буду пробовать, спасибо за совет!

Nlk 11.01.2018 15:08

Скажите пожалуйста, а возможно с помощью js, элементу с свойством position:fixed насильно назначить другого родителя нежели viewport. Чтобы менять позиционирование не относительно окна браузера а относительно другого элемента родителя?

let parent = document.querySelector("wrap");
	let child = document.querySelector("active");
	parent.appendChild(child);


У меня 'ругается' что:
Uncaught TypeError: Cannot read property 'appendChild' of null

j0hnik 11.01.2018 15:20

не лучше ли просто элементу задать позиционирование как :absolute? с помощью js

Dilettante_Pro 11.01.2018 15:29

Nlk,
let parent = document.querySelector(".wrap");
    let child = document.querySelector(".active");
    parent.appendChild(child);

Nlk 12.01.2018 10:25

j0hnik,
К сожалению, свойство absolute не подходит для дальнейшей реализации кода.

Dilettante_Pro,
Спасибо исправил, но не смотря на это позиционирование осталось от viewport.

Хочу попробовать вариант приведённый ниже, единственно не знаю как обращаться к классу active, ведь в начале загрузки страницы его нет, он добавляется впоследствии динамически по событию 'скрола'.

active && active.style.transform = "translateY("+wrap.scrollTop+"px)";

// или так
[].forEach.call(pages, function(el, i) {
			if (el.classList.contains("active")) {
				el.style.transform = "translateY("+wrap.scrollTop+"px)";
			} else {};

рони 12.01.2018 10:30

:) можно не отвечать ... кто подскажет, что хочет сделать Nlk,?

Nlk 12.01.2018 11:57

рони,
:) я так понимаю, что экстрасенсов тут нет, и нужно приводить весь код.

рони 12.01.2018 12:01

Цитата:

Сообщение от Nlk
и нужно приводить весь код.

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

Nlk 14.01.2018 22:24

рони,
Каждый раз надеешься что дальше получиться завершить самому, но и за отсутствия опыта приходиться вновь и вновь обращаться за помощью. Сейчас все работает, спасибо вам, разместил по ссылке https://codecanyon.net/item/page-sli...lugin/22780197

рони 14.01.2018 23:21

Nlk,
не понимаю, видимо выпал из темы, ни оценить, ни подсказать не могу


Часовой пояс GMT +3, время: 10:41.