Is it possible to give a HTML element a new custom attribute?
You know how a "img" html element has the attribute .src:
imgEle.src = "";
Can I dynamically give a HTML element my own custom attribute .animationInterval? Is it as simple as this?...
imgEle.animationInterval = setInterval(...,10);
Maybe I do it the xml kindof way?...
imgEle.setAttribute("animationInterval", setInterval(...));
Whats the best way to do this?
The best way is to use html5 data- attributes:
$(imgEle).attr("data-animateinterval", "12");
Which can then be read back with
$(imgEle).data("animateinterval");
Which of course can also be added directly to your markup
<img src="foo.png" data-animateinterval="12" />
Also, if you're not concerned about whether a new attribute is added to the actual html element, but just want some arbitrary data associated with it, you can simply do this:
$(imgEle).data("animateinterval", "12");
And retrieve it like this:
var animateInterval = $(imgEle).data("animateinterval");
Note however that as Esailija explains, this may or may not actually add a new attribute to your element; it may just store this data internally. If that's not a concern for you, and I can't think of any reasons why it should be, then you may prefer this more succinct syntax.
To be clear, no matter which way you store it, $(imgEle).data("animateinterval"); will still work just fine.
The first way (element.something) sets a property and can be anything.
Th second way (element.setAttribute) sets an attribute, which must be a string (or serialisable as one via its toString() method).
So in this case either way works, but I would recommend the first.
Related
Kind of a newbie to this but I have followed a totorial on a memory game as an attempt to understand the syntax of JS but am stuck on making the round result print in a instead of showing up as a alert
here is a codepen here.
how can I print round in a <span> <!-- result here--> </span> rather than like this alert("result")
How can I make it set to a span instead of being an alert?
Browsers parse HTML into a tree of objects called Document Object Model (DOM). Using JavaScript you can query the DOM to get individual nodes, and then change them.
To get your span, you would typically use document.getElementById or document.querySelector (there are other functions that can fetch collections of related nodes, like document.getElementsByClassName or document.querySelectorAll). The former identify nodes by the property named in the method name (ID, or class name, respectively); the latter ones use CSS selectors. (All of the getElement... functions can be replicated using the newer querySelector and querySelectorAll interface, though you have to know how to use CSS selectors. I almost never use getElement... functions any more.) There are also functions that use XPath, though this is a bit more advanced subject.
Once you have the node, you can change its content using e.g. .textContent or .innerHTML properties, the former being for plain text, the latter for HTML.
For example, if this is the only span on the page, this suffices:
document.querySelector('span').textContent = "Result";
<span></span>
If on the other hand you have more of them, you would need some way to target the correct one. I will also demonstrate how you can style it using HTML:
const node = document.querySelector('#result_goes_here');
node.innerHTML = "<strong>Result</strong> in bold!";
<span id="result_goes_here"></span>
If you are trying to add the result inside the HTML SPAN and not in the alert box. You can do it something like this:
document.getElementById("span_ID").innerHTML = the_variable_result_here;
Hope that helps!
So I'm using this code to:
$('.something').on('click', function () {
console.log($(this).data('id'));
}
And for some reason, if I modify the data-id using the inspector, jQuery still sees the id that was there in the beginning. However, I tried the same thing using JS and it does see the changes. This makes me wondering if jQuery caches in some way the elements selected and uses them instead of the actual DOM.
Can someone please explain what happens and how jQuery does the event binding in the background?
Later edit: I want to specify that I'm talking about the "data-" attribute that I put in the HTML, not about the '.data()' provided by jQuery. Not sure if it's the same thing.
jQuery caches elements selected?
No. But the data managed by data is stored in an object cache maintained by jQuery, keyed by a unique identifier jQuery adds to the element (so it can look up the data). data is only initialized from data-* attributes, it is not an accessor for them. It's both more and less than that.
If you're interested, you can see that as an "expando" property on the element instance, it'll start with "jquery" and have a long number attached to it (currently; it's undocumented — for good reason — so this may change):
var foo = $("#foo");
console.log(foo.data("info")); // hi there
console.log("Expando name: " + Object.getOwnPropertyNames(foo[0]).find(name => name.startsWith("jQuery")));
<div id="foo" data-info="hi there"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
I'm trying to change the id 'character' to 'characterSelected'
var character = document.getElementById('character');
var characterSelected = document.getElementById('characterSelected');
function klik() {
character.innerHTML = characterSelected;
}
character.addEventListener('click', klik);
This is what I have so far but it doensn't seem to work. I want to do this using Javascript only, no jQuery.
Thanks
You tried something, it didn't work. Now is the time to look up the standard properties and functions you're using incorrectly. If guessing doesn't work, always look for reliable documentation.
A good reference would be the Mozilla Developer Network (MDN). It's a wiki-style encyclopedia about the web, its standards and current browser compatibility. If you look at the page about innerHTML, you'll find the following:
The Element.innerHTML property sets or gets the HTML syntax describing
the element's descendants.
This means that the innerHTML property is used to replace the content of a tag as if you wrote that HTML inside it. Not what you want.
What you wanted was to change the id of an element. If you search for element id, you'll land on the Element.id page. And how practical, there's an example:
var idStr = elt.id; // Get the id.
elt.id = idStr; // Set the id
However, this is not going to fix your issues. You see, you guessed wrong when trying to use the getElementById function. This function looks at the page and finds the element with that id right now. If you don't have any element with the characterSelected id at first, then this variable you set is going to be null for the rest of time. Variables won't magically update when an element with that id is placed in the page.
And finally, you have missed the purpose of the id attribute itself.
Its purpose is to identify the element when linking (using a fragment
identifier), scripting, or styling (with CSS).
The purpose of an id is to identify an element uniquely. You might think: "that's what I'm doing". No. You're using an id to represent whether or not an element is selected. This is wrong. Depending on your objective, I would say: just store the selected element inside a variable. Then whenever you need to do something with the selected element, it's in that variable. If you need specific style for that element, then you could set a class to it. But the id isn't meant for this at all - in fact, an id isn't meant to change once an element is placed.
I am wondering if the html class attribute should only be used for styling. Is there any drawback to using the class attribute as a variable. The W3 spec http://www.w3.org/TR/html5/dom.html#classes does not specify one way or another but, all examples and training point in the direction of styling only for multiple objects.
In my case I want to use the class attribute as variable that matches the key value in a object array. For example in my Javascript code I have an object that has a number of key/value pairs. On my web app I have a number of save buttons. When a save button is clicked I grab the parents class attribute value and use it as the key for the object to know which value to change. The class attribute on the parent has not other value than to let me know which key value pair to change in my object
While I'm sure it's possible to use classes that way, it's certainly not their intended purpose. html has data attributes that provide the functionality you want, for example
<button data-key="some value" name="" id="">click me</button>
You can then get that value (onClick if you like) and use it as a key for your object/data structure. Theres a good overview here
While it is not bad, it neither is best practice.
You can, instead of using the class attribute, define explicit data attributes. Using the class attribute would mean that you could not use several classes (because that would be a weird key to search for in an object, right?).
For instance:
<div class="any classes you like" data-mykey="searchforthiskey">
<button></button>
</div>
In jQuery:
$('button').click(function() {
var key = $(this).closest('div').attr('data-mykey');
});
From a functional perspective, there's no reason to NOT use the class attribute to store information about that element. You can access a class attribute as easily as you can a data attribute.
From a standards perspective, it is probably better to use a data attribute. Why? Well, if you are the only person working on your front-end, no big deal. If you are one of many on a team of front-end developers, who works specifically on the javascript side of things, you may run into a conflict with another front-end developer who works on the HTML/CSS side of things. They may remove a class from the element, not realizing that its also being used as your javascript hook into that element. In that case, you're better off creating your own data attribute, which then makes it clear that this attribute is probably data related and won't be molested by someone just trying to fix the styling of that element.
I'm trying to find a "best" method for dynamically loading files, and other elements by using the new html 5 "data-" attribute for storage and then removing it when needed.
My Question:
How do I target the "data-" attribute and remove it thus leaving the remaining attribute name?
For example, this:
<!-- Custom CSS -->
<link rel="stylesheet" class="custom" data-href="css/mobile.css">
Would turn into this:
<!-- Custom CSS -->
<link rel="stylesheet" class="custom" href="css/mobile.css">
Edit: This entire experiment is for Responsive Design (ui/performance), I need to be able to load css files/ elements depending on device resolution. This will result in higher performance for smaller devices to prevent unnecessary data loading. I'm using enquire.js plugin (amazing btw), which allows you to have functions fire off when a media query is targeted. So in an effort to stay current I wanted to use the "data-" attribute to add/remove elements from the DOM depending on device resolution.
This tutorial by Christian Heilmann does just this:
http://christianheilmann.com/2012/12/19/conditional-loading-of-resources-with-mediaqueries/
I'm trying to combine his technique with enquire.js
Assuming you know how to get to your elements, enabling is a one liner:
$(element).attr("href", $(element).data("href"));
since the data-href does nothing, you don't need to remove it. Just mirror it as real href attribute. To invalidate, either invalidate the href attribute again:
$(element).attr("href", false);
or remove it altogether:
$(element).removeAttr("href");
And for <img> it's the same trick but with the string "src" instead of "href"
While I agree that it's worth questioning whether this is the correct way to approach this problem, from a technical stand-point this is how you access, remove, and add attributes on elements.
$('[data-attrName]').each(function() {
var $el = $(this);
var val = $el.attr('data-attrName');
$el.removeAttr('data-attrName')
.attr('attrName', val);
});
To replace all data-attributename attributes with attributename can be accomplished simply by looping over the data object.
$(element).each(function() {
var
el = $(this),
data = el.data();
$.each(data,function(key,value) { el.attr(key,value); });
});
I'll point out what others have already pointed out, though - I think you have decided that this is what you need to do to accomplish something, when it probably isn't what you should be doing.
Try asking a question whose answer will solve your actual problem, not asking a question whose answer will solve the problem that you are experiencing when you are using it to try and solve another problem....I'll understand if you don't understand that last sentence.