He creado una página que extrae múltiples imágenes de varias cámaras web que utilizamos en la oficina para monitorear las redes de carreteras.

Queremos que las imágenes se actualicen automáticamente cada 30 segundos, pero mi JavaScript no es brillante, me temo.

Sé que puedo actualizar toda la página fácilmente, y también puedo actualizar una sola imagen. Pero múltiples imágenes de diferentes URL está resultando más difícil.

Las imágenes de la cámara son las únicas imágenes en la página, si es útil, y se muestran en HTML de la siguiente manera:

<figure class="fluid tiles">
<img src="cam/17002.php" alt="M" onerror="this.src = 'camoffline.png';" />
<figcaption class="textStyle">M20 00/1A J10-11<br /><small>Camera: 17002</small></figcaption>
</figure>
0
Chris Gunton 2 mar. 2018 a las 20:59

3 respuestas

La mejor respuesta
// get all of the images from the page
const images = document.getElementsByTagName( 'img' );

// perform this function every 30,000 ms (30 sec)
const timer = setInterval( function(){
  // go through each image and reference a custom attribute
  // 'data-source' to preserve the original image's src
  for( var i=0, x=images.length; i<x; i++ ){
    // select each image, individually
    let image = images[i];
    let source = image.getAttribute( 'data-source' );
    // if 'data-source' does not exist, create it
    if( !source ){
      source = image.src;
      image.setAttribute( 'data-source', source );
      // give 'data-source' the original image path
    }
    // Add a timestamp to the image source to help mitigate 
    // browser caching
    image.src = source + '?t=' + Date.now();
  }
}, 30000 );
img{ height: 150px; }
<img src="https://image.shutterstock.com/z/stock-photo--week-old-cocker-spaniel-puppy-630877553.jpg">

<img src="https://image.shutterstock.com/z/stock-photo--week-old-cocker-spaniel-puppy-630877553.jpg">

<img src="https://image.shutterstock.com/z/stock-photo--week-old-cocker-spaniel-puppy-630877553.jpg">

<img src="https://image.shutterstock.com/z/stock-photo--week-old-cocker-spaniel-puppy-630877553.jpg">

<img src="https://image.shutterstock.com/z/stock-photo--week-old-cocker-spaniel-puppy-630877553.jpg">

Use .getElementsByTagName ('img') para recopilar todas las imágenes que existen en su página.

Luego, en un intervalo (setInterval: código que continuará ejecutándose cada ### milisegundos) cree un bucle for que iterará a través de la colección HTML capturada con .getElementsByTagName ()

Una idea es crear un nuevo atributo en cada imagen en su página, 'fuente de datos' (los atributos de datos realmente pueden ser cualquier cosa). 'fuente de datos' mantendrá la información original para la ruta al archivo de imagen.

Luego, utilizando el valor de la ruta de la imagen original, reasigne el valor de la ruta de la imagen a la imagen, pero agregue una marca de tiempo como parámetro de consulta. Esto es para ayudar al navegador a cargar una nueva imagen (el contenido de caché de amor del navegador, donde pueden). El navegador ve image.jpeg? T = 1234 y cree que es una imagen diferente a image.jpeg? T = 1233

0
Doug 2 mar. 2018 a las 19:15

Quiero proponer una solución ligeramente modificada que use un <canvas>. Esto pintará todas sus fuentes en un contenedor de ancho fijo y, si están fuera de línea, dibuje el texto "Fuera de línea" donde debería haber estado la fuente.

Haga clic en la casilla de verificación para probar la funcionalidad fuera de línea.

const sources = [
  "https://cdn.sstatic.net/Sites/stackoverflow/img/sprites.svg",
  "https://cdn.sstatic.net/Sites/stackoverflow/img/sprites.svg"
];

function getSources(offline = false) {
  return !offline ?
    sources.map(src => `${src}?cb=${Date.now()}`) :
    sources.map(() => "");
}

function loadImage(src) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.addEventListener("load", () => resolve(img));
    img.addEventListener("error", () => reject(`Problem loading ${src}`));
    img.src = src;
  })
}

const offlineCheckbox = document.getElementsByTagName("input")[0],
  canvas = document.getElementsByTagName("canvas")[0],
  ctx = canvas.getContext("2d");

const {
  width,
  height
} = canvas;

function refresh() {
  console.log("Updating");
  getSources(offlineCheckbox.checked).forEach((source, idx, arr) => {
    const w = width / arr.length,
      dx = w * idx,
      dWidth = w * (idx + 1);

    loadImage(source)
      .then(img => {
        ctx.clearRect(dx, 0, dWidth, height);
        ctx.drawImage(img, dx, 0, dWidth, height);
      })
      .catch(err => {
        ctx.clearRect(dx, 0, dWidth, height);
        ctx.strokeText("Offline", dx, height * 0.5, dWidth);
      })
  });

  setTimeout(() => refresh(), 3 * 1000);
}

refresh();
<main>
  <div>
    <label><input type="checkbox"> Pretend to be offline</label>
  </div>
  <div>
    <canvas width="400" height="400"></canvas>
  </div>
</main>
0
zero298 2 mar. 2018 a las 18:59

Puede usar un timer para restablecer el src de la imagen cada 30 segundos:

var img = document.querySelector("img.cam");
setInterval(function(){
  // I'm appending # and a date to ensure we don't use a cached version of the file
  img.src = "https://picsum.photos/200/300/?random#" + new Date() ;
}, 2000); // number is in milliseconds
img  { width: 100px; }
<figure class="fluid tiles">
<img class="cam" src="cam/17002.php" alt="M" onerror="this.src='camoffline.png';" />
<figcaption class="textStyle">M20 00/1A J10-11<br /><small>Camera: 17002</small></figcaption>
</figure>
-2
Scott Marcus 2 mar. 2018 a las 18:09