0

Desarrollé algo en JQuery para crear una pequeña alerta de espera, en lo que el resto de operaciones y recursos se cargaban.

En el archivo, tengo lo siguiente:

// Executes on ready, only DOM ready

jQuery(function () {
  console.log("Start DOM ready");

  popupS.alert({
    title: 'Producto',
    content: 'Cargando todo para ver tu producto',
    className: 'loading',
  });

});

// Executes when everything is fully loaded
$(window).on('load', function () {
  console.log("Start load ");

  // Algo de la lógica
  
  $.ajax({
    type: 'GET',
    url: '/get-info/' + design_id,
    success: function success(data) {
      $('.producto-relacionado-container').addClass('visible');
      $('#designer-image').css('background-image', 'url(' + data['designer_image'] + ')');
      $('#designer-name').text(data['designer_info']);
      $('#designer-name').attr('href', data['designer_route']);
      $('#title-suggested').text(data['designer_name']);
      $('#suggested-image').css('background-image', 'url(' + data['image'] + ')');
      $('#suggested-design-name').text(data['name']);
      $('#suggested-design').attr('href', data['route']);
    },
    error: function error(data) {
      console.log("Error", data);
    }
  });

});
<script src="https://code.jquery.com/jquery-3.6.0.js" integrity="sha256-H+K7U5CnXl1h5ywQfKtSj8PCmoN9aaq30gDh27Xc0jk=" crossorigin="anonymous"></script>

Este código, en mi entorno local, funciona perfectamente. Si veo las salidas de consola, veo que, efectivamente, se ejecuta primero la función ready() antes que la load(), incluso sin importar que la función load() se encuentre primero que la otra.

Lo que debería de ser lo correcto.

Pero el comportamiento es diferente cuando subo cambios a producción, y mi página está alojada en servidores de Google Cloud, es lo único diferente que existe.

Lo que sucede es que la página en producción (servidores de Google Cloud), ejecuta primero el contenido de la función load() y al final lo de la función ready().

Estuve investigando, pero no me aparece nada relacionado a este problema específico.

Lo que he intentado es reemplazar la línea de jQuery(function () { por $(document).ready(function () { lo cual no tuvo efecto alguno.

También abrí una pestaña de incógnito, borré caché y, como tengo CloudFlare, también purgué los archivos.

Pero en producción, las salidas de consola, muestran en console.log() de load() antes que la de ready().

Noob Dev
  • 925
  • 1
  • 7
  • 22
  • 1
    ¿Cuál es la versión de jQuery? – A. Cedano Jul 29 '21 at 19:07
  • Tengo importado en el head "jquery-3.6.0.js" – Noob Dev Jul 29 '21 at 20:28
  • 1
    Leí que jQuery 3 tiene un pequeño problema con esto. Prueba la forma modena ([y recomendada desde la versión 3](https://es.stackoverflow.com/q/92628/29967)) reemplazando `$(document).ready(function () {` por `$(function(){` y si aún así no se resuelve, usa la forma nativa de Javascript para la escucha de ambos eventos: `document.addEventListener('DOMContentLoaded', (event) => { console.log('A. DOM fully loaded and parsed'); });` y `window.addEventListener("load", function(event) { console.log("'B. Window cargado!"); });` – A. Cedano Jul 29 '21 at 20:35
  • No funcionó, sigue teniendo el mismo comportamiento – Noob Dev Jul 29 '21 at 23:58
  • ¿Aún con los listeners nativos de Javascript? – A. Cedano Jul 30 '21 at 01:12
  • Es correcto, con lis listeners nativos de Javascript, funciona de la misma manera – Noob Dev Jul 30 '21 at 03:36
  • 3
    En el ejemplo de tu pregunta, hasta cierto punto puede ser lógico el comportamiento obtenido, porque no hay contenido para interpretar en el DOM, por lo que el evento `load` se dispara inmediatamente. Insisto, parece "normal" porque `window` es superior a `document`. Basta con agregar una imagen en tu ejemplo para obtener el comportamiento esperado. – Triby Aug 01 '21 at 03:14
  • Dentro de ready() tengo solamente un PopupJs y dentro de load(), desencadeno varias acciones para cargar un elemento según algunos parámetros de URL, en este caso, realizo un AJAX para actualizar algunos elementos, pero es solamente ilustrativo, ya que realizo muchas operaciones – Noob Dev Aug 02 '21 at 00:58
  • Probablemente tiene que ver con el comportamiento asíncrono de JavaScript, además recuerda que llamar a una función es algo un poco costoso, para solucionar tu problema simplemente ejecútalas una después de otra en el orden deseado. Porque podría ser que en tu local primero se ejecute JQuery pero en el mío no... – Eduardo Jiménez Aug 02 '21 at 01:03

1 Answers1

0

En mi entorno de desarrollo local primero se ejecuta el log de load y después el log de ready.

El comportamiento por defecto que esperaba es que primero se debería haber ejecutado ready y después load. PERO NO FUE ASÍ

Por lo cual en mi HTML puse una imagen con el src incorrecto.

<img src="https://es.m.wikipedia.org/wiki/Archivo:Playa_Ostiones2,_Cabo_Rojo.jpg" alt="">

Refresque la página y ahora si veo el log en el orden correcto. Primero muestra el log de ready y después log de load.

Por lo cual llego a una conclusión talvez incorrecta.

El load se ejecuta primero por que no existe o carga muy rápido ya sea imágenes, iframes, etc. Por lo cual gana en rapidez al ready ya que el código HTML se interpreta de arriba hacia abajo.

En fin, la única solución que encontré es forzar a ejecutar el load dos veces para así conseguir el orden ready - load.

let readyEjecutado = false;
$(document).ready(function() {
    console.log('Start DOM ready');

    readyEjecutado = true;        
    $(window).trigger('load');
});

$(window).on('load', function() {
    if (readyEjecutado) {
        console.log('start load');

        //Algo de lógica
    }
});

El código a ejecutar sólo iría dentro del bloque if del evento load.

readyEjecutado sirve para verificar que ready se haya ejecutado y si es así pues ejecutamos el código deseado dentro del bloque if.