Comment ajouter un événement onload à un élément div

232

Comment ajoutez-vous un onloadévénement à un élément?

Puis-je utiliser:

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

pour ça?

monkey_boys
la source
mieux bodymieuxdiv
KingRider
2
divles éléments ne se "chargent" pas.
amn
1
Il y a une réponse plus pertinente maintenant - peut-être pouvez-vous réviser l'accepter?
mplungjan

Réponses:

233

Non, tu ne peux pas. Le moyen le plus simple de le faire fonctionner serait de placer l'appel de fonction directement après l'élément

Exemple:

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

ou - encore mieux - juste devant </body>:

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

... pour ne pas empêcher le chargement du contenu suivant.

DanMan
la source
3
Selon l'usage, il n'est pas préférable de le mettre devant </body>. fe si vous voulez masquer le <div>seul si javascript est activé mais évitez de "flasher". Le temps de visibilité dépend du temps dont le navigateur a besoin pour charger / analyser tous les scripts en ligne / externes.
mgutt
Est-ce un anti-pattern, en ce sens qu'il vaut mieux garder tous les js dans son propre fichier? Existe-t-il un moyen d'exécuter js de manière sélective lorsque certains éléments sont chargés dans le document?
Ryan Walton
1
Ce n'est pas un anti-modèle, mais vous attendez généralement que le DOM soit chargé, puis faites toutes les choses JS.
DanMan
1
Jetez ce lien ici pour quiconque rencontre cette réponse w3schools.com/tags/ev_onload.asp - Tous les éléments HTML qui prennent actuellement en chargeonload
Brandon Benefield
Cette réponse n'est plus d'actualité. En voici une nouvelle
mplungjan
74

L' onloadévénement ne peut être utilisé que sur document(body)lui - même, les cadres, les images et les scripts. En d'autres termes, il ne peut être attaché qu'à un corps et / ou à chaque ressource externe . Le div n'est pas une ressource externe et il est chargé en tant que partie du corps, donc l' onloadévénement ne s'y applique pas.

