Измените цвет текста H1 с помощью функции setTimeout в Javascript - PullRequest
1 голос
/ 09 апреля 2020

В моем html есть три заголовка. При загрузке страницы я хочу изменить цвет этих заголовков один за другим, и он должен начинаться снова с первого после последнего заголовка. Я пробовал установить функцию setTimeout JS, но не могу получить желаемый результат.

Он должен работать так:

  • "Текст 1" - зеленый цвет в течение 10 секунд
  • «Текст 2» - зеленый цвет на 15 секунд
  • «Текст 3» - зеленый цвет на 18 секунд

После «Текст 3» он должен снова запуститься с «Текст 1»

Ниже приведен мой код.

<body onload="startAuto()">
    <h1 id="first">Text 1</h1>
    <h1 id="second">Text 2</h1>
    <h1 id="third">Text 3</h1>
</body>

Я использовал следующее JavaScript, оно работает впервые, но когда оно достигает текста 3, оно не go назад к тексту 1.

function startAuto() {
  function first() {
    document.getElementById('first').style.color = "#32A067";
  }

  function second() {
    setTimeout(function() {
      document.getElementById('first').style.color = "#333";
      document.getElementById('second').style.color = "#32A067";
    }, 13000);
  }

  second();

  function third() {
    setTimeout(function() {
      document.getElementById('first').style.color = "#333";
      document.getElementById('second').style.color = "#333";
      document.getElementById('third').style.color = "#32A067";
    }, 26000);
  }

  third();
}

Ответы [ 4 ]

3 голосов
/ 09 апреля 2020

Спасибо за все эти ответы, но я сам нашел самое простое и чистое решение. Просто установите функцию тайм-аута в предыдущем, по кругу. Это лучше и понятнее. Ниже приведен фрагмент кода.

<body>
    <h1 id="first">Text 1</h1>
    <h1 id="second">Text 2</h1>
    <h1 id="third">Text 3</h1>
</body>


<script>
first();

function first()
{

document.getElementById('third').style.color="#333";

document.getElementById('first').style.color="#32A067";

setTimeout(second,10000);

}


function second()
{

document.getElementById('first').style.color="#333";
document.getElementById('second').style.color="#32A067";

setTimeout(third,15000);

}



function third()
{

document.getElementById('second').style.color="#333";
document.getElementById('first').style.color="#32A067";

setTimeout(first,18000);


}
</script>
2 голосов
/ 09 апреля 2020

Вы должны использовать циклический массив и тайм-аут для сна и вызвать функцию

listElements, содержащую все элементы, которые вы хотите выделить, и время их выделения

startAutoIndex будет увеличивать каждый раз, когда вызывается функция, чтобы она сначала начиналась с идентификатора элемента

var startAutoIndex = 0

function startAuto() {

    let listElements = [
        {id: "first", timer: 10000}, 
        {id: "second", timer: 13000}, 
        {id: "third", timer: 26000}
    ]

    function colorHeader(currentIndex) {
        for (let index = 0; index < listElements.length; index++) {
            const element = listElements[index]
            if (currentIndex != index)
                document.getElementById(element.id).style.color = '#333'
            else {
                document.getElementById(element.id).style.color = '#32A067'
            }
        }
    }

    let currentIndex =
        ((startAutoIndex % listElements.length) + listElements.length) %
        listElements.length

    colorHeader(currentIndex)

    setTimeout(startAuto, listElements[currentIndex].timer)

    startAutoIndex = currentIndex + 1

}
1 голос
/ 09 апреля 2020

Вы можете использовать setTimeout вместе с обещаниями для достижения желаемого результата. Посмотрите мой фрагмент:

var first = document.getElementById('first');
		var second = document.getElementById('second');
		var third = document.getElementById('third');



	const promiseTimeout = (delay, element, newColor) =>
	  {
	  	return new Promise((resolve, reject) => {
		    setTimeout(() => {
		    	
		      element.style.color = newColor;
		      resolve() // when this fires, .then gets called
		      
		    }, delay)
		  });
	  }

	function start(){

		first.style.color = "green";

		promiseTimeout(10000, first, "#333")
		.then(() => {
			return second.style.color = "green";
		})
		.then(() => {
			return promiseTimeout(15000, second, "#333")
		})
		.then(() => {
			third.style.color = "green";
			return promiseTimeout(18000, third, "#333")
		})
		.then(() => start());
	}

	start();
<h1 id="first">Text 1</h1>

<h1 id="second">Text 2</h1>

<h1 id="third">Text 3</h1>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
1 голос
/ 09 апреля 2020

Вы можете обернуть основной таймер внутри интервала, и каждое событие выделения выделяется как отдельный тайм-аут.

Я бы также добавил класс к элементам, к которым вы хотите запросить запрос, или просто выберите все h1 elements.

Вы также можете указать фиксированное время ожидания, и оно рассчитает время ожидания между элементами для вас.

