maxgeor
@maxgeor

Как сделать что бы JS работал в нескольких блоках на сайте?

Добрый день.
Есть код JS на сайте
<div id="wrap">
   <canvas id="output"></canvas>
</div>

console.clear();

var img = document.getElementById('input');

var c = document.getElementById('output'),
    ctx = c.getContext('2d');

c.width = img.width;
c.height = img.height;

var tic, sine, sineNormalized,
    start = Date.now();
    
var params = {
  AMP: 20,
  FREQ: 0.03,
  SPEED: 4,
  VERTICAL: true
};

function update() {
  tic = (Date.now() - start) * 0.001;
}

function render() {
  ctx.clearRect(0, 0, c.width, c.height);
  for(var i = 0; i < img.height; i++) {
    if(params.VERTICAL) {
      var ofs = params.AMP * (0.5 + (Math.sin(tic * params.SPEED + (i * params.FREQ)) * 0.5));
      ctx.drawImage(img,
                  0, i, img.width, 1,
                  0, i - (ofs * 0.5), img.width, 1 + ofs);
    } else {
      var ofs = params.AMP * Math.sin(tic * params.SPEED + (i * params.FREQ));
      ctx.drawImage(img,
                  0, i, img.width, 1,
                  0 + ofs, i, img.width, 1);
    }
    
  }
}

function loop() {
  requestAnimationFrame(loop);
  update();
  render();
}

$('nav input').on('input change', function() {
  var t = $(this).attr('data-param');
  if(t == 'VERTICAL') {
    params.VERTICAL = $(this).is(':checked');
  } else {
    params[t] = $(this).val();
  }
  
});

loop();

но он срабатывает только в одном в первом блоке, а в блоках ниже он не работает.
Но если его не ставить в блок № 1 а сразу поставить в блок № 2 (который ниже) он работает.
Как сделать, что бы он работал и в первом и во втором и в третьем блоке ?
Спасибо.
  • Вопрос задан
  • 388 просмотров
Решения вопроса 2
Kiriniy
@Kiriniy
Графический и веб-дизайнер
В документе может быть только один id со значением output.
Можно попробовать поменять на класс и getElementsByClassName. Проблема в том, что getElementsByClassName работает с массивами и тут нельзя вызвать getContext напрямую, нужна обёртка forEach.

<div id="wrap">
   <canvas class="output"></canvas>
   <canvas class="output"></canvas>
   <canvas class="output"></canvas>
   <canvas class="output"></canvas>
</div>


Вот как-то так...

var img = document.getElementById('input');

var c = document.getElementsByClassName('output');

c = Array.prototype.slice.call(c);

c.forEach(function (c) {

var ctx = c.getContext('2d');

c.width = img.width;
c.height = img.height;

var tic, sine, sineNormalized,
    start = Date.now();
    
var params = {
  AMP: 20,
  FREQ: 0.03,
  SPEED: 4,
  VERTICAL: true
};

function update() {
  tic = (Date.now() - start) * 0.001;
}

function render() {
  ctx.clearRect(0, 0, c.width, c.height);
  for(var i = 0; i < img.height; i++) {
    if(params.VERTICAL) {
      var ofs = params.AMP * (0.5 + (Math.sin(tic * params.SPEED + (i * params.FREQ)) * 0.5));
      ctx.drawImage(img,
                  0, i, img.width, 1,
                  0, i - (ofs * 0.5), img.width, 1 + ofs);
    } else {
      var ofs = params.AMP * Math.sin(tic * params.SPEED + (i * params.FREQ));
      ctx.drawImage(img,
                  0, i, img.width, 1,
                  0 + ofs, i, img.width, 1);
    }
    
  }
}

function loop() {
  requestAnimationFrame(loop);
  update();
  render();
}

$('nav input').on('input change', function() {
  var t = $(this).attr('data-param');
  if(t == 'VERTICAL') {
    params.VERTICAL = $(this).is(':checked');
  } else {
    params[t] = $(this).val();
  }
  
});

loop();

});
Ответ написан
ArsenyMatytsyn
@ArsenyMatytsyn Куратор тега JavaScript
Руководитель frontend направления, предприниматель
Чтобы захватить несколько элементов на странице надо использовать селектор, который собирает все (существующие на момент работы скрипта), например через querySelectorAll('.classname').

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

Ну и как выше указали, ID это уникальный идентификатор, вместо него надо использовать одинаковый класс.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
maxgeor
@maxgeor Автор вопроса
Арсений Матыцин, т.е. мне нужно вместо
var c = document.getElementById('output'),
этот код
querySelectorAll('.output .output_2 .output_3')
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы