Most efficient way to select a set of elements? - javascript

I've always used class names to select sets of related elements. e.g.
<input type="checkbox" value="1" class="checkbox_set_1">
<input type="checkbox" value="2" class="checkbox_set_1">
<input type="checkbox" value="3" class="checkbox_set_1">
$('.checkbox_set_1').filter(':checked') ...
I do this because I know jQuery can delegate to document.getElementsByClassName which should be pretty fast. However, adding classes to all the elements I want to select but not style seems kind of dirty. Isn't there some overhead when the browser has to check checkbox_set_1 against its stylesheet to determine if my checkboxes need styling? Plus, there's some risk of accidental styling if I haven't named my classes nicely.
Is there a better way to select elements that doesn't rely on an attribute meant for styling, without giving up the performance benefits? Or more specifically, is there an attribute other than class (used for styling) and id (limited to a single element) that the browser will optimize queries for?
There are many other attributes to pick from, including data-* attributes, but I don't think the browser optimizes lookups on anything other than id and class, does it?

Isn't there some overhead when the browser has to check checkbox_set_1
against its stylesheet to determine if my checkboxes need styling?
Styling isn't determined that way. The browser doesn't take each attributes of an element and look for rules that apply, instead it looks through the rules once and determine which ones applies to the element.
If you are concerned with adding classes to a lot of elements, you can use selectors that make better use of the document structure, for example setting a class on the element containing the checkboxes and use something like $('.CheckboxContainer :checked').
That might not be quite as efficient as setting classes on every element that you want to target, but in most cases the difference is far from noticable. You shouldn't bother too much about efficient selectors until it's an actual problem. After all, you are using jQuery because it's convenient, not to get the best performance.

Yes, it behaves analouge to the "Marker-Interface in java" and you will find the anti-pattern-description of Tom Butler.
If you have a form around, you could use elements (but you must filter other elements) this is faster than calling a method like "getElementsByClassName".
Example
var lst = jQuery(document.foo.elements);
document.write(lst.length);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form name="foo">
<input type="checkbox" value="1" />
<input type="checkbox" value="2" />
<input type="checkbox" value="3" />
<input type="checkbox" value="4" form="bar" />
</form>

Related

Complex CSS selector - how to require visible

