Zaburzenie interwału

Zaburzenie interwału
ZB
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 4 lata
  • Postów:50
0

Witajcie,
robię slider oparty na JS. W założeniu ma on być dosyć dynamiczny - klient sam dodaje slajdy. Chciałem dodać paginację, w tym celu też wygenerowałem odpowiednie elementy przez JS. No i to zrodziło problemy. Automatyczna zmiana slajdów jest zaburzona (w odpowiednim czasie zmienia się z 1->2, a następnie błyskawicznie na 3), jak również zmiana przez użycie paginacji - zmienia się na docelowy slajd, ale później jest zaburzony czas zmiany slajdów (skraca się blisko 2 razy). Poniżej kod:

Kopiuj
// *--------- SLIDER ---------*
var countSlides = $('.slides').children('li').length;
var sliderControls = new Array();


$(window).load(function() {
	$('.slider').children('.slides').css('width', countSlides*100+'%');
	$('.slider').find('.slide').css('width', $('.slider').width()+'px');
});

// *------ CONFIGURATION ------*
var animationSpeed = 1000;
var pause = 10000;
var currentSlide = 1;

// *------ VARIABLES ------*
var $slider = $('.slider');
var $slides = $('.slider').children('.slides');
var $slide = $('.slider').find('.slide');

var interval;

function startSlider() {
	interval = setInterval(function() {
		if ((currentSlide+1) <= $slide.length) {
			$slides.animate({'margin-left': '-=100%'}, animationSpeed, function() {
				currentSlide++;
				for (var i = 0; i < sliderControls.length; i++) {
					sliderControls[i].removeClass('slide-active');
				}
				sliderControls[currentSlide-1].addClass('slide-active');
			});
		}
		else {
			$slides.animate({'margin-left': '+='+(--currentSlide*100)+'%'}, animationSpeed, function() {
				currentSlide = 1;
				for (var i = 0; i < sliderControls.length; i++) {
					sliderControls[i].removeClass('slide-active');
				}
				sliderControls[currentSlide-1].addClass('slide-active');
			});
		}
	}, pause);
}

function stopSlider() {
	clearInterval(interval);
}

$(function() {
	$slider.on('mouseenter', stopSlider()).on('mouseleave', startSlider());
	startSlider();
});

function changeSlide(number) {
	var currentMargin = $slides.css('margin-left');
	if (number < currentSlide) {
		$slides.animate({'margin-left': '+='+(currentSlide-(number-1))*100+'%'}, animationSpeed, function() {
				currentSlide = number;
				for (var i = 0; i < sliderControls.length; i++) {
					sliderControls[i].removeClass('slide-active');
				}
				sliderControls[currentSlide-1].addClass('slide-active');
				startSlider();
		});
	}
	else {
		$slides.animate({'margin-left': '-='+(number-currentSlide)*100+'%'}, animationSpeed, function() {
				currentSlide = number;
				for (var i = 0; i < sliderControls.length; i++) {
					sliderControls[i].removeClass('slide-active');
				}
				sliderControls[currentSlide-1].addClass('slide-active');
				startSlider();
		});
	}
}

$(window).load(function() {
	$slider.append('<ul class="slider-controls">');
	for (var i = 1; i <= countSlides; i++) {
		$('.slider-controls').append('<li id="'+i+'" onClick="onSliderControlsClick('+i+');">');
	}
	$slider.append('<ul>');

	$('.slider-controls').children('li').each(function() {
		sliderControls.push($(this));
	});
	sliderControls[0].addClass('slide-active');
});

function onSliderControlsClick(id) {
	stopSlider();
	changeSlide(id);
}
Maciej Cąderek
Maciej Cąderek
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 3 lata
  • Lokalizacja:Warszawa
  • Postów:1264
4

Nie mam czasu się teraz wczytywać, ale jedno jest pewne - nie stosuj setInterval, używaj zamiast tego setTimout().

