Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 12 of 12
  1. #1
    Regular Coder
    Join Date
    Nov 2009
    Posts
    200
    Thanks
    23
    Thanked 0 Times in 0 Posts

    Directly add an attribute as an element property

    Here's how I change the value of an existing attribute:

    Code:
    element.attribute = "value"
    But is it OK to use the above method to create a new attribute?

  • #2
    Senior Coder xelawho's Avatar
    Join Date
    Nov 2010
    Posts
    2,981
    Thanks
    56
    Thanked 557 Times in 554 Posts
    it would seem so...

    Code:
    <body>
    <div id="res"></div>
    <script> 
    var thediv = document.getElementById("res");
    thediv.sexiness="extreme";
    alert(thediv.sexiness);
    </script>
    </body>
    although there are conventions that custom attributes should begin with a data- prefix

  • Users who have thanked xelawho for this post:

    Rain Lover (02-14-2014)

  • #3
    Regular Coder
    Join Date
    Nov 2009
    Posts
    200
    Thanks
    23
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by xelawho View Post
    it would seem so...

    Code:
    <body>
    <div id="res"></div>
    <script> 
    var thediv = document.getElementById("res");
    thediv.sexiness="extreme";
    alert(thediv.sexiness);
    </script>
    </body>
    although there are conventions that custom attributes should begin with a data- prefix
    Thanks for the confirmation! Just wanted to make sure.

  • #4
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,378
    Thanks
    11
    Thanked 592 Times in 572 Posts
    Quote Originally Posted by Rain Lover View Post
    Here's how I change the value of an existing attribute:

    Code:
    element.attribute = "value"
    But is it OK to use the above method to create a new attribute?
    the real answer is sometimes, it depends on the attrib's dom binding. In the case of "attribute" the answer is no because there is no dom binding for attribute. In the case of title, id, name, dir, disabled, et al, the answer is yes. Note that some attribs have different dom names than attribute names, for example class is .className. value is a tricky one because it doesn't update the attribute when you update the elm.value, even though the names are the same.

    xelawho provides an example not of setting an attribute, but of setting a dom property, which does typically work provided you avoid conflict with existing property bindings as mentioned above. There will be no change to elm.outerHTML before or after setting thediv.sexiness, because "sexiness" does not have a dom binding.

    you can poke properties to attribs easily by using data- attribs and the dataset sub property of an element. For example, div.dataset.sexiness=123 will add an attrib to the div like data-sexiness="123"...
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%

  • #5
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,315
    Thanks
    29
    Thanked 279 Times in 273 Posts
    Quote Originally Posted by xelawho View Post
    it would seem so...

    Code:
    <body>
    <div id="res"></div>
    <script> 
    var thediv = document.getElementById("res");
    thediv.sexiness="extreme";
    alert(thediv.sexiness);
    </script>
    </body>
    although there are conventions that custom attributes should begin with a data- prefix
    As rnd_me pointed out, this code doesn't create or set a markup attribute. It simply sets a property on the relevant element object.

    In HTML, one can create custom attributes as shown below, though this won't automatically create a shortcut property:

    Code:
    // Sets a property.
    document.body.sexiness = "extreme";
    alert(document.body.getAttribute("sexiness")); // null
    delete document.body.sexiness; // Reset code.
    
    // Sets a custom attribute using the HTML data-* attribute API.
    document.body.dataset.sexiness = "extreme";
    alert(document.body.dataset.sexiness = "extreme"); // "extreme"
    alert(document.body.getAttribute("data-sexiness")); // "extreme"
    alert(document.body.sexiness); // undefined.
    document.body.removeAttribute("sexiness"); // Reset code.
    
    // Sets a custom attribute using the generic DOM API.
    document.body.setAttribute("sexiness", "extreme");
    alert(document.body.getAttribute("sexiness")); // "extreme"
    alert(document.body.sexiness); // undefined
    As far as I can tell, there's no prohibition in the HTML spec on creating custom markup attributes using the generic DOM API, though I would stick with the data-* attribute API to remain consistent with how custom attributes are specified in HTML.

    You should consider whether attributes should be used at all though:

    Code:
    // Set a markup attribute.
    document.body.setAttribute("score", 80);
    document.body.getAttribute("score"); // returns "80", not 80
    
    // Set a property.
    document.body.score = 80;
    document.body.score; // returns 80
    As shown in the above code, setting a markup attribute is inferior to setting a property because the type of the value is lost; the output value is a string no matter what the original type of the value is/was.
    For every complex problem, there is an answer that is clear, simple, and wrong.

  • Users who have thanked Arbitrator for this post:

    Rain Lover (02-15-2014)

  • #6
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,378
    Thanks
    11
    Thanked 592 Times in 572 Posts
    Quote Originally Posted by Arbitrator View Post
    As far as I can tell, there's no prohibition in the HTML spec on creating custom markup attributes using the generic DOM API, though I would stick with the data-* attribute API to remain consistent with how custom attributes are specified in HTML.

    the other big reason to use dataset is to import and export whole collections:

    Code:
    var body=document.body;
    
    body.outerHTML.split(">")[0] // == "<body";
    body.dataset.a=1;
    body.dataset.b=2;
    body.dataset.c=3;
    alert(JSON.stringify(body.dataset)) // shows:  {"a":"1","b":"2","c":"3"}
    body.outerHTML.split(">")[0] // == '<body data-a="1" data-b="2" data-c="3"';
    i don't think the JSON part is well-publicized, but it's been useful to me since i found out about it...
    Last edited by rnd me; 02-15-2014 at 02:04 AM.
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%

  • #7
    Regular Coder
    Join Date
    Nov 2009
    Posts
    200
    Thanks
    23
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Arbitrator View Post
    Code:
    // Sets a custom attribute using the HTML data-* attribute API.
    document.body.dataset.sexiness = "extreme";
    alert(document.body.dataset.sexiness = "extreme"); // "extreme"
    alert(document.body.getAttribute("data-sexiness")); // "extreme"
    alert(document.body.sexiness); // undefined.
    document.body.removeAttribute("sexiness"); // Reset code.
    I knew nothing about dataset. Thanks for the info!

  • #8
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,315
    Thanks
    29
    Thanked 279 Times in 273 Posts
    Quote Originally Posted by rnd me View Post
    i don't think the JSON part is well-publicized, but it's been useful to me since i found out about it...
    I'll keep it in mind though I can't think of any situation it'd be useful for outside of pre-existing (not dynamically generated) data-* attributes.

    Seems more straightforward to use the following for your scenario:

    Code:
    var set = { a: 1, b: 2, c: 3 };
    JSON.stringify(set); // "{"a":1,"b":2,"c":3}"
    
    // Using Object.create (my current convention for object creation):
    var set = Object.create(null);
    Object.defineProperty(set, "a", { value: 1, enumerable: true });
    Object.defineProperty(set, "b", { value: 2, enumerable: true });
    Object.defineProperty(set, "c", { value: 3, enumerable: true });
    JSON.stringify(set); // "{"a":1,"b":2,"c":3}"
    You don't lose any type info this way.
    For every complex problem, there is an answer that is clear, simple, and wrong.

  • #9
    Regular Coder
    Join Date
    Nov 2009
    Posts
    200
    Thanks
    23
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by rnd me View Post
    the real answer is sometimes, it depends on the attrib's dom binding. In the case of "attribute" the answer is no because there is no dom binding for attribute. In the case of title, id, name, dir, disabled, et al, the answer is yes. Note that some attribs have different dom names than attribute names, for example class is .className.
    As far as I have tested you can use the above direct method if the attribute is defined by W3C, e.g. title. But for creating custom attributes we need to use setAttribute.

    Code:
    value is a tricky one because it doesn't update the attribute when you update the elm.value, even though the names are the same.
    But it seems to be working:
    Code:
    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="UTF-8">
        <title>Input value</title>
        <style>
        </style>
    </head>
    
    <body>
        <input id="h" value="bar">
        <script>
            document.getElementById("h").value = "foo";
        </script>
    </body>
    
    </html>
    Last edited by Rain Lover; 02-15-2014 at 08:36 AM.

  • #10
    Senior Coder rnd me's Avatar
    Join Date
    Jun 2007
    Location
    Urbana
    Posts
    4,378
    Thanks
    11
    Thanked 592 Times in 572 Posts
    Quote Originally Posted by Rain Lover View Post
    But it seems to be working:
    Code:
    <!DOCTYPE html>
    <html>
    
    <head>
        <meta charset="UTF-8">
        <title>Input value</title>
        <style>
        </style>
    </head>
    
    <body>
        <input id="h" value="bar">
        <script>
            h.value = "foo";
        </script>
    </body>
    
    </html>
    sure about that?

    Code:
        <script>
            h.value = "foo";
           alert(h.outerHTML);
        </script>
    my site (updated 13/9/26)
    BROWSER STATS [% share] (2014/9/03) IE7:0.1, IE8:4.6, IE11:9.1, IE9:3.1, IE10:3.0, FF:17.2, CH:46, SF:11.4, NON-MOUSE:38%

  • #11
    Senior Coder Arbitrator's Avatar
    Join Date
    Mar 2006
    Location
    Splendora, Texas, United States of America
    Posts
    3,315
    Thanks
    29
    Thanked 279 Times in 273 Posts
    Quote Originally Posted by Rain Lover View Post
    value is a tricky one because it doesn't update the attribute when you update the elm.value, even though the names are the same.

    But it seems to be working:
    You're not changing the value of the value markup attribute in that code; you're changing the value of the value property. The shortcut property for the value attribute is defaultValue, hence the "tricky".

    Code:
    <input id="text" type="text" value="Replace me!">
    <script>
    	(function () {
    		"use strict";
    		var text = document.getElementById("text");
    		text.value = "Hello world!";
    		alert(text.getAttribute("value")); // "Replace me!"
    		alert(text.value); // "Hello world!"
    		alert(text.defaultValue); // "Replace me!"
    	})();
    </script>
    For every complex problem, there is an answer that is clear, simple, and wrong.

  • Users who have thanked Arbitrator for this post:

    Rain Lover (02-15-2014)

  • #12
    Regular Coder
    Join Date
    Nov 2009
    Posts
    200
    Thanks
    23
    Thanked 0 Times in 0 Posts

    Thumbs up

    Quote Originally Posted by Arbitrator View Post
    The shortcut property for the value attribute is defaultValue
    You're fantastic, man!


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •