Как добавить событие onload в элемент div


232

Как добавить onloadсобытие в элемент?

Могу ли я использовать:

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

для этого?


лучше bodyлучшеdiv
KingRider

2
divэлементы не "загружаются".
Amn

1
Теперь есть более актуальный ответ - возможно, вы можете пересмотреть принятие?
mplungjan

Ответы:


233

Нет, ты не можешь. Самый простой способ заставить это работать - поместить вызов функции непосредственно после элемента.

Пример:

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

или - еще лучше - прямо перед </body>:

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

... чтобы не блокировать загрузку следующего контента.


3
В зависимости от использования лучше не ставить его перед собой </body>. Например, если вы хотите скрыть <div>только если JavaScript включен, но избегайте «перепрошивки». Время видимости зависит от того, как долго браузер должен загружать / анализировать все встроенные / внешние скрипты.
Мгутт

Это анти-паттерн, в котором лучше хранить все js внутри своего файла? Есть ли способ выборочно запускать JS, когда определенные элементы загружаются в документ?
Райан Уолтон

1
Это не анти-паттерн, но вы обычно ждете загрузки DOM и затем выполняете все JS.
DanMan

1
Бросьте эту ссылку сюда для всех, кто сталкивается с этим ответом. W3schools.com/tags/ev_onload.asp - Все элементы HTML, которые в настоящее время поддерживаютonload
Брэндон Бенефилд,

Этот ответ больше не актуален. Вот новый
mplungjan

74

onloadСобытие может быть использовано только на document(body)сам, рамки, изображения и скрипты. Другими словами, он может быть привязан только к телу и / или к каждому внешнему ресурсу . DIV не является внешним ресурсом и загружается как часть тела, поэтому onloadсобытие там не применяется.


18
Не только в элементе body, вы можете использовать его, например, вместе с изображениями и iframe. w3schools.com/jsref/event_onload.asp
Джо

2
Стоит отметить, что встроенные сценарии НЕ являются внешними ресурсами, и поэтому onloadне работают ни с одним <script>без srcатрибута HTML (я пытался использовать этот совет во встроенном сценарии, и обнаружил, что он не работает)
gog

64

Вы можете автоматически запускать некоторые js для элемента IMG, используя onerror, но без src.

<img src onerror='alert()'>

4
Brilliant! Может также использоваться для запуска машинописи с углового: img src (error) = "function ()" />
Брайан Ричардсон,

1
Это фантастический подход. Пожалуйста, посмотрите мое расширение вашего решения здесь: stackoverflow.com/questions/4057236/…
Rounin

Caniuse? ͏͏͏͏͏͏͏
Pacerier

28

Событие onload поддерживается только с несколькими тегами, как указано ниже.

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

Здесь ссылка на событие загрузки


17

Попробуй это! И никогда не используйте триггер дважды на div!

Вы можете определить функцию для вызова перед тегом div.

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

ДЕМО: jsfiddle


Выше jsfiddle не имеет загрузчика jQuery - и не работает.
Ариф Бурхан

@ Ариф Бурхан, я не понимаю. Я действительно загружаю JQuery (край). Не могли бы вы проверить еще раз? Я вижу "Hello World", даже используя мобильный телефон.
Куофп

@Kuofp У этой скрипки нет обработчиков, вызываемых при загрузке целевых элементов. Он просто использует jquery для поиска элементов, которые имеют атрибут (в вашем случае onload), а затем вызывает эти функции. Сценарий работает, даже если вы измените атрибут на что-то отличное от, onloadнапример, jsfiddle.net/mrszgbxh
Trindaz

1
@ Триндаз Точно! Другими словами, сценарии действуют как событие onload. Спасибо за оставленный комментарий!
Куофп

10

Я просто хочу добавить, что если кто-то хочет вызвать функцию при загрузке события div и вы не хотите использовать jQuery (из-за конфликта, как в моем случае), то просто вызовите функцию после всего HTML-кода или любого другого другой код, который вы написали, включая код функции, и просто вызовите функцию.

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

ИЛИ

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

  }

 my_func();
</script>

Можете ли вы добавить более одной функции таким образом? то есть в конце HTML-документа непосредственно перед тегом </ body>? Если да, имеет ли значение порядок, в котором они написаны?
Нео

Да, вы можете добавить более одной функции, и порядок не будет иметь значения, это просто (ванильный) JavaScript.
dev_khan