kijin
la source
18
Non seulement dans l'élément body, vous pouvez également l'utiliser avec image et iframe par exemple, entre autres. w3schools.com/jsref/event_onload.asp
Joe
2
Il convient de noter que les scripts en ligne ne sont PAS des ressources externes et onloadne fonctionnent donc sur aucun <script>sans srcattribut HTML (j'essayais d'utiliser ces conseils dans un script en ligne, et j'ai constaté que cela ne fonctionnait pas)
gog
64

Vous pouvez déclencher certains js automatiquement sur un élément IMG en utilisant onerror, et pas de src.

<img src onerror='alert()'>
John Williams
la source
4
Brillant! Peut également être utilisé pour déclencher une frappe à partir d'angular: img src (error) = "function ()" />
Brian Richardson
1
C'est une approche fantastique. Veuillez voir mon expansion de votre solution ici: stackoverflow.com/questions/4057236/…
Rounin
Caniuse? ͏͏͏͏͏͏͏
Pacerier
28

événement onload qu'il ne prend en charge qu'avec quelques balises comme celles répertoriées ci-dessous.

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

Voici la référence pour l'événement onload

Samda
la source
17

Essaye ça! Et n'utilisez jamais le déclencheur deux fois sur div!

Vous pouvez définir la fonction à appeler avant la balise div.

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

DÉMO: jsfiddle

Kuofp
la source
Ci-dessus, jsfiddle n'a pas de chargeur jQuery - et ne fonctionne pas.
Arif Burhan
@Arif Burhan Je ne comprends pas. Je charge JQuery (edge). Pourriez-vous vérifier à nouveau? Je peux voir "Hello World" même en utilisant un mobile.
Kuofp
@Kuofp Ce violon n'a pas réellement de gestionnaires appelés lorsque leurs éléments cibles sont chargés. Il utilise simplement jquery pour rechercher des éléments qui ont un attribut (dans votre cas onload), puis appelle ces fonctions. Le script fonctionne même si vous changez l'attribut en autre chose que onloadpar exemple jsfiddle.net/mrszgbxh
Trindaz
1
@Trindaz Exactement! En d'autres termes, les scripts agissent comme un événement onload. Merci d'avoir laissé un commentaire!
Kuofp
10

Je veux juste ajouter ici que si quelqu'un veut appeler une fonction lors de l'événement de chargement de div et que vous ne voulez pas utiliser jQuery (en raison d'un conflit comme dans mon cas), alors appelez simplement une fonction après tout le code html ou tout tout autre code que vous avez écrit, y compris le code de fonction et appelez simplement une fonction.

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

OU

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

  }

 my_func();
</script>
dev_khan
la source
Pouvez-vous ajouter plus d'une fonction de cette façon? c'est-à-dire à la fin du document html juste avant la balise </body>? Si oui, l'ordre dans lequel ils sont écrits est-il important?
Neo
Oui, vous pouvez ajouter plus d'une fonction et la commande n'aura pas d'importance son javascript tout simplement (vanille).
dev_khan
7

nous pouvons utiliser MutationObserver pour résoudre le problème de manière efficace en ajoutant un exemple de code ci-dessous

<!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>
user2364729
la source
1
La dernière fois que j'ai vérifié que les événements de mutation se sont déroulés terriblement.
DanMan
7

En novembre 2019, je cherche un moyen de créer un (hypothétique) onparse EventListenerpour <elements>lequel ne tient pas onload.

(Hypothétique) onparse EventListenerdoit être capable d'écouter lorsqu'un élément est analysé .


Troisième tentative (et solution définitive)

J'étais assez satisfait de la deuxième tentative ci-dessous, mais il m'a juste semblé que je pouvais rendre le code plus court et plus simple, en créant un événement sur mesure:

let parseEvent = new Event('parse');

C'est encore la meilleure solution.

L'exemple ci-dessous:

  1. Crée un sur-mesure parse Event
  2. Déclare une fonction (qui peut être exécutée à window.onloadtout moment ou à tout moment) qui:
    • Recherche tous les éléments du document qui incluent l'attribut data-onparse
    • Attache le parse EventListenerà chacun de ces éléments
    • Envoie le parse Eventà chacun de ces éléments pour exécuter leCallback

Exemple de travail:

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


Deuxième essai

La première tentative ci-dessous (basée sur @JohnWilliams«brillant Empty Image Hack ) a utilisé un code dur <img />et a fonctionné.

J'ai pensé qu'il devrait être possible de supprimer <img />entièrement le code dur et de ne l'insérer dynamiquement qu'après avoir détecté, dans un élément qui devait déclencher un onparseévénement, un attribut comme:

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

Il s'avère que cela fonctionne très bien.

L'exemple ci-dessous:

  1. Recherche tous les éléments du document qui incluent l'attribut data-onparse
  2. Génère dynamiquement un <img src />et l'ajoute au document, immédiatement après chacun de ces éléments
  3. Se déclenche onerror EventListenerlorsque le moteur de rendu analyse chaque<img src />
  4. Exécute Callback et supprime celui généré dynamiquement à <img src />partir du document

Exemple de travail:

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


Premier essai

Je peux construire sur @JohnWilliams' <img src>hack (sur cette page, à partir de 2017) - qui est, jusqu'à présent, la meilleure approche que j'ai rencontrée.

L'exemple ci-dessous:

  1. Se déclenche onerror EventListenerlorsque le moteur de rendu analyse<img src />
  2. Exécute Callback et supprime le <img src />du document

Exemple de travail:

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
la source
@DavidBradshaw - Vous ne le croirez jamais, mais je pense que je l' ai vraiment craqué. Voir la deuxième tentative , en haut de la réponse ci-dessus.
Rounin
1
@DavidBradshaw - Grattez ça. J'ai trouvé une troisième tentative . Telle est la solution définitive.
Rounin
Peut-être couper la réponse à la version 3
David Bradshaw
6

utiliser un iframe et le cacher iframe fonctionne comme une balise 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>
dota2pro
la source
6

J'avais besoin d'exécuter du code d'initialisation après l'insertion d'un morceau de code HTML (instance de modèle), et bien sûr, je n'avais pas accès au code qui manipule le modèle et modifie le DOM. La même idée vaut pour toute modification partielle du DOM par l'insertion d'un élément html, généralement a <div>.

Il y a quelque temps, j'ai fait un hack avec l'événement onload d'un <img>contenu presque invisible contenu dans un <div>, mais j'ai découvert qu'un style vide et de portée fera également l'affaire:

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

Mise à jour (15 juillet 2017) - La <style>surcharge n'est pas prise en charge dans la dernière version d'IE. Edge le prend en charge, mais certains utilisateurs le voient comme un navigateur différent et s'en tiennent à IE. L' <img>élément semble mieux fonctionner sur tous les navigateurs.

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

Pour minimiser l'impact visuel et l'utilisation des ressources de l'image, utilisez un src en ligne qui la garde petite et transparente.

Un commentaire que je pense avoir besoin de faire à propos de l'utilisation de <script>est combien il est difficile de déterminer de quel <div>script est proche, en particulier dans les modèles où vous ne pouvez pas avoir un identifiant identique dans chaque instance que le modèle génère. Je pensais que la réponse pourrait être document.currentScript, mais ce n'est pas universellement pris en charge. Un <script>élément ne peut pas déterminer son propre emplacement DOM de manière fiable; une référence à «ceci» pointe vers la fenêtre principale et n'est d'aucune utilité.

Je crois qu'il est nécessaire de se contenter d'utiliser un <img>élément, même s'il est maladroit. Cela pourrait être un trou dans le cadre DOM / javascript qui pourrait utiliser le branchement.

Floyd Kosch
la source
3

Étant donné que l' onloadévénement n'est pris en charge que sur quelques éléments, vous devez utiliser une autre méthode.

Vous pouvez utiliser un MutationObserver pour cela:

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
la source
2

J'aime vraiment la bibliothèque YUI3 pour ce genre de choses.

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

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

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

mjhm
la source
9
C'est un assez gros blob de JS à vider sur la page pour lier un seul onload.
meagar
1
@meagar - D'accord, même si je trouve de plus en plus rare que je fasse juste deux ou trois choses JS simples sur une page. M'inquiéter de la compatibilité entre navigateurs me rend également fou.
mjhm
0

J'apprends javascript et jquery et passais par toutes les réponses, j'ai rencontré le même problème lors de l'appel de la fonction javascript pour charger l'élément div. J'ai essayé $('<divid>').ready(function(){alert('test'})et cela a fonctionné pour moi. Je veux savoir est cette bonne façon d'effectuer l'appel onload sur l'élément div de la même manière que j'ai utilisé le sélecteur jquery.

Merci

subro
la source
0

Comme cela a été dit, vous ne pouvez pas utiliser à la place un événement onLoad sur un DIV mais avant la balise body.

mais dans le cas où vous avez un fichier de pied de page et que vous l'incluez dans plusieurs pages. il est préférable de vérifier d'abord si le div que vous voulez est sur cette page affichée, afin que le code ne soit pas exécuté dans les pages qui ne contiennent pas ce DIV pour le charger plus rapidement et gagner du temps pour votre application.

vous devrez donc donner un ID à cette DIV et faire:

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

J'avais la même question et essayais d'obtenir un Div pour charger un script de défilement, en utilisant onload ou load. Le problème que j'ai trouvé était que cela fonctionnerait toujours avant que la Div ne puisse s'ouvrir, pas pendant ou après, donc ça ne marcherait pas vraiment.

Ensuite, j'ai trouvé cela en guise de solution.

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

J'ai placé la Div à l'intérieur d'un Span et ai donné au Span deux événements, un survol et un déplacement. Ensuite, en dessous de cette Div, j'ai placé un lien pour ouvrir la Div et j'ai donné à ce lien un événement pour onclick. Tous les événements sont identiques, pour faire défiler la page vers le bas de la page. Maintenant, lorsque le bouton pour ouvrir le Div est cliqué, la page sautera à mi-chemin et le Div s'ouvrira au-dessus du bouton, provoquant les événements mouseover et mouseout pour aider à pousser le script de défilement vers le bas. Ensuite, tout mouvement de la souris à ce point poussera le script une dernière fois.

Sélectif
la source
0

Vous pouvez utiliser un intervalle pour le vérifier jusqu'à ce qu'il se charge comme ceci: 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
la source
0

D'abord pour répondre à votre question: non, vous ne pouvez pas, pas directement comme vous le vouliez. Peut-être un peu tard pour répondre, mais c'est ma solution, sans jQuery, pur javascript. Il a été écrit à l'origine pour appliquer une fonction de redimensionnement aux zones de texte après le chargement du DOM et à la clé.

De la même manière, vous pouvez l'utiliser pour faire quelque chose avec (toutes) les divs ou une seule, si spécifié, comme ceci:

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 vous avez vraiment besoin de faire quelque chose avec un div, chargé après le chargement du DOM, par exemple après un appel ajax, vous pouvez utiliser un hack très utile, qui est facile à comprendre et vous le trouverez ... working-with- éléments avant-le-dom-est prêt ... . Il dit "avant que le DOM ne soit prêt" mais il fonctionne de la même manière, après une insertion ajax ou js-appendChild-quoi que ce soit d'un div. Voici le code, avec quelques petits changements à mes besoins.

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
la source
0

Lorsque vous chargez du code HTML à partir du serveur et l'insérez dans l'arborescence DOM, vous pouvez l'utiliser DOMSubtreeModifiedcomme il est obsolète - vous pouvez donc utiliser MutationObserverou simplement détecter directement le nouveau contenu dans la fonction loadElement afin que vous n'ayez pas besoin d'attendre les événements DOM

Kamil Kiełczewski
la source
0

Vous pouvez joindre un écouteur d'événements comme ci-dessous. Il se déclenchera chaque fois que le div ayant le sélecteur se #my-idcharge complètement dans DOM.

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

Dans ce cas, EventName peut être «charger» ou «cliquer»

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

SkyRar
la source
-1

Utilisez plutôt l'événement body.onload, soit via l'attribut ( <body onload="myFn()"> ...), soit en liant un événement en Javascript. Ceci est extrêmement courant avec jQuery :

$(document).ready(function() {
    doSomething($('#myDiv'));
});
mway
la source
javascript pur et non jquery, coche;)
KingRider
-3

Essaye ça.

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

Essayez celui-ci aussi. Vous devez supprimer .de oQuickReply.swap()pour que la fonction fonctionne.

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


la source
Cela semble fonctionner, mais il est simplement alert("This is a div.");appelé lorsque cette ligne est exécutée et que le résultat (qui est undefined) est affecté à div.onload. Ce qui est complètement inutile.
Frederic Leitenberger
-4

Vous ne pouvez pas ajouter d'événement onload sur div, mais vous pouvez ajouter onkeydown et déclencher un événement onkeydown lors du chargement du document

$(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
la source