How to get non-DOM properties of HTML in Javascript - javascript

Say a HTML snippet like this:
<div a_example = "x" b_example = "y" class = "z"></div>
What is the proper way to get the corresponding properties of a_example and b_example in Javascript?
Can xpath do the job?

Use getAttribute:
var elem = document.getElementsByClassName("z")[0],
a = elem.getAttribute("a_example");
Here's a working example.
But, as has already been mentioned, you should really be using HTML5 data-* attributes, otherwise your markup is invalid.

Some browsers will add all attributes as named properties of the DOM element, others will only add standard attributes. In both cases you can get non–standard attributes using getAttribute, however such a scheme is not recommended.
It is common to use standard attributes and DOM properties and only use getAttribute where necessary as it is inconsistently implemented in different browsers.

You should take a look at HTML5 data attributes, here is a useful article: http://html5doctor.com/html5-custom-data-attributes/
Reading data attributes from a tag is really easy, and a fallback is available for older browsers. An example from the article:
<div id="sunflower" data-leaves="47" data-plant-height="2.4m"></div>
<script>
// 'Getting' data-attributes using dataset
var plant = document.getElementById('sunflower');
var leaves = plant.dataset.leaves; // leaves = 47;
</script>

If you are using jQuery, it is as simple as saying:
HTML
<div id="testDiv" a_example = "x" b_example = "y" class = "z"></div>
Javascript:
var attr1 = $('#testDiv').attr('a_example');

element.getAttribute(attributename)
This should work for you.

I agree you should look at data attributes and better ways to do add non-standard attributes, but here's a 'raw' answer to your question, but I wouldn't treat this as universally supported (or advisable):
alert(document.getElementsByTagName('div')[0].getAttribute('b_example'));

Related

Get custom field value on span element using javascript

If I have something like this:
<span stylecode="123456789" class="punctis-social-widget"></span>
How can i get the stylecode value using javascript (not jquery). Also, is valid to use custom fields on spans?
Note: The field stylecode sometimes is not present, so the result of the function could be null.
It's not valid to use custom attributes. If you need to store any values consider using the HTML5 data attribute.
<span id="item1" data-stylecode="123456789" class="punctis-social-widget"></span>
Then use JS to fetch that:
<script>
var element = document.getElementById('item1'); // You could use class
var sDataValue = element.getAttribute('data-stylecode'); //123456789
</script>
For jQuery fetch value with:
$('item1').data('stylecode'); //123456789
Provided you can select the span element, you can simply do this:
spanElem.getAttribute('stylecode');
If the attribute doesn't exists, getAttribute() will simply either return null or a '' (seems to vary between browsers).
Selecting it would be easier if it had an id, in which case you could use document.getElementById('id'); Otherwise you can use document.getElementsByClassName('punctis-social-widget') in newer standards-compliant browsers, or use document.getElementsByTagName('span'); and loop over them and inspect their className properties.
As mentioned by Matthew, custom attributes are not valid (but usually don't cause any problems afaik), but provided you use HTML 5, turning it into a data-attribute will make it valid.
Though it is not good practice to use custom attributes like this, you can accomplish this task as such:
var apan = document.getElementsByTagName('span');
var code = span[0].getAttribute('stylecode');
console.log(code);
Use the data attributes.
I know how to catch the value of attribute :
var span = document.getElementsByTagName("span");
var stylecode = span.getAttribute("stylecode");
But I don't know about the second part of your question. Sorry.

Access 'data-' attribute without jQuery

Can I access a data- attribute without jQuery?
It's easy with jQuery, but I can't see anywhere how to do it without jQuery.
If I search on Google 'without jQuery' all I get is jQuery examples.
Is it even possible?
On here I found this example:
<div id='strawberry-plant' data-fruit='12'></div>
<script>
// 'Getting' data-attributes using getAttribute
var plant = document.getElementById('strawberry-plant');
var fruitCount = plant.getAttribute('data-fruit'); // fruitCount = '12'
// 'Setting' data-attributes using setAttribute
plant.setAttribute('data-fruit', '7'); // Pesky birds
</script>
So it would appear very doable.
Update: Since Microsoft is now (2020) phasing out the old Internet Explorer engine in favour of a Chromium based Edge, the dataset property is likely to work everywhere. The exception will, for a time, be organizations and corporate networks where IE is still forced. At the time of writing this though - jsPerf still shows the get/setAttribute method as being faster than using dataset, at least on Chrome 81.
You could use the dataset attribute. As in:
element = document.getElementById("el");
alert(element.dataset.name); // element.dataset.name == data-name
It's just an attribute ... use getAttribute as with any other attribute : https://developer.mozilla.org/en/docs/DOM/element.getAttribute
Or am I missing the point of your question.
You can also use:
getAttribute('data-property');
Which is a bit cleaner and easier to read.
This will get the value of the data attribute.
I think you can try this:
var ele = document.getElementById("myelement");
if (ele.hasOwnProperty("data")) {
alert(ele.data);
}
OR use
alert(ele['data-property']);

Can I add arbitrary properties to DOM objects?

Can I add arbitrary properties to JavaScript DOM objects, such as <INPUT> or <SELECT> elements? Or, if I cannot do that, is there a way to associate my own objects with page elements via a reference property?
ECMAScript 6 has WeakMap which lets you associate your private data with a DOM element (or any other object) for as long as that object exists.
const wm = new WeakMap();
el = document.getElementById("myelement");
wm.set(el, "my value");
console.log(wm.get(el)); // "my value"
Unlike other answers, this method guarantees there will never be a clash with the name of any property or data.
Yes, you can add your own properties to DOM objects, but remember to take care to avoid naming collisions and circular references.
document.getElementById("myElement").myProperty = "my value";
HTML5 introduced a valid way of attaching data to elements via the markup - using the data- attribute prefix. You can use this method in HTML 4 documents with no issues too, but they will not validate:
<div id="myElement" data-myproperty="my value"></div>
Which you can access via JavaScript using getAttribute():
document.getElementById("myElement").getAttribute("data-myproperty");
Sure, people have been doing it for ages. It's not recommended as it's messy and you may mess with existing properties.
If you are looping code with for..in your code may break because you will now be enumerating through these newly attached properties.
I suggest using something like jQuery's .data which keeps metadata attached to objects. If you don't want to use a library, re-implement jQuery.data
Do you want to add properties to the object, or attributes to the element?
You can add attributes using setAttribute
var el = document.getElementById('myelement');
el.setAttribute('custom', 'value');
or you can just add properties to the javascript object:
var el = document.getElementById('myelement');
el.myProperty = 'myValue';
In case someone is wondering in 2015, yes, you can - and jQuery is doing just that in data. Just pick future-proof names like vendor prefixes or time-based random suffixes (jQuery).
If you must, don't use standard HTML attributes. Here's a tutorial on using custom attributes:
http://www.javascriptkit.com/dhtmltutors/customattributes.shtml
It's HTML5, but it's backward-compatible.
I was exploring answers, none have mentioned that in modern JavaScript we can set attributes on domElements using dataset property, it could use on HTMLOrForeignElement (that's a mixin of several features common to the HTMLElement, SVGElement and MathMLElement interfaces).
According to MDN
The dataset property on the HTMLOrForeignElement interface provides read/write access to all the custom data attributes (data-*) set on the element. This access is available both in HTML and within the DOM. It is a map of DOMStrings, one entry for each custom data attribute.
let element = document.getElementById("test");
let footer = document.querySelector("#output");
/* get element values using camelCase names through .dataset */
let sample = element.dataset.sample;
let sampleNumber = element.dataset.sampleNumber;
let dataFromElement = sample + " :: " + sampleNumber;
footer.innerHTML = element.innerHTML + dataFromElement;
<input type="hidden" id="test" data-sample="Sample" data-sample-number=34 />
<div id="output"> </div>
Although there are concerns about Internet Explorer support and performance on this you can check here.

Proper way to change text and elements on a page with JavaScript

I've been using innerHTML and innerText for a while to change elements and text on web pages and I've just discovered that they are not W3C standard.
I've now found that innerHTML can be replaced with createElement, setAttribute and a few others but what is the best method for changing text inside an element?
I found a textContent as well but is there a standard way and is it widly implemented across older browsers?
textContent isn't implemented in IE8 and lower. You can use createTextNode() similar to how you would use createElement(). However, I often use discovery techniques to find out which property I need to use and keep a reference to it:
// You can use a shorter variable name if you want
var innerTextOrTextContent = "textContent" in document.body
? "textContent" : "innerText";
// Set an element's text:
myElement[innerTextOrTextContent] = "Added using: "+innerTextOrTextContent;
The createTextNode() example:
var tNode = document.createTextNode("Added using createTextNode()");
myElement.appendChild(tNode);
Something I often forget about, you can also directly set a text node's value, if you can get a reference to it:
// childNodes[0] is a text node:
myElement.childNodes[0].nodeValue = "Added using nodeValue";
Example - http://jsfiddle.net/BxPaG/.
I think you can't go wrong by using whatever your javascript library offers for changing text (innerHtml for jQuery). After all one of the the main reasons for using such a library is having a platform that abstracts from different browser implementations.

How to add/update an attribute to an HTML element using JavaScript?

I'm trying to find a way that will add / update attribute using JavaScript. I know I can do it with setAttribute() function but that doesn't work in IE.
You can read here about the behaviour of attributes in many different browsers, including IE.
element.setAttribute() should do the trick, even in IE. Did you try it? If it doesn't work, then maybe
element.attributeName = 'value' might work.
What seems easy is actually tricky if you want to be completely compatible.
var e = document.createElement('div');
Let's say you have an id of 'div1' to add.
e['id'] = 'div1';
e.id = 'div1';
e.attributes['id'] = 'div1';
e.createAttribute('id','div1')
These will all work except the last in IE 5.5 (which is ancient history at this point but still is XP's default with no updates).
But there are contingencies, of course.
Will not work in IE prior to 8:e.attributes['style']
Will not error but won't actually set the class, it must be className:e['class'] .
However, if you're using attributes then this WILL work:e.attributes['class']
In summary, think of attributes as literal and object-oriented.
In literal, you just want it to spit out x='y' and not think about it. This is what attributes, setAttribute, createAttribute is for (except for IE's style exception). But because these are really objects things can get confused.
Since you are going to the trouble of properly creating a DOM element instead of jQuery innerHTML slop, I would treat it like one and stick with the e.className = 'fooClass' and e.id = 'fooID'. This is a design preference, but in this instance trying to treat is as anything other than an object works against you.
It will never backfire on you like the other methods might, just be aware of class being className and style being an object so it's style.width not style="width:50px". Also remember tagName but this is already set by createElement so you shouldn't need to worry about it.
This was longer than I wanted, but CSS manipulation in JS is tricky business.
Obligatory jQuery solution. Finds and sets the title attribute to foo. Note this selects a single element since I'm doing it by id, but you could easily set the same attribute on a collection by changing the selector.
$('#element').attr( 'title', 'foo' );
What do you want to do with the attribute? Is it an html attribute or something of your own?
Most of the time you can simply address it as a property: want to set a title on an element? element.title = "foo" will do it.
For your own custom JS attributes the DOM is naturally extensible (aka expando=true), the simple upshot of which is that you can do element.myCustomFlag = foo and subsequently read it without issue.

Categories

Resources