I want to programmatically add attributes to DOM elements (e.g. HTML or SVG elements) dynamically at runtime, i.e. based on user input. If the attribute is standard, I will use the name as is, but if it is not, that is, if it requires conversion to a user attribute, then I want to add the prefix "data-" to it.
So, is there a way to determine if a string represents a "standard / normal" DOM attribute?
For example, let's say I have an SVG rectangle as follows:
<rect x="10" y="10" width="80" height="40" stroke="black"/>
Please note that the fill color is not specified (yet).
The user requests the addition of two attributes:
- attribute with the name "fill" with the value "red", which should give
fill="red"(note the absence of a prefix) - attribute with the name "price" with the value "expensive", which should give
data-price="expensive"(note the prefix data-)
How can I dynamically distinguish between the two? The attribute is fillmissing from my current DOM element, so I cannot check if a pre-existing value exists for the attribute of this name. I also do not believe that I can even check if an error occurs if I create an attribute without a prefix, because, as far as I can tell, at least my current browser (Chrome v61.0) will allow me to add an attribute price="expensive"(without a prefix data-), although this is not the best practice.
I need something like the following:
const elementNodeName = "rect";
const attributeName = "height";
const nameIsValid = testAttributeNameValidity(elementNodeName, attributeName);
if (!nameIsValid) attributeName = 'data-' + attributeName;
- testAttributeNameValidity -type?
javascript, Javascript.
** : SO HTML, SVG **
attributeName in document.createElement(elementNodeName), true false . "id" HTML- (<p>), .
, SVG. createElement createElementNS, , , . . . : testHtmlAttributeNameValidity testSvgAttributeNameValidity. , , HTML, .. id="someId" data-price="expensive". SVG : data-fill="yellow" data-price="expensive".
, Chrome v61.
:
const testHtmlAttributeNameValidity = (elementNodeName, attributeName) => {
return (attributeName in document.createElement(elementNodeName));
};
const testHtmlAttributeName = (attributeName, attributeValue) => {
const elementNodeName = "p";
const nameIsValid = testHtmlAttributeNameValidity(elementNodeName, attributeName);
if (!nameIsValid) attributeName = 'data-' + attributeName;
const element = document.querySelector(elementNodeName);
element.setAttribute(attributeName, attributeValue);
};
testHtmlAttributeName("id", "someId");
testHtmlAttributeName("price", "expensive");
console.log(document.querySelector('div').innerHTML);
const svgNS = "http://www.w3.org/2000/svg";
const testSvgAttributeNameValidity = (elementNodeName, attributeName) => {
return (attributeName in document.createElementNS(svgNS, elementNodeName));
};
const testSvgAttributeName = (attributeName, attributeValue) => {
const elementNodeName = "rect";
const nameIsValid = testSvgAttributeNameValidity(elementNodeName, attributeName);
if (!nameIsValid) attributeName = 'data-' + attributeName;
const element = document.querySelector(elementNodeName);
element.setAttribute(attributeName, attributeValue);
};
testSvgAttributeName("fill", "yellow");
testSvgAttributeName("price", "expensive");
console.log(document.querySelector('svg').innerHTML);
#someId {
color: green;
}
<svg height="55">
<rect x="10" y="10" width="80" height="40" stroke="red"/>
</svg>
<div>
<p>Hello world</p>
</div>
Hide result, .