Is it possible to add attribute to elements within shadow root? - javascript

so i'm using javascript and what i've done is capture a nodeList of shadowroot buttons within a webpage. I need to add attributes to each of them. Is there a way to do so? I've done it to other elements (not shadowroot) by using the .attr() but it appears shadow-roots act differently?
An example of a previously used code I had that is non shadow-root is the following:
elements.eq(i).attr("custom-attr", "analytics-purposes-only" +
elements.eq(i)..text().trim());
thank you in advanced.
also to note, this is my first time interacting with shadow-roots so things are new to me for this one.

Related

How to avoid locking my HTML structure when using jQuery to create rich client experiences?

I've had this happen to me three times now and I feel it's time I learned how to avoid this scenario.
Typically, I build the HTML. Once I'm content with the structure and visual design, I start using jQuery to wire up events and other things.
Thing is, sometimes the client wants a small change or even a medium change that requires me to change the HTML, and this causes my javascript code to break because it depends on HTML selectors that no longer exist.
How can I avoid digging myself into this hole every time I create a website? Any articles I should read?
Make your selectors less brittle.
Don't use a selector by index, next sibling, immediate child, or the like
Use classes so even if you have to change the tag name and the element's position in the HTML, the selector will still work
Don't use parent() or child() without specifying a selector. Make sure you look for a parent or child with a specific class
Sometimes, depending on the amount of rework, you'll have to update the script. Keep them as decoupled as possible, but there's always some coupling, it's the interface between script and HTML. It's like being able to change an implementation without having to change the interface. Sometimes you need new behavior that needs a new interface.
I think the best way to help you is for you to show a small sample of a change in the HTML that required a change to your jQuery code. We could then show you how to minimize changes to JS as you update the HTML

Set variable to HTML elements with certain class?

I'm sure there is a way to set a JavaScript variable to any HTML element with a certain class attached to it? I'm just not sure how to write it. Can anyone help me out?
The best way would be to use a framework, such as jquery, that makes an easy use of (css) selectors, e.g, to select all elements with class my-class do
$('.my-class')
and then apply any code to the list of those elements
edit: don't forget to use the $(document).ready wrapper
you could simply go var x = document.getElementById('somediv'); for example. Now whatever style class pertains to somediv will of course still obtain unless you change it programatically in your javascript.
Hope that helps -- might be able to be more helpful if you give a broader context of what you are trying to accomplish.
To do this without document.getElementsByClassName('myclass') nor $(.'myclass') would be difficult and require some advanced tactics. You would have to recursively generate a list of all DOM objects from the document. While generating the list, every element touched would have to be tested for .className = 'myclass'. This is essentially what jquery does behind the scenes, although I believe on page load it caches the whole DOM for easier querying.

A convention for indicating whether an HTML element is referenced from JS code

