0

This is very odd, I'm getting videos via document.getElementsByTag('video') and I can't change their width nor any other value.

Here's the Javascript code I'm using -

window.onload = function() {

            this.videos = document.getElementsByTagName('video');

            var self = this;
            for(var i=0;i<videos.length;i++) {
                videos.item(i).addEventListener("loadedmetadata", 
                    (function(index){
                        return function() {
                            console.log(self.videos[index].offsetWidth); //shows X
                            self.videos[index].offsetWidth = "480";
                            console.log(self.videos[index].offsetWidth); //shows X
                        }
                    })(i)
                );
            }
        }

Example <video> tag -

<video><source src="videos/video_1.mp4" type="video/mp4"></video>

I have no idea what it is happening and I've never encountered such kind of problem. Thanks

EDIT: Using the setAttribute function just adds it to the live html, but the size isn't really changing

8
  • 2
    offsetWidth is a read-only property of an HTMLElement. Also, don't mistake HTML attributes and DOM properties. Commented Jun 12, 2014 at 11:33
  • @Sacho I've heared about these fellows, what can I do about it? I've tried switching to byClass but same result.. Commented Jun 12, 2014 at 11:34
  • How about the other values you can't change? What are they? Commented Jun 12, 2014 at 11:36
  • @Teemu I've tried accessing other width & height properties, 100% of them were read-only Commented Jun 12, 2014 at 11:37
  • Any help of these: <video>, HTMLVideoElement? Commented Jun 12, 2014 at 11:44

4 Answers 4

1

The offsetWidth is a read-only DOM property so you can not update it. However why not change the element width?

window.onload = function() {
  this.videos = document.getElementsByTagName('video');
  var self = this;
  for(var i=0;i<videos.length;i++) {
    videos.item(i).addEventListener("loadedmetadata", 
      (function(index){
        return function() {
        self.videos[index].width = "480";
      }
    })(i));
  }
}

You can take into account the borders, paddings, margins...

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

Comments

1

Note there is a difference between three things you are conflating into one:

  • HTML attributes
  • DOM properties
  • CSS styles

This is an HTML attribute: <a href="http://example.com"></a>

If you have a DOM element representing an HTML tag, you can modify the attributes like so:

var a = document.createElement('a')
a.setAttribute('href', "http://example.com")

This is a DOM property:

var a = document.createElement('a')
a.href = "http://example.com"

Note how a DOM property can be similarly named to an HTML attribute, but they are not the same thing. Oftentimes, changing an HTML attribute will modify the corresponding DOM property, but not vice versa. Also, not all attributes have matching properties, and so on.

CSS styles are accessed via the DOM property style(which corresponds to the HTML attribute style, but while the HTML attribute style is a string, the DOM property is an object):

var a = document.createElement('a');
a.style.width = "500px";
a.style.height = "20%";

There are HTML attributes "width" and "height", but their use is deprecated in favor of using styles. Also, "width" and "height" as HTML attributes can only be numerical values representing pixels - while a CSS style can be many variations(pixels, ems, percentages, etc)

In your specific case, just modify the width styling of your element to change its width.

Another thing in your code is the usage of this and self, which is entirely unneeded. this.videos is setting a property on the global object(window) for no reason. You can also avoid closing over the index property by using .bind():

window.onload = function() {
    var videos = document.getElementsByTagName('video');
    for (var i = 0; i < videos.length;i++) {
        var video = videos.item(i);
        video.addEventListener("loadedmetadata", (function () {
            console.log(this.offsetWidth);
            this.style.width = "480px";
            console.log(this.offsetWidth);
        }).bind(video));
    }
}

2 Comments

Thanks for the detailed and well explained answer but it has no clear solution to my problem. I really appreciate your answer and it is well written but I've picked @tmarwen's answer. Hope you'll understand.
I don't mind - I was just editing it to add a solution, since I noticed you were using this erroneously as well.
0

Try using getAttribute and setAttribute, as in videos[index].setAttribute('offsetWidth', 480)

2 Comments

Haven't worked.. self.videos[index].setAttribute('offsetWidth',480); console.log(self.videos[index].offsetWidth); Outputed 576
Oh, well, it did added the offesetWidth to the html but it haven't really changed the width of the video
0

First off, this doesn't seem right:

for(var i=0;i<videos.length;i++) {

Shouldn't it be self.videos? Fix that.

Then, to change the video size, you can change the size of the element:

self.videos[index].width = "480";

or, even better, the CSS width:

self.videos[index].style.width = "480px";

The size of the video itself will automatically extend to the size of the video element.

2 Comments

Thanks for the clear solution but it doesn't really matter if it self.video or videos in the loop. The scope is ok
You're welcome. You should still stick to one notation, because that function will fail in anything outside the window scope. And about the videos - try to use CSS for styling, rather than width/height HTML attributes.

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.