Come aggiungere l'evento onload a un elemento div


Risposte:


233

No, non puoi. Il modo più semplice per farlo funzionare sarebbe inserire la chiamata di funzione direttamente dopo l'elemento

Esempio:

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

o - ancora meglio - proprio di fronte a </body>:

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

... quindi non impedisce il caricamento del seguente contenuto.


3
A seconda dell'uso non è meglio metterlo di fronte </body>. fe se vuoi nascondere l' <div>unico se javascript è abilitato ma evita di "lampeggiare". Il tempo di visibilità dipende dal tempo necessario al browser per caricare / analizzare tutti gli script incorporati / esterni.
mgutt

È un anti-pattern, in quanto è meglio tenere tutti i j all'interno del proprio file? C'è un modo per eseguire selettivamente js quando alcuni elementi vengono caricati nel documento?
Ryan Walton,

1
Non è un anti-pattern, ma di solito aspetti che il DOM venga caricato e poi fai tutto il materiale JS.
DanMan,

1
Lancia questo link qui per chiunque trovi questa risposta w3schools.com/tags/ev_onload.asp - Tutti gli elementi HTML che attualmente supportanoonload
Brandon Benefield

Questa risposta non è più pertinente. Eccone uno nuovo
mplungjan il

74

L' onloadevento può essere utilizzato solo su document(body)se stesso, frame, immagini e script. In altre parole, può essere collegato solo al corpo e / o a ciascuna risorsa esterna . Il div non è una risorsa esterna ed è caricato come parte del corpo, quindi l' onloadevento non si applica lì.


18
Non solo nell'elemento body, puoi usarlo anche con immagini e iframe, ad esempio, tra gli altri. w3schools.com/jsref/event_onload.asp
Joe,

2
Vale la pena notare che gli script inline NON sono risorse esterne e quindi onloadnon funzionano su nessuno <script>senza un srcattributo HTML (stavo cercando di usare questo consiglio in uno script inline e ho scoperto che non funzionava)
gog


28

evento onload supporta solo con pochi tag come quelli elencati di seguito.

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

Qui il riferimento per l' evento onload


17

Prova questo! E non usare mai il grilletto due volte su div!

È possibile definire la funzione da chiamare prima del tag div.

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

DEMO: jsfiddle


Sopra jsfiddle non ha un caricatore jQuery - e non funziona.
Arif Burhan,

@Arif Burhan Non capisco. Carico JQuery (bordo). Potresti controllare di nuovo? Vedo "Hello World" anche usando il cellulare.
Kuofp,

@Kuofp Quel violino in realtà non ha i gestori che vengono chiamati quando vengono caricati i loro elementi target. Usa solo jquery per cercare elementi che hanno un attributo (nel tuo caso onload) e quindi chiama quelle funzioni. Lo script funziona anche se si modifica l'attributo in qualcosa di diverso da onloadad esempio jsfiddle.net/mrszgbxh
Trindaz,

1
@Trindaz Exactly! Per dirla in altro modo, gli script si comportano come eventi onload. Grazie per aver lasciato un commento!
Kuofp,

10

Voglio solo aggiungere qui che se qualcuno vuole chiamare una funzione in caso di caricamento di div e non si desidera utilizzare jQuery (a causa di conflitti come nel mio caso), è sufficiente chiamare una funzione dopo tutto il codice HTML o qualsiasi altro codice che hai scritto incluso il codice funzione e semplicemente chiama una funzione.

