how to find specific particular attribute in javascript - javascript

<div __jx__id="___$_15" style="position: absolute; overflow: hidden;">
I would like to modify the above div by adding display:block to the style using javascript
<div __jx__id="___$_15" style="display:block;position: absolute; overflow: hidden;">
I tried using
function getAllElementsWithAttribute(attribute)
{
var matchingElements = [];
var allElements = document.getElementsByTagName('*');
for (var i = 0; i < allElements.length; i++)
{
if (allElements[i].getAttribute(attribute))
{
// Element exists with attribute. Add to array.
matchingElements.push(allElements[i]);
}
}
return matchingElements;
}
getAllElementsWithAttribute('__jx__id="___$_15);
adapted from
Get elements by attribute when querySelectorAll is not available without using libraries?
the selector itself is not working let alone add the additonal display:block to the div

The name of your attribute is __jx__id and the value is ___$_15.
so try: getAllElementsWithAttribute("__jx__id");
If you also want to filter by the value of the attribute then you'll need to pass it in seperately: getAllElementsWithAttributeAndValue("__jx__id", "___$_15");

A lot easier with jQuery:
$("div[__jx__id]").css({display:block});
or even
$("div[__jx__id]").show();

Related

Get elements whose display is block

I am writing a chrome extension where I working on a webpage which lists some things. So, basically, I am reading that table and doing some calculation in the javascript and showing them. Now, there is a filter option on the webpage. After filtering, it doesn't show some things on the list according to the filter selected. And it does so, by making the display as none. It makes the display as none by doing something like below:
[data-assignee]:not([data-aggr-assignees*="|xyz|"]) {
display: none;
}
So, when I am trying to find the elements whose display is not none to see the filtered items, it is giving all items since looks like it is not changing the CSS property of the items. I checked the style.display values of all the elements and it is coming '' for all. Can someone help me in how can I get the elements whose display is block in this kind of case?
You can query selector the whole document with * and go through each element with a for loop to check if its inline display property is set to none. Of course, this will only handle cases when the element is hidden with inline CSS.
<div style="display: block;">
DIV
</div>
<span style="display: none;"></span>
<script>
var allElems = document.querySelectorAll("*");
var visibleElems = [];
var hiddenElems = [];
for(let i = 0; i < allElems.length; i++){
if(allElems[i].style.display != "none"){
visibleElems.push(allElems[i]);
} else {
hiddenElems.push(allElems[i]);
}
}
console.log("Visible elements: "+visibleElems);
console.log("Hidden elements: "+hiddenElems);
</script>
If you want to check the display property of the elements from the CSS stylesheet, you will need to use window.getComputedStyle.
.hidden{
display: none;
}
<div style="display: block;">
DIV
</div>
<textarea class="hidden"></textarea>
<span style="display: none;"></span>
<style>
</style>
<div class="hidden">
</div>
<select class="hidden"></select>
<script>
var allElems = document.querySelectorAll("*");
var visibleElems = [];
var hiddenElems = [];
for(let i = 0; i < allElems.length; i++){
if(allElems[i].style.display == "none"||window.getComputedStyle(allElems[i], null).getPropertyValue("display")=="none"){
hiddenElems.push(allElems[i]);
} else {
visibleElems.push(allElems[i]);
}
}
console.log("Visible elements: "+visibleElems);
console.log("Hidden elements: "+hiddenElems);
</script>

How do I change an attribute or class using only Javascript?

I would like to change the styling attribute values of all elements that have the class "post-feature" and contain an attribute value of "http"
So the div element will look like the following:
<div class="post-feature" style="backgroundimage:url(http://local.test.com/test_image.jpg);">
So far the http check works. But I am not able to set the attribute value.
I have the following code
var features = document.getElementsByClassName(".post-feature")
[0].getAttribute("style");
if (features.includes("http")) {
features.setAttribute("background-color", "orange");
} else {
alert('no change');
}
You can use querySelectorAll('.post-feature[style*="http"]') to find those elements.
Then simply iterate through them and i.e. set their background color with
element.style.backgroundColor = 'orange';
Now, if you want to make sure you only target elements having a background-image and http, you can use this selector:
querySelectorAll('.post-feature[style*="http"][style*="background-image"]')
Also, by adding an i (or I) just before the end bracket [style*="http"i], the value will be compared case-insensitively.
window.addEventListener('load', function() {
var elements = document.querySelectorAll('.post-feature[style*="http"]');
for (var i = 0; i < elements.length; i++) {
elements[i].style.backgroundColor = 'orange'; /* add propert value */
/* replace class
elements[i].className = 'myClass';
*/
/* add a class
elements[i].classList.add('myClass');
*/
}
/* temp log */
console.log('Found ', elements.length,' element(s)');
})
div {
height: 40px;
background-color: gray;
}
div + div {
margin-top: 10px;
}
<div class="post-feature" style="background-image:url(http://local.test.com/test_image.jpg);"></div>
<div class="post-feature"></div>
<div class="post-feature" style="background-image:url(http://local.test.com/test_image.jpg);"></div>
<div class="post-feature"></div>
Updated
To only change styling, like colors etc., you don't even need a script, you can use CSS alone
div {
height: 40px;
background-color: gray;
}
div + div {
margin-top: 10px;
}
/* for elements that contain "http" and "background-image" */
.post-feature[style*="http"i][style*="background-image"i] {
background-color: orange;
}
<div class="post-feature" style="background-image:url(http://local.test.com/test_image.jpg);"></div>
<div class="post-feature"></div>
<div class="post-feature" style="background-image:url(HTTP://local.test.com/test_image.jpg);"></div>
<div class="post-feature"></div>
As a note, and as discussed in a few comments, if to make sure it is the background-image property that also contain the http in its url(), you can adjust the selector to this, which as well can be used without any script, as a CSS rule
.post-feature[style*="background-image:url(http"i] {
background-color: orange;
}
The above selector can of course also be used in the first sample, like this
querySelectorAll('.post-feature[style*="background-image:url(http"i]')
First, you can use querySelctorAll() with a CSS query that selects the elements with the class you desire and, in most cases, you should use this instead of getElementsByClassName() as that returns a "live node list" that causes the DOM to be re-scanned every time you access it.
Next, setAttribute() is for setting HTML element attributes. You are asking to change the value of a CSS property. While that could be accomplished with setAttribute('style', value), it is very "old-school" and not the best approach, nor is getAttribute('style') the best way to read a CSS property value (it won't work if the CSS was set from a style sheet).
Also, your code is trying to access: backgroundimage, but the property is accessed as background-image when working in CSS and backgroundImage when accessing it via JavaScript.
To access the inline styles applied to an HTML element, just access the style property of that element, followed by the name of the CSS property you are interested in. For example:
var bColor = element.style.backgroundColor;
If the style has been applied to the element from an internal style sheet or an external style sheet, the above approach won't work for you and you'll need to get it another way, via window.getComputedStyle():
var bColor = window.getComputedStyle(element, null).backgroundColor;
But, note that getComputedStyle() doesn't always return the same value that you set - - it's the value after the browser has computed all factors. In this case, even paths that you wrote as relative references (without the "http") will be returned as absolute paths (with the http).
So, here is a modern approach that correctly checks only the background-image CSS property for the presence of http.
NOTE: This solution tests for http specifically in the background-image property. Unlike most of the other answers given, this code will correctly ignore http in other CSS properties besides background-image. Examine the CSS of the last div to see this in action.
// querySelectorAll() is more efficient than getElementsByClassName()
var features = document.querySelectorAll(".post-feature");
// Loop over the list
for(var i = 0; i < features.length; i++){
// Get access to the background-image property (called backgroundImage from JavaScript) value,
// convert that value to lower case and check to see if "http" is in that value
if(features[i].style.backgroundImage.toLowerCase().indexOf("http") > -1){
// Set the CSS background-color property (called "backgroundColor" in JavaScript) to orange:
features[i].style.backgroundColor = "orange";
// Just for testing:
features[i].textContent = features[i].style.backgroundImage;
} else {
alert("No change");
}
}
.post-feature { width:100%; height:50px; border:1px solid black; background-color:gray; color:yellow; }
<!-- The correct CSS property is "background-image", not "backgroundimage" -->
<div class="post-feature" style="background-image:url(http://local.test.com/test_image.jpg);"></div>
<div class="post-feature" style="background-image:url(test_image.jpg);"></div>
<div class="post-feature" style="background-image:url(http://local.test.com/test_image.jpg);"></div>
<div class="post-feature"
style="border-image: url('http:///images/border.png') 30 30 repeat;background-image:url(test_image.jpg);">I have "http" in one of my CSS properties, but not "background-image", so I shouldn't be orange.</div>
i think some wrong in your code, try this code
element.setAttribute("style", "background-color: orange;"); // bad
or
element.style.backgroundColor = "orange"; // good
Use element.style.backgroundColor and indexOf
var features = document.getElementsByClassName(".post-feature")[0].getAttribute("style");
if (features.indexOf("http") > -1) {
features.style.backgroundColor = "orange";
} else {
alert('no change');
}
check this fiddle
https://jsfiddle.net/vywk72j8/2/
<div class="post-feature" style="background-image:url(http://local.test.com/test_image.jpg);">
tt</div>
var feature = document.getElementsByClassName("post-feature")[0];
if (feature.style.backgroundImage.indexOf("http") !== -1) {
feature.style.backgroundColor = "orange";
} else {
alert('no change');
}
In your code, you are fetching the attribute value in features
var features = document.getElementsByClassName(".post-feature")
[0].getAttribute("style");
Here features is a string containing attribute value, not an element so you cannot use it to set value.

Changing properties of all <hr> html elements

In css I have set all the <hr> elements in my html to "display:none;" which works.
I have an onclick event listener set up to change the "display" to "block".
I use:
document.getElementsByTagName("hr").innerHTML.style.display = "block";
I get an error "Cannot read property 'style' of undefined".
Do it the following way:
var hrItems = document.getElementsByTagName("hr");
for(var i = 0; i < hrItems.length; i++) {
hrItems[i].style.display = 'block';
}
This is incorrect in two ways
getElementsByTagName gives you a list on elements and there is no method to operate on all elements, so you'll have to loop through all of them and add the required style individually.
innerHTML returns a string containing the mark up in an element but <hr> doesn't have any thing in it and the style property is on the <hr> itself.
var hrs = document.getElementsByTagName("hr");
for(var i = 0; i < hrs.length; i++) {
hrs[i].style.display = 'block';
}
Simple (and very effective) solution:
tag your body with a class-element
<body class="no_hr"> <article><hr/> TEXT Foo</article> <hr/> </body>
in css don't hide hr directly, but do
.no_hr hr {
display:none;
}
now define a second style in your css
.block_hr hr{
display:block;
}
in your buttons onClick, change the one and only body class from no_hr to block_hr
onclick() {
if ( document.body.className == "no_hr" ) {
document.body.className = "block_hr";
} else {
document.body.className = "no_hr";
}
}
This is a very charming solution, because you don't have to iterate over elements yourself, but let your browsers optimized procedures do their job.
For people who want a solution that doesn't require JavaScript.
Create an invisible checkbox at the top of the document and make sure that people can click on it.
<input type="checkbox" id="ruler"/>
<label for="ruler">Click to show or hide the rules</label>
Then tell the stylesheet that the <hr>s should be hidden by default, but should be visible if the checkbox is checked.
#ruler, hr {display:none}
#ruler:checked ~ hr {display:block}
Done. See fiddle.
getElementsByTagName() returns a node list, and therefore you must iterate through all the results. Additionally, there is no innerHTML property of an <hr> tag, and the style must be set directly on the tag.
I like writing these types of iterations using Array.forEach() and call:
[].forEach.call(document.getElementsByTagName("hr"), function(item) {
item.style.display = "block";
});
Or, make it even easier on yourself and use jQuery:
$("hr").show();

getElementById with changing IDs

I need to hide all the elements that have the string "replies-36965584" anywhere in their IDs.
HTML:
<div id="replies-36965584_1">aaaa</div>
<div id="replies-36965584_2">aaaa</div>
<div id="replies-36965584_3">aaaa</div>
<div id="replies-36965584_4">aaaa</div>
<div id="replies-36222224_2">nnnn</div>
JavaScript:
document.getElementById("replies-36965584").style.display="none"
How can I modify this JS to select the first four elements?
You can do this with CSS and attribute selectors.
[att^=val]
Represents an element with the att attribute whose value begins with the prefix "val". If "val" is the empty string then the selector does not represent anything.
Source: http://www.w3.org/TR/css3-selectors/#attribute-substrings
jsfiddle
CSS
[id^="replies-36965584_"] {
display: none;
}
Is using jQuery an option? If so, this is dead simple:
$(document).ready(function(){
$('div[id^="replies-36965584"]').hide();
});
If you're unfamiliar with jQuery, here's a link to get started: http://learn.jquery.com/javascript-101/getting-started/
EDIT: Fixed syntax error.
EDIT: Added jsFiddle: http://jsfiddle.net/xbVp9/
If you don't know certain literal values but you know the general pattern and only the number will change, then I will consider some matching with regular expresiion.
You can do it the painful way:
var o = document.getElementsByTagName("div");
for (var i=0;i<o.length;i++) {
if(o[i].id.indexOf('replies-36965584') == 0) {
o[i].style.display = 'none';
}
}
The only way to do this with vanilla javascript that I know of, is to fetch all the divs on the page, and test the id's for the ones you want.
var divs = document.getElementsByTagName('div');
for (var i = 0; i < divs.length; ++i) {
var div = divs[i];
if (/replies-36965584/.test(div.id)) {
div.style.display = 'none';
}
}

Selecting a div by classname

I got this div...
<div tabindex="0" class="button-base inline-block button aw-btn button-base-active">
<input type="text" tabindex="-1" style="opacity: 0; height: 1px; width: 1px; z-index: -1; overflow-x: hidden; overflow-y: hidden; position: absolute; ">
</div>
in the middle of my page, it has no id and I am unable to edit the pages HTML, I am also no able to use jQuery. Also trying to do it with IE7 and IE8.
Nightmare here :)
The solution would be document.getElementsByClassName but that is not ie7 and ie8 compatible.
This div is buried in about 10 divs, all of which are similar style with no id's etc. The classes on this div are unique!
The only solution I can see is to get ALL divs and loop them looking for hasAttriutes similar.
Anyone have a better idea?
Here's a cross-browser implementation of getElementsByClassName for non-compliant browsers (citation):
if (!document.getElementsByClassName)
{
document.getElementsByClassName = function(classname)
{
var elArray = [];
var tmp = document.getElementsByTagName("*");
var regex = new RegExp("(^|\\s)" + classname + "(\\s|$)");
for ( var i = 0; i < tmp.length; i++ ) {
if ( regex.test(tmp[i].className) ) {
elArray.push(tmp[i]);
}
}
return elArray;
};
}
Nope, that's how it's done. Unless they're in something with an ID you're stuck iterating all DIVs on the page. Fortunately it is just a list though (no need to recurse through a tree) so it's not so bad.
I would suggest using XPaths to select the nodes. Might work...
Use jQuery/Sizzle. IE6 and up. :)
Load it:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
Use it:
jQuery('.class.otherclass.anotherclass')

Categories