7

мы можем использовать MutationObserver для эффективного решения проблемы, добавив пример кода ниже

<!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
В прошлый раз я проверял, что мутационные события выполняются ужасно.
DanMan

7

В ноябре 2019 года я ищу способ создать (гипотетический) onparse EventListenerдля <elements>которых не берут onload.

(Гипотетический) onparse EventListenerдолжен быть в состоянии слушать, когда элемент анализируется .


Третья попытка (и окончательное решение)

Я был очень доволен второй попыткой ниже, но меня просто поразило, что я могу сделать код короче и проще, создав специальное событие:

let parseEvent = new Event('parse');

Это лучшее решение пока.

Пример ниже:

  1. Создает на заказ parse Event
  2. Объявляет функцию (которую можно запустить в window.onloadлюбое время), которая:
    • Находит любые элементы в документе, которые включают атрибут data-onparse
    • Прикрепляет parse EventListenerк каждому из этих элементов
    • Отправляет parse Eventкаждый из этих элементов для выполненияCallback

Рабочий пример:

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


Вторая попытка

Первая попытка ниже ( на основе @JohnWilliams"Блестящий Empty Image Hack ) используется зашиты<img /> и работал.

Я подумал, что должна быть возможность <img />полностью удалить жестко закодированный и только динамически вставить его после обнаружения в элементе, который должен вызывать onparseсобытие, атрибута вроде:

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

Оказывается, это действительно работает очень хорошо.

Пример ниже:

  1. Находит любые элементы в документе, которые включают атрибут data-onparse
  2. Динамически генерирует <img src />и добавляет его в документ сразу после каждого из этих элементов.
  3. Запускает, onerror EventListenerкогда механизм рендеринга анализирует каждый<img src />
  4. Выполняет Callback и удаляет то, что динамически генерируется <img src />из документа

Рабочий пример:

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


Первая попытка

Я могу построить на @JohnWilliams' <img src>хака (на этой странице, с 2017 года) - что, до сих пор, лучший подход , который я наткнулся.

Пример ниже:

  1. Запускает onerror EventListenerкогда анализирует движок рендеринга<img src />
  2. Выполняет Callback и удаляет <img src />из документа

Рабочий пример:

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 - Вы никогда не поверите, но я думаю , что я бы на самом деле взломали. Смотрите вторую попытку , в верхней части ответа выше.
Рунин

1
@DavidBradshaw - поцарапайте это. Я придумал третью попытку . Это окончательное решение.
Рунин

Возможно сократить ответ до версии 3
Дэвид Брэдшоу

6

используйте iframe и скрывайте его, если iframe работает как тег 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

Мне нужно было запустить некоторый код инициализации после вставки фрагмента html (экземпляра шаблона), и, конечно, у меня не было доступа к коду, который манипулирует шаблоном и модифицирует DOM. Та же идея имеет место для любой частичной модификации DOM путем вставки html-элемента, обычно<div> .

Некоторое время назад я взломал событие onload почти невидимого, <img>содержащегося в a <div>, но обнаружил, что пустой стиль с областью видимости также подойдет:

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

Обновление (15 июля 2017 г.) - <style>загрузка не поддерживается в последней версии IE. Edge поддерживает это, но некоторые пользователи видят в этом другой браузер и придерживаются IE. <img>Элемент , кажется, лучше работать во всех браузерах.

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

Чтобы минимизировать визуальное воздействие и использование ресурсов изображения, используйте встроенный src, который делает его маленьким и прозрачным.

Один комментарий, который я считаю нужным сделать с использованием a, <script>состоит в том, насколько сложнее определить, какой <div>сценарий находится рядом, особенно в шаблонах, где вы не можете иметь идентичный идентификатор в каждом экземпляре, который генерирует шаблон. Я думал, что ответ может быть document.currentScript, но это не всегда поддерживается. <script>Элемент не может определить свое собственное местоположение DOM надежно; ссылка на «это» указывает на главное окно и не помогает.

Я считаю, что необходимо согласиться на использование <img>элемента, несмотря на то, что глупо. Это может быть дыра в платформе DOM / javascript, в которой можно использовать подключение.


3

Поскольку onloadсобытие поддерживается только для нескольких элементов, вы должны использовать альтернативный метод.

Вы можете использовать MutationObserver для этого:

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

Мне действительно нравится библиотека YUI3 для такого рода вещей.

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

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

Смотрите: http://developer.yahoo.com/yui/3/event/#onavailable


9
Это довольно большой кусок JS, который нужно выгрузить на страницу ради связывания одного onload.
Meagar

1
@Meagar - Да, хотя я нахожу все более редким, что я делаю только две или три простые вещи JS на странице. Беспокойство о кросс-браузерной совместимости также сводит меня с ума.
MJHM

0

Я изучаю javascript и jquery и прохожу все ответы, я столкнулся с той же проблемой при вызове функции javascript для загрузки элемента div. Я пытался, $('<divid>').ready(function(){alert('test'})и это сработало для меня. Я хочу знать, это хороший способ выполнить вызов onload элемента div так же, как я использовал селектор jquery.

Спасибо


0

Как уже говорилось, вы не можете использовать событие onLoad вместо DIV, но перед тегом body.

но в случае, если у вас есть один файл нижнего колонтитула и включить его на многих страницах. лучше сначала проверить, отображается ли нужный div на этой странице, чтобы код не выполнялся на страницах, не содержащих этот DIV, чтобы он загружался быстрее и экономил время для вашего приложения.

так что вам нужно будет дать этому DIV ID и сделать:

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

0

У меня был тот же вопрос, и я пытался заставить Div загрузить скрипт прокрутки, используя onload или load. Проблема, которую я обнаружил, состояла в том, что она всегда будет работать до того, как Div сможет открыться, а не во время или после нее, поэтому она не будет работать.

Тогда я придумал это как обходной путь.

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

Я поместил Div внутри Span и дал Span два события: наведение мыши и мышью. Затем под этим Div я разместил ссылку, чтобы открыть Div, и дал этой ссылке событие для onclick. Все события одинаковы, чтобы страница прокручивалась вниз до конца страницы. Теперь, когда нажата кнопка, чтобы открыть Div, страница частично опустится вниз, и Div откроется над кнопкой, вызывая события mouseover и mouseout, помогающие протолкнуть скрипт прокрутки вниз. Тогда любое движение мыши в этой точке будет толкать скрипт в последний раз.


0

Вы можете использовать интервал, чтобы проверить его, пока он не загрузится так: 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

Сначала ответьте на ваш вопрос: нет, вы не можете, не так, как вы хотели. Может быть, немного поздно, чтобы ответить, но это мое решение, без jQuery, чистый javascript. Первоначально он был написан для применения функции изменения размера к textareas после загрузки DOM и при включении.

Таким же образом вы можете использовать его для выполнения чего-либо с (всеми) элементами div или только с одним, если указано, например:

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

Если вам действительно нужно что-то сделать с div, загруженным после загрузки DOM, например, после вызова ajax, вы можете использовать очень полезный хак, который легко понять, и вы найдете его ... работая с элементы перед домом готов . Он говорит «до того, как DOM будет готов», но работает блестяще, точно так же, после вставки ajax или js-appendChild - независимо от div. Вот код, с небольшими изменениями в моих потребностях.

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

Когда вы загружаете html с сервера и вставляете его в дерево DOM, вы можете использовать DOMSubtreeModifiedего, однако он устарел - так что вы можете использовать MutationObserverили просто обнаруживать новый контент непосредственно внутри функции loadElement, чтобы вам не пришлось ждать событий DOM


0

Вы можете прикрепить прослушиватель событий, как показано ниже. Он сработает всякий раз, когда div с селектором #my-idполностью загружается в DOM.

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

В этом случае EventName может быть «загрузить» или «щелкнуть»

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


-1

Вместо этого используйте событие body.onload либо через attribute ( <body onload="myFn()"> ...) , либо связав событие в Javascript. Это очень часто встречается в jQuery :

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

чистый javascript, а не jquery, отметьте тег;)
KingRider,

-3

Попробуй это.

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

Попробуйте это тоже. Вы должны удалить .из, oQuickReply.swap()чтобы функция работала.

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


Кажется, это работает, но это просто, что alert("This is a div.");вызывается, когда эта строка выполняется и результат (который undefined) назначается div.onload. Что совершенно бессмысленно.
Фредерик Лейтенбергер

-4

Вы не можете добавить событие onload на div, но вы можете добавить onkeydown и вызвать событие onkeydown при загрузке документа

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

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.