/* 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>

Puoi aggiungere più di una funzione in questo modo? cioè alla fine del documento HTML appena prima del tag </body>? In caso affermativo, l'ordine in cui sono scritti conta?
Neo,

Sì, puoi aggiungere più di una funzione e l'ordine non avrà importanza solo in javascript (semplice).
dev_khan,

7

possiamo usare MutationObserver per risolvere il problema in modo efficiente aggiungendo un codice di esempio di seguito

<!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>

1
L'ultima volta che ho verificato gli eventi di mutazione eseguiti terribilmente.
DanMan,

7

A novembre 2019, sto cercando un modo per creare un (ipotetico) onparse EventListenerper <elements>cui non prendere onload.

L'ipotetico onparse EventListenerdeve essere in grado di ascoltare quando viene analizzato un elemento .


Terzo tentativo (e soluzione definitiva)

Sono stato abbastanza contento del Secondo tentativo di seguito, ma mi è sembrato di poter rendere il codice più breve e più semplice, creando un evento su misura:

let parseEvent = new Event('parse');

Questa è la soluzione migliore ancora.

L'esempio seguente:

  1. Crea un modello su misura parse Event
  2. Dichiara una funzione (che può essere eseguita in window.onloadqualsiasi momento) che:
    • Trova tutti gli elementi nel documento che includono l'attributo data-onparse
    • Allega parse EventListenera ciascuno di quegli elementi
    • Invia parse Eventa ciascuno di quegli elementi per eseguire ilCallback

Esempio di lavoro:

// 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>


Secondo tentativo

Il primo tentativo di seguito (basato sul @JohnWilliams'brillante Empty Image Hack ) usava un hardcoded <img />e funzionava.

Ho pensato che sarebbe stato possibile rimuovere del <img />tutto l'hardcoded e inserirlo in modo dinamico solo dopo aver rilevato, in un elemento che doveva generare un onparseevento, un attributo come:

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

Si scopre che funziona davvero molto bene.

L'esempio seguente:

  1. Trova tutti gli elementi nel documento che includono l'attributo data-onparse
  2. Genera dinamicamente un <img src />e lo aggiunge al documento, immediatamente dopo ciascuno di quegli elementi
  3. Lancia onerror EventListenerquando il motore di rendering analizza ciascuno<img src />
  4. Esegue Callback e rimuove quello generato dinamicamente <img src />dal documento

Esempio di lavoro:

// 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>


Primo tentativo

Posso costruire su @JohnWilliams' <img src>mod (in questa pagina, a partire dal 2017) - che è, finora, l'approccio migliore che abbia mai incontrato.

L'esempio seguente:

  1. Lancia onerror EventListenerquando il motore di rendering analizza<img src />
  2. Esegue il Callback e rimuove il <img src />dal documento

Esempio di lavoro:

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 />



@DavidBradshaw - Non ci crederai mai, ma penso di averlo effettivamente rotto. Vedi il secondo tentativo , nella parte superiore della risposta sopra.
Rounin,

1
@DavidBradshaw: grattalo. Ho escogitato un terzo tentativo . Questa è la soluzione definitiva.
Rounin,

Forse ridurre la risposta alla versione 3
David Bradshaw,

6

usa un iframe e nascondilo se funziona come un tag body

<!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>

6

Avevo bisogno di avere un po 'di codice di inizializzazione eseguito dopo l'inserimento di un pezzo di html (istanza del modello), e ovviamente non avevo accesso al codice che manipola il modello e modifica il DOM. La stessa idea vale per qualsiasi modifica parziale del DOM mediante l'inserimento di un elemento html, di solito a <div>.

Qualche tempo fa, ho fatto un hack con l'evento onload di uno quasi invisibile <img>contenuto in a <div>, ma ho scoperto che anche uno stile vuoto con ambito farà:

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

Aggiornamento (15 luglio 2017) - L' <style>onload non è supportato nell'ultima versione di IE. Edge lo supporta, ma alcuni utenti lo vedono come un browser diverso e si attaccano a IE. L' <img>elemento sembra funzionare meglio su tutti i browser.

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

Per ridurre al minimo l'impatto visivo e l'utilizzo delle risorse dell'immagine, utilizzare uno src integrato che lo mantenga piccolo e trasparente.

Un commento che sento di dover fare sull'uso di a <script>è quanto sia più difficile determinare quale sia <div>lo script vicino, specialmente nel modello in cui non è possibile avere un ID identico in ogni istanza generata dal modello. Ho pensato che la risposta potesse essere document.currentScript, ma questo non è universalmente supportato. Un <script>elemento non può determinare la propria posizione DOM in modo affidabile; un riferimento a "questo" indica la finestra principale e non è di alcun aiuto.

Credo che sia necessario accontentarsi di usare un <img>elemento, nonostante sia sciocco. Questo potrebbe essere un buco nel framework DOM / javascript che potrebbe utilizzare il collegamento.


3

Poiché l' onloadevento è supportato solo su alcuni elementi, è necessario utilizzare un metodo alternativo.

È possibile utilizzare un MutationObserver per questo:

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>


2

Mi piace molto la libreria YUI3 per questo genere di cose.

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

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

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


9
È una grossa quantità di JS da scaricare sulla pagina per legare un singolo onload.
meagar

1
@meagar - Giusto, anche se trovo sempre più raro che io faccia solo due o tre semplici cose JS su una pagina. Preoccuparmi della compatibilità tra browser mi fa impazzire.
mjhm,

0

Sto imparando javascript e jquery e ho passato tutte le risposte, ho riscontrato lo stesso problema quando ho chiamato la funzione javascript per caricare l'elemento div. Ho provato $('<divid>').ready(function(){alert('test'})e ha funzionato per me. Voglio sapere è questo buon modo per eseguire la chiamata onload sull'elemento div come ho fatto con il selettore jquery.

Grazie


0

Come tutto detto, non è possibile utilizzare l'evento onLoad su un DIV invece che prima del tag body.

ma nel caso tu abbia un file piè di pagina e includilo in molte pagine. è meglio verificare prima se il div desiderato è su quella pagina visualizzata, quindi il codice non viene eseguito nelle pagine che non contengono quel DIV per caricarlo più velocemente e risparmiare tempo per l'applicazione.

quindi dovrai dare a quel DIV un ID e fare:

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

0

Avevo la stessa domanda e stavo cercando di ottenere un Div per caricare uno script di scorrimento, usando onload o load. Il problema che ho riscontrato è che avrebbe sempre funzionato prima che la Div potesse aprirsi, non durante o dopo, quindi non avrebbe funzionato davvero.

Poi mi sono inventato questo come soluzione.

<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>

Ho messo il Div in uno Span e ho dato allo Span due eventi, un passaggio del mouse e un passaggio del mouse. Quindi sotto quel Div, ho inserito un link per aprire il Div e ho dato a quel link un evento per onclick. Tutti gli eventi sono uguali, per far scorrere la pagina fino alla fine della pagina. Ora quando si fa clic sul pulsante per aprire Div, la pagina salterà in parte e il Div si aprirà sopra il pulsante, causando il passaggio del mouse e gli eventi del mouse per spingere lo script verso il basso. Quindi qualsiasi movimento del mouse a quel punto spingerà lo script un'ultima volta.


0

È possibile utilizzare un intervallo per verificarlo fino a quando non si carica in questo modo: 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);

0

Prima di rispondere alla tua domanda: No, non puoi, non direttamente come volevi farlo. Potrebbe essere un po 'tardi per rispondere, ma questa è la mia soluzione, senza jQuery, javascript puro. È stato originariamente scritto per applicare una funzione di ridimensionamento alle textareas dopo che DOM è stato caricato e al keyup.

Allo stesso modo potresti usarlo per fare qualcosa con (tutti) i div o solo uno, se specificato, in questo modo:

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);
});

Se hai davvero bisogno di fare qualcosa con un div, caricato dopo il caricamento del DOM, ad esempio dopo una chiamata ajax, potresti usare un hack molto utile, che è facile da capire e lo troverai ... working-with- elementi-prima-del-dom-is-ready ... . Dice "prima che il DOM sia pronto" ma funziona brillante allo stesso modo, dopo un inserimento ajax o js-appendChild, qualunque sia il div. Ecco il codice, con alcune piccole modifiche alle mie esigenze.

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);

0

Quando carichi un po 'di html dal server e lo inserisci nell'albero del DOM puoi usarlo DOMSubtreeModifiedcomunque è deprecato - quindi puoi usare MutationObservero semplicemente rilevare nuovi contenuti all'interno della funzione loadElement direttamente in modo da non dover aspettare eventi DOM


0

È possibile allegare un listener di eventi come di seguito. Si attiverà ogni volta che il div con selettore viene #my-idcaricato completamente su DOM.

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

In questo caso EventName può essere 'load' o 'click'

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


-1

Utilizzare invece l'evento body.onload, tramite attributo ( <body onload="myFn()"> ...) o associando un evento in Javascript. Questo è estremamente comune con jQuery :

$(document).ready(function() {
    doSomething($('#myDiv'));
});

javascript puro e non jquery, verifica tag;)
KingRider

-3

Prova questo.

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

Prova anche questo. È necessario rimuovere .da oQuickReply.swap()per far funzionare la funzione.

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


Sembra funzionare, ma è semplicemente quello che alert("This is a div.");viene chiamato quando questa linea viene eseguita e il risultato (che è undefined) viene assegnato div.onload. Che è completamente inutile.
Frederic Leitenberger,

-4

Non è possibile aggiungere il caricamento dell'evento sul div, ma è possibile aggiungere onkeydown e attivare l'evento onkeydown al caricamento del documento

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

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

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.