0

I'm working on a custom video codec for Javascript that supports transparency. I'm at the point of developing an API for the codec, and I would like to match the html video API as much as possible.

So with regular video you can play a video element by chaining the "play" function to the element itself:

document.getElementById("myVideo").play();

You can also access certain object settings within the element and change them such as the video source:

document.getElementById("myVideo").src = "movie.mp4";

I want to achieve this but with my own custom object between the HTML element and the function/object you are referencing to avoid name conflicts. In practice it would look like this:

document.getElementById("myVideo").myObject.play();
document.getElementById("myVideo").myObject.src = "movie.mp4";

However I can't think of a way to make this work using the same "myObject". myObject can be a constructor function which would return a new object, or it can be an object with functions/values stored inside.

Returning a function would work well for the "play" function because it could have access to the html element that called it.

HTMLElement.prototype.myObject= function(){
  var objInstance = {};
  objInstance.documentElement = this;
  objInstance.play = function() { alert(this.documentElement) };
  return objInstance;
}

"this" is referencing the html element which called the function. However doing this means that setting an attritubute like "src" won't work externally because the function is only a constructor that returns a new object. I would also like to have source be an object which can be externally exposed like this:

HTMLElement.prototype.myObject = {
  documentElement: HTMLElement,
  src: "hi",
  play () {
    console.log(this.documentElement);
  }
}

Now I can edit "src" externally, and call the play function, however in this case the play function no longer has access to the html element. Instead the documentElement is storing the window object for the entire page.

How can I implement both these features above in the same variable?

2
  • 1
    Modifying native prototypes is not a good idea,. myObject here is just a glorified global object anyway, there is no instance creation here, and even if you do make it so it does, having every HTMLElement having an instance of myObject would be very wasteful. It would make much more sense to create a wrapper Object. Commented Aug 29, 2018 at 14:32
  • @Keith How would I use a wrapper object and only allow one object to be created per html element? Essentially I wouldn't want someone to call 2 video instances on the same element. Commented Aug 29, 2018 at 15:39

1 Answer 1

1

The best way to attach custom methods to an existing HTML element would be to use a WeakMap, but on older browsers this won't work. Another option is to attach the object to the actual HTML element, making sure you don't overload existing methods / properties.

Below I have used the option of attaching to the object, basically you check to see if you have already attached the object, if not create it.

function MyObject(element) {
  this.element = element;
}

MyObject.prototype.showTime = function () {
  this.element.innerText = new Date();
}

function wrap(element) {
  if (!element.myObject) {
    element.myObject = new MyObject(element);
    console.log("new instance");
  }
  return element.myObject;
}



const test = document.querySelector("#test");

wrap(test).showTime();
wrap(test2).showTime();

//below new objects won't be created..

//update test every second
setInterval(function () {
  wrap(test).showTime();
}, 1000);

//update test2 every 10 seconds
setInterval(function () {
  wrap(test2).showTime();
}, 10000);
<div id="test">
</div>

<div id="test2" style="background-color: yellow">
</div>

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.