Como adicionar um evento onload a um elemento div

231

Como você adiciona um onloadevento a um elemento?

Eu posso usar:

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

por esta?

monkey_boys
fonte
melhor bodymelhordiv
KingRider 23/03
2
divelementos não "carregam".
amn
1
Existe uma resposta mais relevante agora - talvez você possa revisar a aceitação?
mplungjan

Respostas:

233

Não, você não pode. A maneira mais fácil de fazê-lo funcionar seria colocar a chamada de função diretamente após o elemento

Exemplo:

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

ou - melhor ainda - bem na frente de </body>:

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

... para que não impeça o carregamento do seguinte conteúdo.

DanMan
fonte
3
Dependendo do uso, não é melhor colocá-lo na frente </body>. fe se você quiser ocultar <div>apenas se o javascript estiver ativado, mas evite "piscar". O tempo de visibilidade depende de quanto tempo o navegador precisa carregar / analisar todos os scripts embutidos / externos.
mgutt
Isso é um antipadrão, pois é melhor manter todos os js dentro de seu próprio arquivo? Existe uma maneira de executar seletivamente js quando certos elementos são carregados no documento?
Ryan Walton
1
Não é um anti-padrão, mas você normalmente espera que o DOM seja carregado e depois faz todo o material JS.
18715 DanMan
1
Jogue este link aqui para qualquer pessoa que se depare com esta resposta w3schools.com/tags/ev_onload.asp - Todos os elementos HTML atualmente suportadosonload
Brandon Benefield
Esta resposta não é mais relevante. Aqui está um novo
mplungjan 13/11/19
74

O onloadevento pode ser usado apenas em document(body)si mesmo, quadros, imagens e scripts. Em outras palavras, ele pode ser anexado apenas ao corpo e / ou a cada recurso externo . O div não é um recurso externo e é carregado como parte do corpo, portanto, o onloadevento não se aplica a ele.

kijin
fonte
18
Não apenas no elemento body, você pode usá-lo também com imagem e iframe, por exemplo, entre outros. w3schools.com/jsref/event_onload.asp
Joe
2
Vale ressaltar que os scripts embutidos NÃO são recursos externos e, portanto onload, não funcionam <script>sem nenhum srcatributo HTML (eu estava tentando usar este conselho em um script embutido e achei que não estava funcionando)
gog
64

Você pode acionar alguns js automaticamente em um elemento IMG usando onerror e nenhum src.

<img src onerror='alert()'>
John Williams
fonte
4
Brilhante! Também pode ser usado para disparar texto datilografado a partir de angular: img src (erro) = "function ()" />
Brian Richardson
1
Esta é uma abordagem fantástica. Por favor, veja minha expansão de sua solução aqui: stackoverflow.com/questions/4057236/…
Rounin
Caniuse? Pac
Pacerier
28

evento onload, ele suporta apenas algumas tags, como as listadas abaixo.

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

Aqui a referência para o evento onload

Samda
fonte
17

Tente isso! E nunca use trigger duas vezes em div!

Você pode definir a função a ser chamada antes da tag div.

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

DEMO: jsfiddle

Kuofp
fonte
Acima, o jsfiddle não possui um carregador jQuery - e não funciona.
Arif Burhan
@Arif Burhan Eu não entendo. Eu carrego o JQuery (borda). Você poderia verificar novamente? Eu posso ver "Olá Mundo", mesmo usando dispositivos móveis.
Kuofp 6/03/16
@Kuofp Esse violino não tem manipuladores que são chamados quando seus elementos de destino são carregados. Ele apenas usa o jquery para procurar elementos que tenham um atributo (no seu caso onload) e depois chama essas funções. O script funciona mesmo se você alterar o atributo para algo diferente de onloadeg jsfiddle.net/mrszgbxh
Trindaz
1
@Trindaz Exatamente! Em outras palavras, os scripts agem como um evento onload. Obrigado por deixar um comentário!
Kuofp 17/08/16
10

Eu só quero adicionar aqui que, se alguém quiser chamar uma função no evento load de div e você não quiser usar o jQuery (devido a conflitos como no meu caso), basta chamar uma função depois de todo o código html ou qualquer outro código que você escreveu, incluindo o código da função e simplesmente chame uma função.

