Cómo agregar un evento de carga a un elemento div

231

¿Cómo se agrega un onloadevento a un elemento?

Puedo usar:

<div onload="oQuickReply.swap();" ></div>

¿para esto?

monkey_boys
fuente
mejor bodymejordiv
KingRider
2
divlos elementos no se "cargan".
amn
1
Ahora hay una respuesta más relevante : ¿quizás pueda revisar la aceptación?
mplungjan

Respuestas:

233

No puedes. La forma más fácil de hacerlo funcionar sería colocar la llamada a la función directamente después del elemento

Ejemplo:

...
<div id="somid">Some content</div>
<script type="text/javascript">
   oQuickReply.swap('somid');
</script>
...

o, mejor aún, justo delante de </body>:

...
<script type="text/javascript">
   oQuickReply.swap('somid');
</script>
</body>

... por lo que no bloquea la carga del siguiente contenido.

DanMan
fuente
3
Dependiendo del uso, no es mejor ponerlo delante </body>. fe si desea ocultar el <div>único si javascript está habilitado pero evite "flashear" El tiempo de visibilidad depende de cuánto tiempo necesita el navegador cargar / analizar todos los scripts en línea / externos.
mgutt
¿Es este un antipatrón, ya que es mejor mantener todos los js dentro de su propio archivo? ¿Hay alguna manera de ejecutar selectivamente js cuando ciertos elementos se cargan en el documento?
Ryan Walton
1
No es un antipatrón, pero generalmente esperas a que se cargue el DOM y luego haces todas las cosas de JS.
DanMan
1
Lanza este enlace aquí para cualquier persona que encuentre esta respuesta w3schools.com/tags/ev_onload.asp - Todos los elementos HTML que admiten actualmenteonload
Brandon Benefield
Esta respuesta ya no es relevante. Aquí hay uno nuevo
mplungjan
74

El onloadevento solo se puede usar en document(body)sí mismo, marcos, imágenes y scripts. En otras palabras, se puede conectar solo al cuerpo y / o a cada recurso externo . El div no es un recurso externo y se carga como parte del cuerpo, por lo que el onloadevento no se aplica allí.

kijin
fuente
18
No solo en el elemento del cuerpo, también puede usarlo con imágenes e iframe, por ejemplo, entre otros. w3schools.com/jsref/event_onload.asp
Joe
2
Vale la pena señalar que las secuencias de comandos en línea no son recursos externos, por lo que onloadno funciona en ninguna <script>sin un srcatributo HTML (yo estaba tratando de utilizar este consejo en una secuencia de comandos en línea y encontró que no estaba trabajando)
Gog
64

Puede activar algunos js automáticamente en un elemento IMG usando onerror, y no src.

<img src onerror='alert()'>
John Williams
fuente
44
¡Brillante! También se puede usar para activar el mecanografiado desde angular: img src (error) = "function ()" />
Brian Richardson
1
Este es un enfoque fantástico. Vea mi expansión de su solución aquí: stackoverflow.com/questions/4057236/…
Rounin el
Caniuse? Pa
Pacerier
28

El evento onload solo es compatible con algunas etiquetas como las que se enumeran a continuación.

<body>, <frame>, <iframe>, <img>, <input type="image">, <link>, <script>, <style>

Aquí la referencia para el evento de carga

Samda
fuente
17

¡Prueba esto! ¡Y nunca use el gatillo dos veces en div!

Puede definir la función para llamar antes de la etiqueta div.

$(function(){
    $('div[onload]').trigger('onload');
});

DEMO: jsfiddle

