JavaScript - overwriting .onload prototype of HTMLImageElement(s)

前端 未结 4 2388
花落未央
花落未央 2020-12-21 17:50

Is it possible to bind an onload event to each image, declaring it once? I tried, but can\'t manage to get it working... (this error is thrown: Uncaught

4条回答
  •  渐次进展
    2020-12-21 18:24

    You get that error because onload is an accessor property defined in HTMLElement.prototype.

    You are supposed to call the accessor only on HTML elements, but you are calling the setter on HTMLImageElement.prototype, which is not an HTML element.

    If you want to define that function, use defineProperty instead.

    Object.defineProperty(HTMLImageElement.prototype, 'onload', {
      configurable: true,
      enumerable: true,
      value: function () {
        console.log(this, "loaded");
      }
    });
    var img = new Image();
    img.onload();

    Warning: Messing with builtin prototypes is bad practice.

    However, that only defines a function. The function won't be magically called when the image is loaded, even if the function is named onload.

    That's because even listeners are internal things. It's not that, when an image is loaded, the browser calls the onload method. Instead, when you set the onload method, that function is internally stored as an event listener, and when the image is loaded the browser runs the load event listeners.

    Instead, the proper way would be using Web Components to create a custom element:

    var proto = Object.create(HTMLElement.prototype);
    proto.createdCallback = function() {
      var img = document.createElement('img');
      img.src = this.getAttribute('src');
      img.addEventListener('load', function() {
        console.log('loaded');
      });
      this.appendChild(img);  
    };
    document.registerElement('my-img', {prototype: proto});

    There is not much browser support yet, though.

提交回复
热议问题