Kopiuj
(function nextSlide() {
    // kod zmiany slajdu
    setTimeout(nextSlide, 1000);
)();

Różnica jest taka, że setTimeout grawantuje w miarę równe odstępy między akcjami niezależnie od czasu trwania akcji, a setInterval gwarantuje jedynie wrzucenie funkcji do kolejki callbacków w równych odstępach czasu - jak funkcja wykonuje się dłużej niż czas interwału to kolejka się zapycha i masz takie efekty.

edytowany 1x, ostatnio: Maciej Cąderek
DE
Jeżeli chodzi o kolejkę callbacków to polecam film, który woją drogą sam poleciłeś kiedyś https://www.youtube.com/watch?v=8aGhZQkoFbQ
ŁF
setInterval nie gwarantuje nawet tego. Jeśli system będzie zajęty czymś innym to setInterval będzie mieć dowolnie duże opóźnienia, nawet jeśli sama przeglądarka się nudzi.
Maciej Cąderek
Maciej Cąderek
@ŁF Racja, "gwarantuje" to za duże słowo ;)
ZB
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 4 lata
  • Postów:50
0

Zmieniłem na setTimeout() i problem jest dalej... Poniżej w komentarzu zaznaczyłem gdzie dokładniej są błędy

Kopiuj
// *--------- SLIDER ---------*
var countSlides = $('.slides').children('li').length;
var sliderControls = new Array();


$(window).load(function() {
	$('.slider').children('.slides').css('width', countSlides*100+'%');
	$('.slider').find('.slide').css('width', $('.slider').width()+'px');
});

// *------ CONFIGURATION ------*
var animationSpeed = 1000;
var pause = 10000;
var currentSlide = 1;

// *------ VARIABLES ------*
var $slider = $('.slider');
var $slides = $('.slider').children('.slides');
var $slide = $('.slider').find('.slide');

var interval;

function startSlider() {
	interval = setTimeout(function() {
		if ((currentSlide+1) <= $slide.length) {
			$slides.animate({'margin-left': '-=100%'}, animationSpeed); // to się wykonuje
			currentSlide++; // to się wykonuje i wraca linijkę wyżej, przez co jest podwójna zmiana slajdu
		}
		else {
			$slides.animate({'margin-left': '+='+(--currentSlide*100)+'%'}, animationSpeed);
			currentSlide = 1;
		}
		for (var i = 0; i < sliderControls.length; i++) {
			sliderControls[i].removeClass('slide-active');
		}
		sliderControls[currentSlide-1].addClass('slide-active');
	}, pause);
}

function stopSlider() {
	clearTimeout(interval);
}

$(function() {
	$slider.on('mouseenter', stopSlider()).on('mouseleave', startSlider());
	startSlider();
});

function changeSlide(number) {
	var currentMargin = $slides.css('margin-left');
	if (number < currentSlide) {
		$slides.animate({'margin-left': '+='+(currentSlide-(number-1))*100+'%'}, animationSpeed, function() {
				currentSlide = number;
				for (var i = 0; i < sliderControls.length; i++) {
					sliderControls[i].removeClass('slide-active');
				}
				sliderControls[currentSlide-1].addClass('slide-active');
				startSlider();
		});
	}
	else {
		$slides.animate({'margin-left': '-='+(number-currentSlide)*100+'%'}, animationSpeed, function() {
				currentSlide = number;
				for (var i = 0; i < sliderControls.length; i++) {
					sliderControls[i].removeClass('slide-active');
				}
				sliderControls[currentSlide-1].addClass('slide-active');
				startSlider();
		});
	}
}

$(window).load(function() {
	$slider.append('<ul class="slider-controls">');
	for (var i = 1; i <= countSlides; i++) {
		$('.slider-controls').append('<li id="'+i+'" onClick="onSliderControlsClick('+i+');">');
	}
	$slider.append('<ul>');

	$('.slider-controls').children('li').each(function() {
		sliderControls.push($(this));
	});
	sliderControls[0].addClass('slide-active');
});

function onSliderControlsClick(id) {
	stopSlider();
	changeSlide(id);
}

ŁF
Moderator
  • Rejestracja:ponad 22 lata
  • Ostatnio:dzień
1

Wrzuć to na jsfiddle i wklej link, żeby można było zobaczyć to w działaniu.