Kuofp
fuente
Por encima de jsfiddle no tiene un cargador jQuery, y no funciona.
Arif Burhan
@Arif Burhan, no lo entiendo. Cargo JQuery (borde). ¿Podrías comprobar de nuevo? Puedo ver "Hello World" incluso usando dispositivos móviles.
Kuofp
@Kuofp Ese violín en realidad no tiene controladores llamados cuando se cargan sus elementos de destino. Simplemente usa jquery para buscar elementos que tienen un atributo (en su caso onload) y luego llama a esas funciones. El script funciona incluso si cambia el atributo a algo diferente a, onloadpor ejemplo, jsfiddle.net/mrszgbxh
Trindaz
1
@Trindaz ¡Exactamente! Para decirlo de otra manera, los scripts actúan como un evento de carga. ¡Gracias por dejar un comentario!
Kuofp
10

Solo quiero agregar aquí que si alguien quiere llamar a una función en el evento de carga de div y no desea usar jQuery (debido a un conflicto como en mi caso), simplemente llame a una función después de todo el código html o cualquier otro código que haya escrito, incluido el código de función y simplemente llame a una función.

/* All Other Code*/
-----
------
/* ----At the end ---- */
<script type="text/javascript">
   function_name();
</script>

O

/* All Other Code*/
-----
------
/* ----At the end ---- */
<script type="text/javascript">
 function my_func(){
   function definition;      

  }

 my_func();
</script>
dev_khan
fuente
¿Puedes agregar más de una función de esta manera? es decir, al final del documento html justo antes de la etiqueta </body>? En caso afirmativo, ¿importa el orden en que están escritos?
Neo
Sí, puede agregar más de una función y el orden no importará es simplemente JavaScript (vainilla).
dev_khan
7

podemos usar MutationObserver para resolver el problema de manera eficiente agregando un código de muestra a continuación

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <style>
        #second{
            position: absolute;
            width: 100px;
            height: 100px;
            background-color: #a1a1a1;
        }
    </style>
</head>
<body>
<div id="first"></div>
<script>
    var callthis = function(element){
           element.setAttribute("tabIndex",0);
        element.focus();
        element.onkeydown = handler;
        function handler(){
                alert("called")
        }
    }


    var observer = new WebKitMutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            for (var i = 0; i < mutation.addedNodes.length; i++)
            if(mutation.addedNodes[i].id === "second"){
                callthis(mutation.addedNodes[i]);
            }

        })
    });
    observer.observe(document.getElementById("first"), { childList: true });


    var ele = document.createElement('div');
    ele.id = "second"

    document.getElementById("first").appendChild(ele);

</script>

</body>
</html>
usuario2364729
fuente
1
La última vez que revisé los eventos de mutación tuvieron un desempeño terrible.
DanMan
7

En noviembre de 2019, estoy buscando una manera de crear un (hipotético) onparse EventListenerpara el <elements>cual no lo tomo onload.

El (hipotético) onparse EventListenerdebe poder escuchar cuando se analiza un elemento .


Tercer intento (y solución definitiva)

Estaba bastante contento con el segundo intento a continuación, pero me sorprendió que puedo hacer que el código sea más corto y simple, creando un evento a medida:

let parseEvent = new Event('parse');

Esta es la mejor solución hasta ahora.

El siguiente ejemplo:

  1. Crea un hecho a medida parse Event
  2. Declara una función (que se puede ejecutar en window.onloado en cualquier momento) que:
    • Encuentra cualquier elemento en el documento que incluya el atributo data-onparse
    • Adjunta parse EventListenera cada uno de esos elementos
    • Distribuye el parse Eventa cada uno de esos elementos para ejecutar elCallback

Ejemplo de trabajo

// Create (homemade) parse event
let parseEvent = new Event('parse');

// Create Initialising Function which can be run at any time
const initialiseParseableElements = () => {

  // Get all the elements which need to respond to an onparse event
  let elementsWithParseEventListener = document.querySelectorAll('[data-onparse]');
  
  // Attach Event Listeners and Dispatch Events
  elementsWithParseEventListener.forEach((elementWithParseEventListener) => {

    elementWithParseEventListener.addEventListener('parse', updateParseEventTarget, false);
    elementWithParseEventListener.dataset.onparsed = elementWithParseEventListener.dataset.onparse;
    elementWithParseEventListener.removeAttribute('data-onparse');
    elementWithParseEventListener.dispatchEvent(parseEvent);
  });
}

