Я пытаюсь автоматически перебирать переключатели каждые 5 секунд через jquery; однако мне нужно, чтобы эта функция запускалась и при переключении кнопок вручную. Вот что у меня есть на данный момент:
$(document).ready(function () {
(function news() {
if ($('#pabnews_slide1').is(':checked')) {
$('#pabnews_slide2').prop('checked', true)
}
else if ($('#pabnews_slide2').is(':checked')) {
$('#pabnews_slide3').prop('checked', true)
}
else if ($('#pabnews_slide3').is(':checked')) {
$('#pabnews_slide4').prop('checked', true)
}
else if ($('#pabnews_slide4').is(':checked')) {
$('#pabnews_slide1').prop('checked', true)
}
setTimeout(news, 5000);
})();
});
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<input name = "slideshow" id = "pabnews_slide1" type = "radio" checked />
<label for = "pabnews_slide1">A</label>
<input name = "slideshow" id = "pabnews_slide2" type = "radio"/>
<label for = "pabnews_slide2">B</label>
<input name = "slideshow" id = "pabnews_slide3" type = "radio" />
<label for = "pabnews_slide3">C</label>
<input name = "slideshow" id = "pabnews_slide4" type = "radio" />
<label for = "pabnews_slide4">D</label>
это работает, но моя проблема в том, что функция вызывается каждые 5 секунд, и таймер не возвращается к 0, когда я вручную переключаю кнопки. Как бы вы это сделали?
Чтобы быть понятнее, в текущем состоянии, когда вы ждете 3 секунды и вручную переключаете кнопку, функция вызывается только через 2 секунды, и мне нужно будет сделать ее 5.
Сохраните возврат setTimeout
и передайте его clearTimeout
при нажатии, а затем начните новый setTimeout
.
@fdomn-m Извините, я новичок в JavaScript, поэтому мне нужно больше рекомендаций по этому поводу, хотя я понимаю теорию
Вот простой пример JS, хотя я добавил атрибут набора данных в ваш HTML, чтобы отслеживать количество изменяемых элементов и использовать его при выборе элемента changed
, который вы выберете. Я также провел рефакторинг функции, которая просматривает список элементов и изменяет элемент checked
.
Сначала мы получаем список входных элементов, используя тег имени.
Затем мы устанавливаем инкрементатор i
, чтобы он соответствовал набору дат и индексу каждого элемента внутри цикла.
Поскольку мы хотим отслеживать, какой элемент в данный момент выбран и на каком элементе установлен setTimeout, мы будем отслеживать это с помощью переменных currentSlide
и SelectedSlide
. Затем мы создаем экземпляр пустой переменной для отслеживания таймаута timer
.
Теперь мы запускаем логику в функции, чтобы изменить элемент, используя инкремент и список входных элементов, если i
больше, чем список элементов length
, сбрасываем i
на 0. Затем мы отслеживаем значение selectedSlide
, если оно установлено, мы установите значение i
равным dataset.id
.
Теперь имейте в виду, что selectedSlide
устанавливается внутри метода/функции setCurrentSlide(e)
, которая отслеживает изменение event.target
. Внутри этой функции мы запускаем clearTimeout(timer)
, которая очищает setTimeout()
, и повторно создаем экземпляр timer
, передаваемый в элемент selectedSlide
, чтобы мы могли получить его dataset.id
и использовать это, чтобы установить цикл на правильный элемент, с которого нужно начинать, когда мы вызываем метод/функцию changeSlide()
. .
currentSlide
устанавливается с помощью i
в списке элементов slides
=> currentSlide = slides[i]
Наконец, мы используем список элементов slides
для запуска eventListener, который прослушивает событие change
. Здесь мы вызываем метод/функцию set setCurrentSlide
, которая снова использует event.target
=> e.target
для получения dataset.id
. Затем мы устанавливаем атрибут проверенных элементов на true
.
Затем мы устанавливаем значение timer
с помощью setTimeout(), передавая функцию changeSlide
и устанавливая ее задержку.
Наконец, мы увеличиваем i
на 1, i++
.
Дайте мне знать, если что-то не имеет смысла, и я надеюсь, что это поможет. Я оставил заметки в коде, чтобы помочь понять, что делает каждая строка.
$(document).ready(function() {
// get all the slides elements
const slides = document.querySelectorAll('input[name = "slideshow"]');
// set an incrementer
let i = 0;
// instantiate empty variables
var currentSlide, selectedSlide, timer;
// method to changeEach slide to the next in line and reset to
function changeSlide(currentSlide, selectedSlide){
// ternary conditional, sets i to 0 if it has reached the last element
i > slides.length-1 ? i = 0 : null;
// ternary conditional, sets the selectedSlide if it is passed as a param
selectedSlide ? i = selectedSlide.dataset.id : null;
// set the current element to the indexed incrementer
currentSlide = slides[i];
// checks the proper element using the checked attribute
currentSlide.checked = true;
// define timer and call the changeSlide method and set delay
timer = setTimeout(changeSlide, 5000);
// increment i by 1
i++;
}
// method to set current element
// uses the eventTarget passed from the eventListener
function setCurrentSlide(e){
// clear the timeout
clearTimeout(timer);
// set the selectedSlide variable to the event.target
selectedSlide = e.target;
// run the changeSlide method again using the event.target as reference as selectedSlide param
changeSlide(currentSlide, selectedSlide);
}
// iterate over the slides elements
slides.forEach(slide => {
// event listener listens for a change and runs the setCurrentSlide method
slide.addEventListener('change', setCurrentSlide);
});
// run the changeSlide method
changeSlide(currentSlide, selectedSlide);
});
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<input name = "slideshow" id = "pabnews_slide1" data-id = "0" type = "radio" checked />
<label for = "pabnews_slide1">A</label>
<input name = "slideshow" id = "pabnews_slide2" data-id = "1" type = "radio" />
<label for = "pabnews_slide2">B</label>
<input name = "slideshow" id = "pabnews_slide3" data-id = "2" type = "radio" />
<label for = "pabnews_slide3">C</label>
<input name = "slideshow" id = "pabnews_slide4" data-id = "3" type = "radio" />
<label for = "pabnews_slide4">D</label>