This is a follow-up question for In jQuery is it a bad idea to use name=X for all selectors?
I am using Backbone and decided that I wanted a way to differentiate between HTML elements that were bound and those that were not.
So I would write (in HAML):
.container
.title(name='title')
.separator
As you can see it's clear that the dynamic element is title.
The reason for this was so I could mess around with the style and rename classes without worrying about breaking the app. It also means in the template I can tell what the dynamic elements are without needing to go back and forth with the Backbone View.
My question now is, without using the [name] selector, does anyone have a code convention to keep track of which HTML elements are referenced from JS.
I have considering:
Using a common prefix on class names (e.g. class=bind-title)
Using some sort of custom HTML element (
Thanks!
FYI: I'm using CoffeeScript, Backbone and haml_coffee templates.
Updated jsperf to test all suggestions:
http://jsperf.com/class-or-name-attr-lookup/3
I would consider using a class to indicate that it is dynamic.
I'm not sure if you are aware of this but you can have multiple classes on one element. Like so:
.container
.dynamic.title(name='title')
.separator
This works in traditional HAML but I have not tried it with haml-coffee. If it doesn't work, you might have to specify the class like .title{:class => "dynamic"}(name='title').
I prefer this over a prefix on the class name because it's more semantically meaningful, which is how HTML should be used.
I am using data-view attribute on elements being set when rendering my Views.
This helps me to then show a tooltip in a browser window when I hover over View(s).

Best way to manipulate dom element attributes with javascript/jQuery

I want some return about dom manipulation. I think we can save elements' status in several ways. For exemple, you want to make an element "inserted", what do i have to use? :
Add css class as "inserted"
Save an attribute with .data("inserted",true)
Push my element in a global array containing all "inserted" elements
...
But what is the best way? Maybe the solution is to use all possibilities. I don't know.
That's a general question. I don't have a specific problem, but i am starting developing a huge javascript application and i want to choose my rules :)
Do you want selected elements to look in a specific way?
--> Use the css-class
Do you want to check whether a specific element is selected at a different place in code?
--> Use .data
Do you want to do something to all selected elements?
--> Use an array.
If you plan to do multiple of the things above, you can also combine the approaches.
If you want a visual element to accompany the status, then the CSS class is the obvious way to go.
Data elements are a perfectly valid way of tagging something as well.
If you want to persist state, then saving element status in a JSON structure may be a good option. The JSON data is the "master model" and the elements are rendered based on its model. The JSON data can be passed to the server or to the next page easily.
This is a hard question to answer generally because it really depends on the needs of your application. How many elements do you need to evaluate at any given time? A dozen? A few thousand? What else do you need to do with these elements when you select them? Basic guidelines are:
Don't add a selected class unless you really need to change the style of the element.
If you need to traverse to an element based on whether it has been selected or not, do not use the data() option.
Do not cache the selected elements in memory (variables or localStorage or whatever) if you don't need them to persist for more than one simple call. The overhead of managing your array of selected elements is only worth it if you have a noticeable performance gain or need to persist the data.
So, what do you really need to do with these elements? With more information about your situation, we can make a better recommendation.
For me this depends on what the use of the status will be...
If layout changes depending on selected, i use a class
JS logic (more than only styling) -> atribute
I hardly use classes to add js logic to elements ... css tends to change more often than the underlying javascript files. In case I use classes in js, I force myself to keep the classnames and selectors in css or just redo all element-selection in both js and css when one needs to change (for instance because of using another library or css templates)
as for your third option, an attribute can give you an array of all selected alemens useing a jquery selector $('*[selected]')
if things get complicated I put enhanced dom elements into "classes"
var InserttMe = function(element){
this.element = element;
this.inserted= false;
};
selectMe.prototype = {
insert: function(){
this.inserted= true;
//do whatever you do with your element
}
}

What's the best way to get a list of the contents of a specific group of DOM elements in javascript?

The basic scenario: I've got a series of elements on an HTML page, generated dynamically. (Currently, they're all divs, but they don't need to be.)
What I want is a javascript function that will loop though all of those divs (or whatever) looking for the presence of a specific value.
What's the best, most cross-browser way to do this? Does getElementsByName() work on divs in all browsers? Can I give them all the same ID and get an array back out of getElementById somehow?
If I change those divs to spans or inputs, does that make things easier?
Thanks!
(edit: it would be best, for this project, if there was a solution without using any external js libraries. I assume jQuery has a function that does just this in one line, but for the moment I'd like to avoid opening that can of worms with the client.)
getElementsByTagName is defined in DOM Core, so any browser which implements that works. That's about every browser in current use.
Take a gander over here for the specifics: http://www.quirksmode.org/dom/w3c_core.html
One gotcha to be ware of, is that getElementsByTagName returns a NodeList - not an array. It works the same, but it is evaluated very late, so if you add/remove nodes to the DOM while traversing a NodeList, you will get weird results. In these cases, write two loops; First loop through the NodeList and store all entries in an array - Then loop through the array.
It doesn't matter what the elements are, but what does matter is where they are in the page. If they are all child elements of a single parent element, your problem is simple. Give the parent element an ID and you can use getElementById() to grab it and iterate its children.
getElementById() behavior is undefined when more than one instance of an ID is found in the document. Most will return the first Element they can find, but you certainly can't cound on getting an array.
getElementsByTagName() will work only if you can use some obscure tag that you are sure won't appear elsewhere in your page. You could augment this by specifying that the elements you are interested in will have an attribute present that you can check for (such as #class or #title). You can then loop through the result of getElementsByTagName() checking for this and only look at Elements where the attribute is present.
You can use this site to see what getElementBy most suites your needs.
There are some using libraries and some like troelskn wrote that apply for standard javascript in all supporting browsers.

Categories

Resources