// Callback function for the Parse Event Listener
const updateParseEventTarget = (e) => {
  
  switch (e.target.dataset.onparsed) {

    case ('update-1') : e.target.textContent = 'My First Updated Heading'; break;
    case ('update-2') : e.target.textContent = 'My Second Updated Heading'; break;
    case ('update-3') : e.target.textContent = 'My Third Updated Heading'; break;
    case ('run-oQuickReply.swap()') : e.target.innerHTML = 'This <code>&lt;div&gt;</code> is now loaded and the function <code>oQuickReply.swap()</code> will run...'; break;
  }
}

// Run Initialising Function
initialiseParseableElements();

let dynamicHeading = document.createElement('h3');
dynamicHeading.textContent = 'Heading Text';
dynamicHeading.dataset.onparse = 'update-3';

setTimeout(() => {

  // Add new element to page after time delay
  document.body.appendChild(dynamicHeading);

  // Re-run Initialising Function
  initialiseParseableElements();

}, 3000);
div {
  width: 300px;
  height: 40px;
  padding: 12px;
  border: 1px solid rgb(191, 191, 191);
}

h3 {
position: absolute;
top: 0;
right: 0;
}
<h2 data-onparse="update-1">My Heading</h2>
<h2 data-onparse="update-2">My Heading</h2>
<div data-onparse="run-oQuickReply.swap()">
This div hasn't yet loaded and nothing will happen.
</div>


Segundo intento

