How to add onload event to a div element

前端 未结 24 2507
谎友^
谎友^ 2020-11-22 00:26

How do you add an onload event to an element?

Can I use:

for t

24条回答
  •  离开以前
    2020-11-22 00:56

    In November 2019, I am seeking a way to create a (hypothetical) onparse EventListener for which don't take onload.

    The (hypothetical) onparse EventListener must be able to listen for when an element is parsed.


    Third Attempt (and Definitive Solution)

    I was pretty happy with the Second Attempt below, but it just struck me that I can make the code shorter and simpler, by creating a tailor-made event:

    let parseEvent = new Event('parse');
    

    This is the best solution yet.

    The example below:

    1. Creates a tailor-made parse Event
    2. Declares a function (which can be run at window.onload or any time) which:
      • Finds any elements in the document which include the attribute data-onparse
      • Attaches the parse EventListener to each of those elements
      • Dispatches the parse Event to each of those elements to execute the Callback

    Working Example:

    // 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 <div> is now loaded and the function oQuickReply.swap() 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;
    }

    My Heading

    My Heading

    This div hasn't yet loaded and nothing will happen.


    Second Attempt

    The First Attempt below (based on @JohnWilliams' brilliant Empty Image Hack) used a hardcoded and worked.

    I thought it ought to be possible to remove the hardcoded entirely and only dynamically insert it after detecting, in an element which needed to fire an onparse event, an attribute like:

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

    It turns out, this works very well indeed.

    The example below:

    1. Finds any elements in the document which include the attribute data-onparse
    2. Dynamically generates an and appends it to the document, immediately after each of those elements
    3. Fires the onerror EventListener when the rendering engine parses each
    4. Executes the Callback and removes that dynamically generated from the document

    Working Example:

    // Get all the elements which need to respond to an onparse event
    let elementsWithParseEventListener = document.querySelectorAll('[data-onparse]');
    
    // Dynamically create and position an empty  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 <div> is now loaded and the function oQuickReply.swap() 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);
    }

    My Heading

    My Heading

    This div hasn't yet loaded and nothing will happen.


    First Attempt

    I can build on @JohnWilliams' hack (on this page, from 2017) - which is, so far, the best approach I have come across.

    The example below:

    1. Fires the onerror EventListener when the rendering engine parses
    2. Executes the Callback and removes the from the document

    Working Example:

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

    My Heading

提交回复
热议问题