Yehonatan
Yehonatan

Reputation: 3225

Can't change html attribute via javascript

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

Upvotes: 0

Views: 1963

Answers (4)

Sacho
Sacho

Reputation: 2179

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

Upvotes: 1

Shomz
Shomz

Reputation: 37701

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.

Upvotes: 0

tmarwen
tmarwen

Reputation: 16374

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

Upvotes: 1

sjjh
sjjh

Reputation: 51

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

Upvotes: 0

Related Questions