El primer intento a continuación (basado en @JohnWilliams'brillante truco de imagen vacía ) usó un código rígido<img /> y funcionó.

Pensé que debería ser posible eliminar por <img />completo el código rígido y solo insertarlo dinámicamente después de detectar, en un elemento que necesitaba disparar un onparseevento, un atributo como:

data-onparse="run-oQuickReply.swap()"

Resulta que esto funciona muy bien.

El siguiente ejemplo:

  1. Encuentra cualquier elemento en el documento que incluya el atributo data-onparse
  2. Genera <img src />y agrega dinámicamente al documento, inmediatamente después de cada uno de esos elementos
  3. Dispara onerror EventListenercuando el motor de renderizado analiza cada<img src />
  4. Ejecuta Callback y elimina dinámicamente <img src />el documento generado.

Ejemplo de trabajo

// Get all the elements which need to respond to an onparse event
let elementsWithParseEventListener = document.querySelectorAll('[data-onparse]');

// Dynamically create and position an empty <img> after each of those elements 
elementsWithParseEventListener.forEach((elementWithParseEventListener) => {

  let emptyImage = document.createElement('img');
  emptyImage.src = '';
  elementWithParseEventListener.parentNode.insertBefore(emptyImage, elementWithParseEventListener.nextElementSibling);
});

// Get all the empty images
let parseEventTriggers = document.querySelectorAll('img[src=""]');

// Callback function for the EventListener below
const updateParseEventTarget = (e) => {

  let parseEventTarget = e.target.previousElementSibling;
  
  switch (parseEventTarget.dataset.onparse) {

    case ('update-1') : parseEventTarget.textContent = 'My First Updated Heading'; break;
    case ('update-2') : parseEventTarget.textContent = 'My Second Updated Heading'; break;
    case ('run-oQuickReply.swap()') : parseEventTarget.innerHTML = 'This <code>&lt;div&gt;</code> is now loaded and the function <code>oQuickReply.swap()</code> will run...'; break;
  }
  
  // Remove empty image
  e.target.remove();
}

// Add onerror EventListener to all the empty images
parseEventTriggers.forEach((parseEventTrigger) => {
  
  parseEventTrigger.addEventListener('error', updateParseEventTarget, false);
  
});
div {
  width: 300px;
  height: 40px;
  padding: 12px;
  border: 1px solid rgb(191, 191, 191);
}
<h2 data-onparse="update-1">My Heading</h2>
<h2 data-onparse="update-2">My Heading</h2>
<div data-onparse="run-oQuickReply.swap()">
This div hasn't yet loaded and nothing will happen.
</div>


Primer intento

Puedo construir sobre @JohnWilliams' <img src>hackear (en esta página, desde 2017), que es, hasta ahora, el mejor enfoque que he encontrado.

El siguiente ejemplo:

  1. Se activa onerror EventListenercuando el motor de renderizado analiza<img src />
  2. Ejecuta Callback y elimina el <img src />del documento.

Ejemplo de trabajo

let myHeadingLoadEventTrigger = document.getElementById('my-heading-load-event-trigger');

const updateHeading = (e) => {

  let myHeading = e.target.previousElementSibling;
  
  if (true) { // <= CONDITION HERE
    
    myHeading.textContent = 'My Updated Heading';
  }
  
  // Modern alternative to document.body.removeChild(e.target);
  e.target.remove();
}

myHeadingLoadEventTrigger.addEventListener('error', updateHeading, false);
<h2>My Heading</h2>
<img id="my-heading-load-event-trigger" src />

Rounin
fuente
@DavidBradshaw: nunca lo creerás, pero creo que en realidad lo he descifrado. Vea el Segundo intento , en la parte superior de la respuesta anterior.
Rounin el
1
@DavidBradshaw - Rasca eso. Se me ocurrió un tercer intento . Esta es la solución definitiva.
Rounin el
Tal vez reduzca la respuesta a la versión 3
David Bradshaw
6

use un iframe y escóndelo iframe funciona como una etiqueta de cuerpo

<!DOCTYPE html>
<html>
<body>

<iframe style="display:none" onload="myFunction()" src="http://www.w3schools.com"></iframe>
<p id="demo"></p>

<script>
function myFunction() {
    document.getElementById("demo").innerHTML = "Iframe is loaded.";
}
</script>

</body>
</html>
dota2pro
fuente
6

Necesitaba ejecutar un código de inicialización después de insertar un fragmento de html (instancia de plantilla) y, por supuesto, no tenía acceso al código que manipula la plantilla y modifica el DOM. La misma idea es válida para cualquier modificación parcial del DOM mediante la inserción de un elemento html, generalmente un<div> .

Hace algún tiempo, hice un truco con el evento de carga de un elemento casi invisible <img>contenido en un <div>, pero descubrí que un estilo vacío y con alcance también funcionaría:

<div .... >
<style scoped="scoped" onload="dosomethingto(this.parentElement);" >   </style>
.....
</div>

Actualización (15 de julio de 2017): la <style>carga no es compatible con la última versión de IE. Edge lo admite, pero algunos usuarios lo ven como un navegador diferente y se adhieren a IE. El <img>elemento parece funcionar mejor en todos los navegadores.

<div...>
<img onLoad="dosomthing(this.parentElement);" src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAOw==" />
...
</div>

Para minimizar el impacto visual y el uso de recursos de la imagen, use un src en línea que la mantenga pequeña y transparente.

Un comentario que creo que necesito hacer sobre el uso de a <script>es cuánto más difícil es determinar qué <div>secuencia de comandos está cerca, especialmente al crear plantillas donde no se puede tener una identificación idéntica en cada instancia que genera la plantilla. Pensé que la respuesta podría ser document.currentScript, pero esto no es universalmente compatible. Un <script>elemento no puede determinar su propia ubicación DOM de manera confiable; una referencia a 'esto' apunta a la ventana principal y no sirve de nada.

Creo que es necesario conformarse con usar un <img>elemento, a pesar de ser tonto. Esto podría ser un agujero en el marco DOM / javascript que podría usar la conexión.

Floyd Kosch
fuente
3

Dado que el onloadevento solo se admite en unos pocos elementos, debe utilizar un método alternativo.

Puede usar un MutationObserver para esto:

const trackElement = element => {
  let present = false;
  const checkIfPresent = () => {
    if (document.body.contains(element)) {
      if (!present) {
        console.log('in DOM:', element);
      }
      present = true;
    } else if (present) {
      present = false;
      console.log('Not in DOM');
    }
  };

  const observer = new MutationObserver(checkIfPresent);
  observer.observe(document.body, { childList: true });
  checkIfPresent();

  return observer;
};

const element = document.querySelector('#element');
const add = () => document.body.appendChild(element);
const remove = () => element.remove();

trackElement(element);
<button onclick="add()">Add</button>
<button onclick="remove()">Remove</button>

<div id="element">Element</div>

jo_va
fuente
2

Realmente me gusta la biblioteca YUI3 para este tipo de cosas.

<div id="mydiv"> ... </div>

<script>
YUI().use('node-base', function(Y) {
  Y.on("available", someFunction, '#mydiv')
})

Ver: http://developer.yahoo.com/yui/3/event/#onavailable

mjhm
fuente
99
Esa es una gran cantidad de JS para volcar en la página con el fin de vincular una sola onload.
Meagar
1
@meagar - Correcto, aunque me parece cada vez más raro que solo haga dos o tres cosas simples de JS en una página. Preocuparme por la compatibilidad entre navegadores también me vuelve loco.
mjhm
0

Estoy aprendiendo javascript y jquery y estaba revisando toda la respuesta, me enfrenté al mismo problema al llamar a la función javascript para cargar el elemento div. Lo intenté$('<divid>').ready(function(){alert('test'}) y funcionó para mí. Quiero saber si esta es una buena forma de realizar una llamada de carga en el elemento div de la forma en que lo hice con jquery selector.

Gracias

subro
fuente
0

Como todos decimos, no puedes usar el evento onLoad en un DIV sino antes que la etiqueta del cuerpo.

pero en caso de que tenga un archivo de pie de página e inclúyalo en muchas páginas. es mejor verificar primero si se muestra el div que desea en esa página, para que el código no se ejecute en las páginas que no contienen ese DIV para que se cargue más rápido y ahorre algo de tiempo para su aplicación.

entonces deberá darle una identificación a ese DIV y hacer:

var myElem = document.getElementById('myElementId');
if (myElem !== null){ put your code here}
Mostafa Yousef
fuente
0

Tenía la misma pregunta y estaba tratando de obtener un Div para cargar un script de desplazamiento, usando onload o load. El problema que encontré fue que siempre funcionaría antes de que el Div pudiera abrirse, no durante o después, por lo que realmente no funcionaría.

Entonces se me ocurrió esto como una solución.

<body>

<span onmouseover="window.scrollTo(0, document.body.scrollHeight);" 
onmouseout="window.scrollTo(0, document.body.scrollHeight);">

<div id="">
</div>

<a href="" onclick="window.scrollTo(0, document.body.scrollHeight);">Link to open Div</a>

</span>
</body>

Puse el Div dentro de un Span y le di dos eventos, un mouseover y un mouseout. Luego, debajo de ese Div, coloqué un enlace para abrir el Div, y le di a ese enlace un evento para onclick. Todos los eventos son exactamente iguales, para que la página se desplace hacia abajo hasta la parte inferior de la página. Ahora, cuando se hace clic en el botón para abrir el Div, la página saltará hacia abajo en parte, y el Div se abrirá sobre el botón, haciendo que los eventos de mouseover y mouseout ayuden a empujar el script de desplazamiento hacia abajo. Luego, cualquier movimiento del mouse en ese punto empujará el script por última vez.

Selectivo
fuente
0

Puede usar un intervalo para verificarlo hasta que se cargue de esta manera: https://codepen.io/pager/pen/MBgGGM

let checkonloadDoSomething = setInterval(() => {
  let onloadDoSomething = document.getElementById("onloadDoSomething");
  if (onloadDoSomething) {
    onloadDoSomething.innerHTML="Loaded"
    clearInterval(checkonloadDoSomething);
  } else {`enter code here`
    console.log("Waiting for onloadDoSomething to load");
  }
}, 100);
Robert Page
fuente
0

Primero para responder a su pregunta: No, no puede, no directamente como quería hacerlo. Puede ser un poco tarde para responder, pero esta es mi solución, sin jQuery, javascript puro. Originalmente se escribió para aplicar una función de cambio de tamaño a áreas de texto después de que se carga DOM y en el keyup.

De la misma manera que podría usarlo para hacer algo con (todos) divs o solo uno, si se especifica, así:

document.addEventListener("DOMContentLoaded", function() {
    var divs = document.querySelectorAll('div'); // all divs
    var mydiv = document.getElementById('myDiv'); // only div#myDiv
    divs.forEach( div => {
        do_something_with_all_divs(div);
    });
    do_something_with_mydiv(mydiv);
});

Si realmente necesita hacer algo con un div, cargado después de cargar el DOM, por ejemplo, después de una llamada ajax, puede usar un truco muy útil, que es fácil de entender y lo encontrará ... trabajando con ... elements-before-the-dom-is-ready ... . Dice "antes de que el DOM esté listo", pero funciona de la misma manera, después de una inserción ajax o js-appendChild-lo que sea de un div. Aquí está el código, con algunos pequeños cambios a mis necesidades.

css

.loaded { // I use only class loaded instead of a nodename
    animation-name: nodeReady;
    animation-duration: 0.001s;
}

@keyframes nodeReady {  
    from { clip: rect(1px, auto, auto, auto); }
    to { clip: rect(0px, auto, auto, auto); }  
}

javascript

document.addEventListener("animationstart", function(event) {
    var e = event || window.event;
    if (e.animationName == "nodeReady") {
        e.target.classList.remove('loaded');
        do_something_else();
    }
}, false);
ddlab
fuente
0

Cuando carga algo de HTML desde el servidor e lo inserta en el árbol DOM, puede usarlo, DOMSubtreeModifiedsin embargo, está en desuso, por lo que puede usar MutationObservero simplemente detectar contenido nuevo dentro de la función loadElement directamente, por lo que no tendrá que esperar los eventos DOM

Kamil Kiełczewski
fuente
0

Puede adjuntar un detector de eventos como se muestra a continuación. Se disparará cada vez que el div que tiene un selector se #my-idcargue completamente en DOM.

$(document).on('EventName', '#my-id', function() {
 // do something
});

En este caso, EventName puede ser 'cargar' o 'hacer clic'

https://api.jquery.com/on/#on-events-selector-data-handler

SkyRar
fuente
-1

Utilice el evento body.onload en su lugar, ya sea mediante el atributo ( <body onload="myFn()"> ...) o vinculando un evento en Javascript. Esto es extremadamente común con jQuery :

$(document).ready(function() {
    doSomething($('#myDiv'));
});
mway
fuente
javascript puro y no jquery, etiqueta de verificación;)
KingRider
-3

Prueba esto.

document.getElementById("div").onload = alert("This is a div.");
<div id="div">Hello World</div>

Prueba este también. Debe eliminar .de oQuickReply.swap()para que la función funcione.

document.getElementById("div").onload = oQuickReplyswap();
function oQuickReplyswap() {
alert("Hello World");
}
<div id="div"></div>


fuente
Parece funcionar, pero simplemente alert("This is a div.");se llama cuando se ejecuta esta línea y undefinedse asigna el resultado (que es ) div.onload. Lo cual es completamente inútil.
Frederic Leitenberger
-4

No puede agregar la carga de eventos en div, pero puede agregar onkeydown y activar el evento onkeydown en la carga de documentos

$(function ()
{
  $(".ccsdvCotentPS").trigger("onkeydown");
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.2.3/jquery.min.js"></script>

<div  onkeydown="setCss( );"> </div>`

Muhammad Bilal
fuente