/* 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
fonte
Você pode adicionar mais de uma função dessa maneira? ou seja, no final do documento html, logo antes da tag </body>? Se sim, a ordem em que são escritas é importante?
Neo
Sim, você pode adicionar mais de uma função e a ordem não importa seu javascript simples (baunilha).
precisa saber é
7

podemos usar o MutationObserver para resolver o problema de maneira eficiente, adicionando um código de exemplo abaixo

<!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
fonte
1
A última vez que verifiquei os eventos de mutação teve um desempenho terrível.
precisa saber é o seguinte
7

Em novembro de 2019, estou procurando uma maneira de criar um (hipotético) onparse EventListenerpara o <elements>qual não é precisoonload .

O (hipotético) onparse EventListenerdeve poder ouvir quando um elemento é analisado .


Terceira tentativa (e solução definitiva)

Fiquei muito feliz com a Segunda Tentativa abaixo, mas me ocorreu que eu posso tornar o código mais curto e mais simples, criando um evento personalizado:

let parseEvent = new Event('parse');

Esta é a melhor solução ainda.

O exemplo abaixo:

  1. Cria um projeto feito sob medida parse Event
  2. Declara uma função (que pode ser executada a window.onloadqualquer momento) que:
    • Localiza quaisquer elementos no documento que incluam o atributo data-onparse
    • Anexa a parse EventListenercada um desses elementos
    • Despacha parse Eventpara cada um desses elementos para executar oCallback

Exemplo de trabalho:

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


Segunda tentativa

o primeira tentativa abaixo (baseada no @JohnWilliams'brilhante corte de imagem vazia ) usou um código<img /> e funcionou.

Eu pensei que deveria ser possível remover o código codificado <img /> completamente e apenas inseri-lo dinamicamente depois de detectar, em um elemento que precisava disparar um onparseevento, um atributo como:

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

Acontece que isso funciona muito bem mesmo.

O exemplo abaixo:

  1. Localiza quaisquer elementos no documento que incluam o atributo data-onparse
  2. Gera dinamicamente um <img src /> e o anexa ao documento, imediatamente após cada um desses elementos
  3. Dispara o onerror EventListener quando o mecanismo de renderização analisa cada<img src />
  4. Executa Callback e remove que gerado dinamicamente<img src /> do documento

Exemplo de trabalho:

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


Primeira tentativa

Eu posso construir sobre @JohnWilliams' <img src>hack (nesta página, a partir de 2017) - que é, até agora, a melhor abordagem que encontrei.

O exemplo abaixo:

  1. Dispara o onerror EventListener quando o mecanismo de renderização analisa<img src />
  2. Executa Callback e remove o <img src />do documento

Exemplo de trabalho:

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
fonte
@DavidBradshaw - Você não vai acreditar, mas eu acho que eu tenha realmente rachou. Veja a segunda tentativa , na parte superior da resposta acima.
Rounin
1
@DavidBradshaw - Scratch that. Eu vim com uma terceira tentativa . Esta é a solução definitiva.
Rounin
Talvez cortar o baixo resposta para a versão 3
David Bradshaw
6

use um iframe e oculte-o iframe funciona como uma etiqueta corporal

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

Eu precisava que algum código de inicialização fosse executado depois que um pedaço de html (instância do modelo) foi inserido e, é claro, não tive acesso ao código que manipula o modelo e modifica o DOM. A mesma idéia vale para qualquer modificação parcial do DOM pela inserção de um elemento html, geralmente um<div> .

Há algum tempo, fiz um hack com o evento onload de um quase invisível <img>contido em um <div>, mas descobri que um estilo vazio com escopo também fará:

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

Atualização (15 de julho de 2017) - O <style>onload não é suportado na última versão do IE. O Edge é compatível, mas alguns usuários veem isso como um navegador diferente e seguem o IE. O <img>elemento parece funcionar melhor em todos os navegadores.

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

Para minimizar o impacto visual e o uso de recursos da imagem, use um src embutido que a mantenha pequena e transparente.

Um comentário que acho que preciso fazer sobre o uso de a <script>é o quão mais difícil é determinar qual <div>script está próximo, especialmente em modelos em que você não pode ter um ID idêntico em cada instância que o modelo gera. Eu pensei que a resposta poderia ser document.currentScript, mas isso não é universalmente suportado. Um <script>elemento não pode determinar sua própria localização DOM de maneira confiável; uma referência a 'this' aponta para a janela principal e não ajuda em nada.

Eu acredito que é necessário se contentar em usar um <img>elemento, apesar de ser pateta. Isso pode ser um buraco na estrutura DOM / javascript que pode ser usada.

Floyd Kosch
fonte
3

Como o onloadevento é suportado apenas em alguns elementos, é necessário usar um método alternativo.

Você pode usar um MutationObserver para isso:

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

Eu realmente gosto da biblioteca YUI3 para esse tipo de coisa.

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

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

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

mjhm
fonte
9
Esse é um blob bastante grande de JS para despejar na página com o objetivo de vincular um único onload.
meagar
1
@meagar - Certo, embora eu esteja achando cada vez mais raro fazer apenas duas ou três coisas simples sobre JS em uma página. Preocupar-se com a compatibilidade entre navegadores também me deixa louco.
Mjhm 30/10/10
0

Eu estou aprendendo javascript e jquery e estava passando por toda a resposta, enfrentei o mesmo problema ao chamar a função javascript para carregar o elemento div. eu tentei$('<divid>').ready(function(){alert('test'}) e funcionou para mim. Eu quero saber se esta é uma boa maneira de executar a chamada onload no elemento div da maneira que fiz usando o seletor jquery.

obrigado

subro
fonte
0

Como foi dito, você não pode usar o evento onLoad em uma DIV, mas antes da tag body.

mas caso você tenha um arquivo de rodapé e o inclua em várias páginas. é melhor verificar primeiro se a div que você deseja está nessa página exibida, para que o código não seja executado nas páginas que não contêm esse DIV para agilizar o carregamento e economizar tempo para o seu aplicativo.

então, você precisará fornecer um ID a esse DIV e fazer:

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

Eu tinha a mesma pergunta e estava tentando obter um Div para carregar um script de rolagem, usando onload ou load. O problema que encontrei foi que sempre funcionava antes que o Div pudesse abrir, não durante ou depois, para que realmente não funcionasse.

Então eu vim com isso como uma solução alternativa.

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

Coloquei o Div dentro de um Span e dei ao Span dois eventos, um mouseover e um mouseout. Em seguida, abaixo desse Div, coloquei um link para abrir o Div e dei a esse link um evento para onclick. Todos os eventos são exatamente iguais, para fazer a página rolar para baixo até o final da página. Agora, quando você clica no botão para abrir o Div, a página salta para baixo parcialmente e o Div é aberto acima do botão, fazendo com que os eventos de mouseover e mouseout ajudem a empurrar o script de rolagem para baixo. Então, qualquer movimento do mouse nesse ponto empurrará o script uma última vez.

Seletivo
fonte
0

Você pode usar um intervalo para procurá-lo até que ele carregue assim: 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
fonte
0

Primeiro a responder sua pergunta: Não, você não pode, não diretamente como você queria. Pode ser um pouco tarde para responder, mas esta é a minha solução, sem jQuery, javascript puro. Ele foi originalmente escrito para aplicar uma função de redimensionamento às áreas de texto depois que o DOM é carregado e pressionado.

Da mesma forma que você pode usá-lo para fazer algo com (all) divs ou apenas um, se especificado, da seguinte forma:

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 você realmente precisa fazer algo com uma div, carregada após o DOM ser carregado, por exemplo, após uma chamada ajax, você pode usar um hack muito útil, fácil de entender e que você encontrará ... trabalhando com elementos-antes-do-dom-estar-pronto ... . Ele diz "antes que o DOM esteja pronto", mas funciona de maneira brilhante da mesma maneira, após uma inserção do ajax ou js-appendChild, qualquer que seja uma div. Aqui está o código, com algumas pequenas alterações nas minhas necessidades.

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

Quando você carrega algum html do servidor e o insere na árvore do DOM, pode usá- DOMSubtreeModifiedlo, mas está obsoleto - para que você possa usar MutationObserverou apenas detectar novo conteúdo diretamente na função loadElement, para não precisar esperar pelos eventos do DOM

Kamil Kiełczewski
fonte
0

Você pode anexar um ouvinte de evento como abaixo. Ele será acionado sempre que o div com seletor for #my-idcarregado completamente no DOM.

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

Nesse caso, EventName pode ser 'load' ou 'click'

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

SkyRar
fonte
-1

Use o evento body.onload, por meio de attribute ( <body onload="myFn()"> ...) ou vinculando um evento em Javascript. Isso é extremamente comum no jQuery :

$(document).ready(function() {
    doSomething($('#myDiv'));
});
mway
fonte
javascript puro e não jquery, verifique tag;)
KingRider
-3

Tente isso.

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

Experimente este também. Você precisa remover .de oQuickReply.swap()para que a função funcione.

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


fonte
Parece funcionar, mas é meramente alert("This is a div.");chamado quando essa linha é executada e o resultado (que é undefined) atribuído div.onload. O que é completamente inútil.
Frederic Leitenberger
-4

Você não pode adicionar evento onload na div, mas pode adicionar onkeydown e acionar onkeydown evento no carregamento do 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>`

Muhammad Bilal
fonte