window.startAuto = () => {
  start({
    selector : '.highlighter',
    timeouts : [ 1000, 2000, 1000 ], // or, for a fixed timout: 1000
    callback : (el, index, activeIndex) => {
      el.classList.toggle('active', index === activeIndex);
    }
  });
};

const defaultOptions = {
  selector : '',
  timeouts : [],
  initialDelay : 0
};

const start = (options) => {
  let opts = Object.assign({}, defaultOptions, options);
  opts.elements = Array.from(document.querySelectorAll(opts.selector));
  let interval = 0;
  if (!Array.isArray(opts.timeouts)) {
    opts.timeouts = fillArray(opts.timeouts, opts.elements.length);
  }
  interval = opts.timeouts.reduce((t, x) => t + x, 0);
  opts.timeouts = normalizeTimeouts(opts.timeouts);
  setTimeout(() => {
    update(opts);
    setInterval(update, interval, opts);
  }, opts.initialDelay);
};

const normalizeTimeouts = (timeouts) => {
  return timeouts.reduce((results, timeout, index, all) => {
    return results.concat(timeout + all.slice(0, index).reduce((t, x) => t + x, 0));
  }, [0]);
};

const update = (opts) => {
  opts.timeouts.slice(0, opts.timeouts.length -1).forEach((timeout, index) => {
    setTimeout(() => {
      opts.elements.forEach((element, i) => {
        return opts.callback.call(element, element, i, index);
      });
    }, timeout);
  })
};

const fillArray = (value, count) => new Array(count).fill(value);
.active {
  color: green;
}
<body onload="startAuto()">
  <h1 class="highlighter" id="first">Text 1</h1>
  <h1 class="highlighter" id="second">Text 2</h1>
  <h1 class="highlighter" id="third">Text 3</h1>
</body>

Вот супер-динамический; многоразовый класс.

document.addEventListener('DOMContentLoaded', () => main());

const main = () => {
  let looper = new Looper({
    selector : '.highlighter',
    timeouts : [ 1000, 2000, 1000 ], // or, for a fixed timout: 1000
    callback : (el, index, activeIndex) => {
      el.classList.toggle('active', index === activeIndex);
    },
    initialDelay : 1000,
    autoStart : true
  })
  
  document.querySelector('#stop-btn').addEventListener('click', (e) => {
    looper.stop();
  });
  
  document.querySelector('#restart-btn').addEventListener('click', (e) => {
    looper.stop();
    looper.start();
  });
}

class Looper {
  constructor(options) {
    let opts = Object.assign({}, Looper.defaultOptions, options);
    this.elements = Array.from(document.querySelectorAll(opts.selector));
    if (!Array.isArray(opts.timeouts)) {
      opts.timeouts = this.__fillArray(opts.timeouts, this.elements.length);
    }
    this.interval = opts.timeouts.reduce((t, x) => t + x, 0);
    this.timeouts = this.__normalizeTimeouts(opts.timeouts);
    this.initialDelay = opts.initialDelay;
    this.autoStart = opts.autoStart;
    this.callback = opts.callback;
    this.__startupId = null;
    this.__processId = null;
    this.__subprocessIds = this.__fillArray(null, this.elements.length);
    
    if (this.autoStart === true) this.start();
  }
  
  start() {
    if (this.callback == null) {
      throw new Error('callback function is undefined');
    }
    if (this.__processId == null) {
      this.__startupId = setTimeout(() => {
        this.__update();
        this.__processId = setInterval(() => {
          this.__update();
        }, this.interval);
      }, this.initialDelay);
    }
  }

  stop() {
    this.__subprocessIds.forEach((id, index) => {
      if (id != null) {
        clearTimeout(id);
        this.__subprocessIds[index] = null;
      }
    });
    if (this.__processId != null) {
      clearInterval(this.__processId);
      this.__processId = null;
    }
    if (this.__startupId != null) {
      clearTimeout(this.__startupId);
      this.__startupId = null;
    }
  }

  __update() {
    let self = this;
    self.timeouts.slice(0, this.timeouts.length -1).forEach((timeout, index) => {
      self.__subprocessIds[index] = setTimeout(() => {
        self.elements.forEach((element, i) => {
          return self.callback.call(element, element, i, index);
        });
      }, timeout);
    })
  }

  __normalizeTimeouts(timeouts) {
    return timeouts.reduce((results, timeout, index, all) => {
      return results.concat(timeout + all.slice(0, index).reduce((t, x) => t + x, 0));
    }, [0]);
  }

  __fillArray(value, count) {
    return new Array(count).fill(value);
  }
}

Looper.defaultOptions = {
  selector : '',
  timeouts : [],
  initialDelay : 0,
  autoStart : false
}
.active {
  color: green;
}
<div>
  <h2 class="highlighter" id="first">Text 1</h2>
  <h2 class="highlighter" id="second">Text 2</h2>
  <h2 class="highlighter" id="third">Text 3</h2>
</div>

<button id="stop-btn">Stop</button>
<button id="restart-btn">Restart</button>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...