BTW:
$slider.on('mouseenter', stopSlider()).on('mouseleave', startSlider());
startSlider();
w ten sposób mogą startować dwa slidery jednocześnie, przy czym jednego nie będziesz mógł zatrzymać. Funkcja zatrzymująca slider powinna zerować interval (BTW fatalna nazwa na zmienną, przecież nie określa i nigdy nie określała interwału, zrób tego jakiś timerHandle), a funkcja startująca powinna sprawdzać, czy ta zmienna > 0 i jeśli tak, to nie wykonywać się.


edytowany 2x, ostatnio: ŁF
ZB
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 4 lata
  • Postów:50
0

Mniej więcej coś takiego: https://jsfiddle.net/31gd0boz/
Nie ma paginacji, bo coś jQ nie chce wykryć. Ale w tym problemu większego nie ma - obecny kod obsługuje poprawnie ręczną zmianę slajdów. Za to automatyczna działa tylko raz.

O8
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 7 lat
  • Postów:17
0

Do wszelkich animacji radzę korzystać z czegoś takiego jak requestAnimationFrame + ewentualna korekcja poprzez Delta Timing. jQuery do kosza :(

ŁF
Do prostego slidera? oO
DO
  • Rejestracja:około 9 lat
  • Ostatnio:ponad 6 lat
  • Lokalizacja:Warszawa
  • Postów:213
0

Robisz to dla kogoś na zlecenie czy dla siebie poćwiczyć? Ja zrobiłem slider z opcja dodawania obrazków i tekstu w dość prosty sposób przerabiając te z http://www.jssor.com/ :)

Kliknij, aby dodać treść...

Pomoc 1.18.8

Typografia

Edytor obsługuje składnie Markdown, w której pojedynczy akcent *kursywa* oraz _kursywa_ to pochylenie. Z kolei podwójny akcent **pogrubienie** oraz __pogrubienie__ to pogrubienie. Dodanie znaczników ~~strike~~ to przekreślenie.

Możesz dodać formatowanie komendami , , oraz .

Ponieważ dekoracja podkreślenia jest przeznaczona na linki, markdown nie zawiera specjalnej składni dla podkreślenia. Dlatego by dodać podkreślenie, użyj <u>underline</u>.

Komendy formatujące reagują na skróty klawiszowe: Ctrl+B, Ctrl+I, Ctrl+U oraz Ctrl+S.

Linki

By dodać link w edytorze użyj komendy lub użyj składni [title](link). URL umieszczony w linku lub nawet URL umieszczony bezpośrednio w tekście będzie aktywny i klikalny.

Jeżeli chcesz, możesz samodzielnie dodać link: <a href="link">title</a>.

Wewnętrzne odnośniki

Możesz umieścić odnośnik do wewnętrznej podstrony, używając następującej składni: [[Delphi/Kompendium]] lub [[Delphi/Kompendium|kliknij, aby przejść do kompendium]]. Odnośniki mogą prowadzić do Forum 4programmers.net lub np. do Kompendium.

Wspomnienia użytkowników

By wspomnieć użytkownika forum, wpisz w formularzu znak @. Zobaczysz okienko samouzupełniające nazwy użytkowników. Samouzupełnienie dobierze odpowiedni format wspomnienia, zależnie od tego czy w nazwie użytkownika znajduje się spacja.

Znaczniki HTML

Dozwolone jest używanie niektórych znaczników HTML: <a>, <b>, <i>, <kbd>, <del>, <strong>, <dfn>, <pre>, <blockquote>, <hr/>, <sub>, <sup> oraz <img/>.

Skróty klawiszowe

Dodaj kombinację klawiszy komendą notacji klawiszy lub skrótem klawiszowym Alt+K.

Reprezentuj kombinacje klawiszowe używając taga <kbd>. Oddziel od siebie klawisze znakiem plus, np <kbd>Alt+Tab</kbd>.

Indeks górny oraz dolny

Przykład: wpisując H<sub>2</sub>O i m<sup>2</sup> otrzymasz: H2O i m2.

Składnia Tex

By precyzyjnie wyrazić działanie matematyczne, użyj składni Tex.

<tex>arcctg(x) = argtan(\frac{1}{x}) = arcsin(\frac{1}{\sqrt{1+x^2}})</tex>

Kod źródłowy

Krótkie fragmenty kodu

Wszelkie jednolinijkowe instrukcje języka programowania powinny być zawarte pomiędzy obróconymi apostrofami: `kod instrukcji` lub ``console.log(`string`);``.

Kod wielolinijkowy

Dodaj fragment kodu komendą . Fragmenty kodu zajmujące całą lub więcej linijek powinny być umieszczone w wielolinijkowym fragmencie kodu. Znaczniki ``` lub ~~~ umożliwiają kolorowanie różnych języków programowania. Możemy nadać nazwę języka programowania używając auto-uzupełnienia, kod został pokolorowany używając konkretnych ustawień kolorowania składni:

```javascript
document.write('Hello World');
```

Możesz zaznaczyć również już wklejony kod w edytorze, i użyć komendy  by zamienić go w kod. Użyj kombinacji Ctrl+`, by dodać fragment kodu bez oznaczników języka.

Tabelki

Dodaj przykładową tabelkę używając komendy . Przykładowa tabelka składa się z dwóch kolumn, nagłówka i jednego wiersza.

Wygeneruj tabelkę na podstawie szablonu. Oddziel komórki separatorem ; lub |, a następnie zaznacz szablonu.

nazwisko;dziedzina;odkrycie
Pitagoras;mathematics;Pythagorean Theorem
Albert Einstein;physics;General Relativity
Marie Curie, Pierre Curie;chemistry;Radium, Polonium

Użyj komendy by zamienić zaznaczony szablon na tabelkę Markdown.

Lista uporządkowana i nieuporządkowana

Możliwe jest tworzenie listy numerowanych oraz wypunktowanych. Wystarczy, że pierwszym znakiem linii będzie * lub - dla listy nieuporządkowanej oraz 1. dla listy uporządkowanej.

Użyj komendy by dodać listę uporządkowaną.

1. Lista numerowana
2. Lista numerowana

Użyj komendy by dodać listę nieuporządkowaną.

* Lista wypunktowana
* Lista wypunktowana
** Lista wypunktowana (drugi poziom)

Składnia Markdown

Edytor obsługuje składnię Markdown, która składa się ze znaków specjalnych. Dostępne komendy, jak formatowanie , dodanie tabelki lub fragmentu kodu są w pewnym sensie świadome otaczającej jej składni, i postarają się unikać uszkodzenia jej.

Dla przykładu, używając tylko dostępnych komend, nie możemy dodać formatowania pogrubienia do kodu wielolinijkowego, albo dodać listy do tabelki - mogłoby to doprowadzić do uszkodzenia składni.

W pewnych odosobnionych przypadkach brak nowej linii przed elementami markdown również mógłby uszkodzić składnie, dlatego edytor dodaje brakujące nowe linie. Dla przykładu, dodanie formatowania pochylenia zaraz po tabelce, mogłoby zostać błędne zinterpretowane, więc edytor doda oddzielającą nową linię pomiędzy tabelką, a pochyleniem.

Skróty klawiszowe

Skróty formatujące, kiedy w edytorze znajduje się pojedynczy kursor, wstawiają sformatowany tekst przykładowy. Jeśli w edytorze znajduje się zaznaczenie (słowo, linijka, paragraf), wtedy zaznaczenie zostaje sformatowane.

  • Ctrl+B - dodaj pogrubienie lub pogrub zaznaczenie
  • Ctrl+I - dodaj pochylenie lub pochyl zaznaczenie
  • Ctrl+U - dodaj podkreślenie lub podkreśl zaznaczenie
  • Ctrl+S - dodaj przekreślenie lub przekreśl zaznaczenie

Notacja Klawiszy

  • Alt+K - dodaj notację klawiszy

Fragment kodu bez oznacznika

  • Alt+C - dodaj pusty fragment kodu

Skróty operujące na kodzie i linijkach:

  • Alt+L - zaznaczenie całej linii
  • Alt+, Alt+ - przeniesienie linijki w której znajduje się kursor w górę/dół.
  • Tab/⌘+] - dodaj wcięcie (wcięcie w prawo)
  • Shit+Tab/⌘+[ - usunięcie wcięcia (wycięcie w lewo)

Dodawanie postów:

  • Ctrl+Enter - dodaj post
  • ⌘+Enter - dodaj post (MacOS)