Javascript.RU

Создать новую тему Ответ
 
Опции темы Искать в теме
  #131 (permalink)  
Старый 30.12.2017, 23:20
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,112

Nlk,
может сделать рефакторинг, вернутся к минимальному макету и сформулировать задачу по новой, возможно дверь где-то рядом.
Ответить с цитированием
  #132 (permalink)  
Старый 31.12.2017, 17:27
Аватар для Nlk
Nlk Nlk вне форума
Кандидат Javascript-наук
Отправить личное сообщение для Nlk Посмотреть профиль Найти все сообщения от Nlk
 
Регистрация: 25.12.2016
Сообщений: 146

Сообщение от рони Посмотреть сообщение
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>
Ответить с цитированием
  #133 (permalink)  
Старый 31.12.2017, 18:45
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,112

Сообщение от Nlk
Поясню, в приведённом ниже коде при прокручивании страницы, должен активироваться последующийся блок кораллового цвета.
как и прежде туманно ... может вам нужен блок который ближе всего к верхней части окна?
ссылка снова на плавный скролл при нажатии на кнопки клавиатуры(вниз, вверх)
Ответить с цитированием
  #134 (permalink)  
Старый 31.12.2017, 18:55
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,112

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>
Ответить с цитированием
  #135 (permalink)  
Старый 31.12.2017, 19:46
Аватар для Nlk
Nlk Nlk вне форума
Кандидат Javascript-наук
Отправить личное сообщение для Nlk Посмотреть профиль Найти все сообщения от Nlk
 
Регистрация: 25.12.2016
Сообщений: 146

рони,
Заработало в Firefox, спасибо. Правда в Opera иногда прокручивает, но суть понятна спасибо большое, буду пробовать.
Ответить с цитированием
  #136 (permalink)  
Старый 31.12.2017, 19:52
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,112

Nlk,
if (-100 < pages[i].getBoundingClientRect().top) эксперементируйте.
Ответить с цитированием
  #137 (permalink)  
Старый 03.01.2018, 04:32
Аватар для Nlk
Nlk Nlk вне форума
Кандидат Javascript-наук
Отправить личное сообщение для Nlk Посмотреть профиль Найти все сообщения от Nlk
 
Регистрация: 25.12.2016
Сообщений: 146

рони,
скажите пожалуйста, в приведённом ниже коде, помимо добавления класса к определённому элементу, можно ещё добавить другой класс к его двум соседним элементам справа и слева, используя методы 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");
		});
	}
Ответить с цитированием
  #138 (permalink)  
Старый 03.01.2018, 09:29
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,112

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");

         */
     }
    });
}
Ответить с цитированием
  #139 (permalink)  
Старый 03.01.2018, 19:31
Аватар для Nlk
Nlk Nlk вне форума
Кандидат Javascript-наук
Отправить личное сообщение для Nlk Посмотреть профиль Найти все сообщения от Nlk
 
Регистрация: 25.12.2016
Сообщений: 146

рони,
огромное вам спасибо. Извините что так часто обращаюсь к вам за помощью.
Но я снова с просьбой, когда я искал решение, касаемо уменьшения количества событий на один 'скрол' в браузере 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);
Ответить с цитированием
  #140 (permalink)  
Старый 03.01.2018, 19:45
Аватар для рони
Профессор
Отправить личное сообщение для рони Посмотреть профиль Найти все сообщения от рони
 
Регистрация: 27.05.2010
Сообщений: 33,112

Nlk,
var myEfficientFn = debounce(eventScroll, 250);
document.addEventListener("scroll", myEfficientFn );
Ответить с цитированием
Ответ



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

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


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
jquery выборка элементов из переменной winch jQuery 4 15.04.2016 09:09
выборка элементов таблицы и цвет фона xber9 jQuery 10 07.08.2013 20:30
выборка видимых элементов ChikiSt Общие вопросы Javascript 8 01.12.2011 11:26
Выборка элементов у которых есть данные установленные через дата TicTac jQuery 2 02.05.2011 23:45
выборка элементов jetli13 jQuery 9 30.07.2010 13:53