I'm writing a CSS selector, which I have working so far:
input[placeholder*='mail']
but I'd like to ensure it's not finding invisible (ie: not visible) elements.
I've been trying :visible in various places in the pattern (because I couldn't find a good reference on the CSS selector lexer, but not luck with these:
input[placeholder:visible*='mail']
input:visible[placeholder*='mail']
input[placeholder*='mail']:visible
How do I do this? And anyone have a good reference on learning more complex selector formats?
:visible is a jQuery selector. Not a CSS one.
And you can't use it on an element's attribute like placeholder.
To check if there is an inputted value (which makes the placeholder "not visible"), you need to use some client-side code.
The jQuery would look like this:
$("input[placeholder*='mail']").each(function(){
if( $(this).val() != "" ){
// Do something.
// ...
}
});
To "filter out invisible elements" and keep only the visible ones:
var visible = $("input[placeholder*='mail']:visible").length;
console.log(visible+" elements are visible.");
.hidden{
display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="one" placeholder="My mail">
<input type="text" id="two" placeholder="Your mail">
<input type="text" id="three" class="hidden" placeholder="Junk mail">
<input type="hidden" id="four" placeholder="Cool mail">
There is no CSS selector for :visible. You sould then work with classes and target the elements which have the class .visible. (Or NOT have the class .visible.
The :visible selector is only available in jQuery for example, which uses the pseudo selector for finding elements visible in current scroll view.
You can't do it with only CSS.
But you can do it with jquery and most probably this answer can help you.

Using the for attribute in JSX - linter unknown property "for"

I have a label with an input. I want to make the whole label area clickable to trigger the input (a checkbox). So I have used the for attribute as I believe this is exactly what it is intended for:
<label for={id}>
<input
name="checkbox"
type="radio"
data-id={id}
/>
</label>
Functionally this works but the linter does not like it:
error Unknown property 'for' found, use 'htmlFor' instead react/no-unknown-property
htmlFor does not appear to have the same functionality as the for attribute.
How can I change my code to make it work whilst retaining the functionality of for - I'd rather avoid writing a custom function that selects the correlating checkbox when you click on the label when that functionality already exists with for
Nothing special you need to do.Try This,
<input
name="checkbox"
type="radio"
data-id={id}
/>
<label htmlFor={id}></label>
Just replace for with htmlFor.
As in React class becomes className, for becomes htmlFor.
If you do document.getElementById you will have to access for property as label.htmlFor, as under the hood JavaScript uses htmlFor.
You can read about it here : prop_label_htmlfor, React htmlfor
Eslint suggestion for reference :

Inject Javascript to select all radio buttons with specified value

Slightly odd question, but I'm trying to find a way (if possible) to select all radio buttons that have the same value. We regularly get hundreds of spam accounts signing up on our website, and it would be easier to set all radio buttons to "Reject" and double-check to make sure there's no legitimate ones, as opposed to constantly clicking on a radio button. (Lazy is my middle name, yes.)
Is this possible? If so, how? I haven't got access to the actual web pages to code in a button to do just this yet, but it's something I'm looking at long term. Right now though, I need something quick and dirty to do what I want it to do. I'm using Chrome, and can use Greasemonkey if that's required.
The value to select by is "reject".
A snippet of code that's being used. If it's of any consequence, our forum is running Xenforo:
<li>
<label for="ctrl_users16667action_reject">
<input type="radio" name="users[16667][action]" value="reject" class="Disabler" id="ctrl_users16667action_reject">
Reject and delete with rejection reason:
</label>
<ul id="ctrl_users16667action_reject_Disabler" class="disablerList">
<li>
<input type="text" name="users[16667][reject_reason]" value="" size="45" placeholder="Optional" class="textCtrl" id="ctrl_users16667reject_reason">
</li>
</ul>
</li>
You're looking for a bookmarklet or a GreaseMonkey (or TamperMonkey or similar) script.
Re bookmarklets, you can use the javascript: pseuedo-protocol to run script on the page you're looking at from your bookmarks manager. Just make the URL in your bookmark:
javascript:(function() { /* ...your code here ...*/ })();
Because it has to be URI-encoded, you can find "bookmarklet generators" out there to handle that part for you.
Alternately, there are GreaseMonkey, TamperMonkey, and similar add-ons/extensions for browsers.
Then it's a trivial matter of selecting the relevant radio buttons:
$('input[type=radio][value="reject"]').prop('checked', true);
So if jQuery is already loaded on the page in question, you could use this as a bookmarklet:
javascript:(function(){$('input[type=radio][value="reject"]').prop('checked',true);})();
Use :radio to get radio buttons, then for filtering use attribute equals selector
var $ele = $(':radio[value="reject"]')
or filter()
var $ele = $(':radio').filter(function(){ return this.value == 'reject'; });
FYI : It's a jQuery solution and it only works if you are loaded jQuery library in the page.
Try this it will work
$("input:radio[value=reject]")
you have to give unique name to all radio buttons then you can select multiple radio buttons using javascript
you have to give same class to radio button
<input type="radio" name="radio[]" class="my_class" value="1" />
<input type="radio" name="radio[]" class="my_class" value="1" />
<input type="radio" name="radio[]" class="my_class" value="0" />
$(".my_class").each(function(){
if($(this).val() == "1"){
$(this).attr('checked','checked);
}
});
Thanks

jquery can't hide a form with an input name of "style"?

I am trying to hide a form on a site, but it refuses to hide via jquery. I can manually set the style properties on the element, but .hide() does not hide it.
Consider this code:
$(document).ready(function() {
$('form').hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form>
<input name="style_name" value="small" type="hidden">
<p>I AM hidden</p>
</form>
<form>
<input name="style" value="small" type="hidden">
<p>I should be hidden</p>
</form>
Basically, if there is an input with a name of "style" it can't hide the form. If the input has a different name, it hides it just fine.
Is there a reason this is happening?
The "name" attributes of input elements in a form are used to populate properties on the form DOM node. Your name, "style", overrides the "style" property of the form, which means that jQuery can no longer access the native style object. It needs to do that in order to hide the form.
Note that you can still do this with CSS.
$(document).ready(function() {
$('form').addClass("hidden");
});
CSS:
.hidden { display: none; }
Those old habits of implicitly trampling over namespaces dates from the early days of browser technology. It's hard to imagine anyone thinking it's a good idea nowadays, at least without there being some qualified sub-space (like form.fields or something).

How to reach javascript object property

I have some radio buttons like to
<input type="radio" checked="checked" value="0" id="paramsmenu_images0" name="params[menu_images]">
I would like to reach this in javascript somehow like this:
console.log(document.adminForm.params[menu_images]);
Of course it doesn't work, so how can I reach it?
Is this OK?
document.getElementsByName('params[menu_images]')
You can also iterate over document.adminForm.elements to find your form element...
document.getElementById('paramsmenu_images0') will give you the dom element if that's what you want.

Categories