I do not know how to access a specific CSS using javascript.
Let us say,
#menu { color: red; }
can be accessed by
document.getElementById('menu').style.color = "blue";
But I want to access
#menu li a { height: 10%; }
How do I access that using document.getElementById() ?
Plain JavaScript solution:
You cannot use getElementById() in this case since its purpose is only to query id attributes, but you can use getElementsByTagName() in context of #menu:
var m = document.getElementById('menu');
// Get all <li> children of #menu
var lis = m.getElementsByTagName('li');
// Loop over them
for (var i=0; i<lis.length; i++) {
// Get all <a> children of each <li>
var atags = lis[i].getElementsByTagName('a');
for (var a = 0; a<atags.length; a++) {
// And set their color in a loop.
atags[a].style.color = 'blue';
// or change some other property
atags[a].style.height = '25%';
}
}
jQuery Solution:
If you are able to use jQuery, this becomes exceedingly simpler:
$('#menu li a').css('color', 'blue');
You don't; you'd have to find all the <a> tags that matched that criteria.
The .getElementById() function is about getting an element by a unique "id" string. If you need to get elements otherwise, there are other APIs to use: .getElementsByTagName(), .getElementsByClass(), .querySelectorAll(), etc. Browser support varies, and even .getElementById() is different between IE and other browsers.
Related
I've got the following code:
<div id="header">
white link
white link
white link
white link
</div>
<div id="some_other_div>
unnafected link ...
What I want to do it modify only the <a> tags inside the header div in a similar way to:
#header a {
color:white;
}
using only Javascript. How would I go about it?
You can use the same CSS selector with querySelector() method.
var ele = document.querySelector('#header a');
ele.style.color = 'white';
If there are multiple elements within the div then use querySelectorAll() and iterate over them to update the style property. You can iterate over the collection using simple for loop or Array#forEach method with [].slice.call or Array.from method(for converting into an array).
var eles = document.querySelectorAll('#header a');
[].slice.call(eles, function(ele){
ele.style.color = 'white';
})
here the solution:
var elements = document.querySelector('#header a');
var i;
for (i = 0; i < elements.length; i++) {
elements[i].style.color = 'white';
}
I have a CSS selector #menu li {background-color: red;}.
I want to access its attributes in JavaScript. It's important that I need to access both #menu and li since #menu alone has different attributes. It seems like getElementById(menu li), QuerySelector and getComputedStyle are not working in this case.
Is there any other way to achieve that or am I missing something here?
You should use jQuery for this, here the easy code example
//html
<div id="menu" data-number="123" >
</div>
//jquery
var menu = $('#menu').attr('data-number');
console.log(menu);
//print 123
jquery version
https://jsfiddle.net/pn52uvw1/
$(".button_1").click(function(){
alert($("#menu").attr("data-item-id"));
})
$(".button_2").click(function(){
alert($("#menu li").attr("data-item-id"));
})
non jquery version
https://jsfiddle.net/pn52uvw1/2/
window.firstFunction = function(){
var target = document.getElementById("menu");
alert(target.getAttribute('data-item-id'));
}
window.secondFunction = function(){
var target = document.getElementById("menu").children[0];
alert(target.getAttribute('data-item-id'));
}
but you will need to get rid of that [0] index probably, and use a for or something for multiple li items
If you want to get that css rule's property, you can do like this:
function getStyleFromSelector(selector, styleName) {
// Get all style elements
var styles = document.styleSheets;
var styleIndex = 0, styleCount = styles.length;
var rules, ruleCount, ruleIndex;
// Iterate though styles
for (styleIndex = 0; styleIndex < styleCount; ++styleIndex) {
// Get the css rules under the style.
rules = styles[styleIndex].rules;
ruleCount = rules.length;
for (ruleIndex = 0; ruleIndex < ruleCount; ++ruleIndex) {
// Check if the selector match the one we want
if (rules[ruleIndex].selectorText === selector) {
return styleName ?
rules[ruleIndex].style.getPropertyValue(styleName) : rules[ruleIndex];
}
}
}
}
var div = document.getElementById("results");
var result = getStyleFromSelector('#menu li');
console.log(result);
div.innerHTML = 'background-color is : ' + result.style.backgroundColor;
console.log(getStyleFromSelector('#menu li', 'background-color'));
#menu li {background-color: red;}
<div id="results"></div>
You can try it without additional Libraries with the following
var len = document.querySelectorAll("#menu li").length;
for(i = 0; i<len; i++)
document.querySelectorAll("#menu li")[i].style.backgroundColor="blue";
I also made you (a not very beautiful) jsfiddle
https://jsfiddle.net/gmeewsmz/
I have an HTML page having css class for a control with following definition:
.ms-crm-Inline-Edit select.ms-crm-SelectBox {
border: 1px solid #CCCCCC;
font-size: 12px;
margin: 1px 0 0 1px;
width: 100%;
}
I need to add a new attribute to this class as follows:
height: "120px !important";
This has to be done through Javascript. I can't modify origional class definition that's why I have to add Javascript function which does this job. For that purpose I have written Jscript method but its not working.
function CustomizePicklistHeight ()
{
document.getElementsByClassName('ms-crm-Inline-Edit select.ms-crm-SelectBox').style.height = '120px !important';
}
I guess, first we have to add height attribute to this class but I dont know how to do that in JScript. Please suggest.
document.getElementsByClassName returns an array of all items with that class.
Try this:
function CustomizePicklistHeight()
{
// Store elements for each class differently. Just in case :)
var elements1 = document.getElementsByClassName('ms-crm-Inline-Edit');
var elements2 = document.getElementsByClassName('ms-crm-SelectBox');
// Since you cant affect the array directly, you use a loop to do the operation on each individual element
for (var i = 0; i < elements1.length; i++)
{
element1[i].style.height = '120px !important';
};
for (var j = 0; j < elements2.length; j++)
{
element1[j].style.height = '120px !important';
};
}
Hope this helps.. :)
var matches = document.querySelectorAll(".ms-crm-Inline-Edit, select.ms-crm-SelectBox");
for(i=0; i<matches.length; i++)
{
matches[i].style.height = '120px !important';
}
Reference: https://developer.mozilla.org/en-US/docs/Web/API/Document.querySelectorAll
ClassName means "class name" (ms-crm-SelectBox) not "Entire selector". (querySelector and querySelectorAll let you use complete selectors though.
Elements means "elements" (plural) not "Element". It returns a NodeList, which you can loop over like an array.
If, on the other hand, you want to the modify the CSS rule-set instead of the styles applied directly to the HTML elements, then you need to look at document.styleSheets instead.
you will have to make a loop by setting each item, and if you have not "! important" earlier you do not need it.
I have some div ids that are generated dynamicly via php
<div id='a<?php echo $gid?>>
How can I access them in JavaScript? All these divs start with "A" followed by a number.
Is there some kind of search function
getElementById(a*)?
Thanks for any help
No generic JavaScript function for this (at least not something cross browser), but you can use the .getElementsByTagName and iterate the result:
var arrDivs = document.getElementsByTagName("div");
for (var i = 0; i < arrDivs.length; i++) {
var oDiv = arrDivs[i];
if (oDiv.id && oDiv.id.substr(0, 1) == "a") {
//found a matching div!
}
}
This is the most low level you can get so you won't have to worry about old browsers, new browsers or future browsers.
To wrap this into a neater function, you can have:
function GetElementsStartingWith(tagName, subString) {
var elements = document.getElementsByTagName(tagName);
var result = [];
for (var i = 0; i < elements.length; i++) {
var element = elements[i];
if (element.id && element.id.substr(0, subString.length) == subString) {
result.push(element);
}
}
return result;
}
The usage example would be:
window.onload = function() {
var arrDivs = GetElementsStartingWith("div", "a");
for (var i = 0; i < arrDivs.length; i++) {
arrDivs[i].style.backgroundColor = "red";
}
};
Live test case.
In case you choose to use jQuery at some point (not worth for this thing alone) all the above code turns to single line:
$(document).ready(function() {
$('div[id^="a"]').css("background-color", "blue");
});
Updated fiddle, with jQuery.
No, you need a fixed id value for getElementById to work. However, there are other ways to search the DOM for elements (e.g. by CSS classes).
You can use querySelectorAll to get all divs that have an ID starting with a. Then check each one to see if it contains a number.
var aDivs = document.querySelectorAll('div[id^="a"]');
for(var index = 0, len = aDivs.length; index < len; index++){
var aDiv = aDivs[index];
if(aDiv.id.match(/a\d+/)){
// aDiv is a matching div
}
}
DEMO: http://jsfiddle.net/NTICompass/VaTMe/2/
Well, I question myself why you would need to select/get an element, that has a random ID. I would assume, you want to do something with every div that has a random ID (like arranging or resizing them).
In that case -> give your elements a class like "myGeneratedDivs" with the random ID (if you need it for something).
And then select all with javascript
var filteredResults=document.querySelectorAll(".myGeneratedDivs").filter(function(elem){
....
return true;
});
or use jQuery/Zepto/YourWeaponOfChoice
var filteredResults=$(".myGeneratedDivs").filter(function(index){
var elem=this;
....
return true;
});
If you plan to use jQuery, you can use following jQuery selectors
div[id^="a"]
or
$('div[id^="id"]').each(function(){
// your stuff here
});
You will have to target the parent div and when someone click on child div inside a parent div then you can catch the child div.
<div id="target">
<div id="tag1" >tag1</div>
<div id="tag1" >tag2</div>
<div id="tag1" >tag3</div>
</div>
$("#target").on("click", "div", function() {
var showid = $(this).attr('id');
alert(showid)
});
getElementById() will return the exact element specified. There are many javascript frameworks including jQuery that allow much more powerful selection capabilities. eg:
Select an element by id: $("#theId")
Select a group of elements by class: $(".class")
Select subelements: $("ul a.action")
For your specific problem you could easily construct the appropriate selector.
I have a series of p tags on my page and I want to wrap them all into a container, e.g.
<p>foo</p>
<p>bar</p>
<p>baz</p>
I want to wrap all the above tags into a container as follows:
<div>
<p>foo</p>
<p>bar</p>
<p>baz</p>
</div>
How to wrap a NodeList in an element using vanilla JavaScript?
Posted below are a pure JavaScript version of jQuery's wrap and wrapAll methods. I can't guarantee they work exactly as they do in jQuery, but they do in fact work very similarly and should be able to accomplish the same tasks. They work with either a single HTMLElement or an array of them. I haven't tested to confirm, but they should both work in all modern browsers (and older ones to a certain extent).
Unlike the selected answer, these methods maintain the correct HTML structure by using insertBefore as well as appendChild.
wrap:
// Wrap an HTMLElement around each element in an HTMLElement array.
HTMLElement.prototype.wrap = function(elms) {
// Convert `elms` to an array, if necessary.
if (!elms.length) elms = [elms];
// Loops backwards to prevent having to clone the wrapper on the
// first element (see `child` below).
for (var i = elms.length - 1; i >= 0; i--) {
var child = (i > 0) ? this.cloneNode(true) : this;
var el = elms[i];
// Cache the current parent and sibling.
var parent = el.parentNode;
var sibling = el.nextSibling;
// Wrap the element (is automatically removed from its current
// parent).
child.appendChild(el);
// If the element had a sibling, insert the wrapper before
// the sibling to maintain the HTML structure; otherwise, just
// append it to the parent.
if (sibling) {
parent.insertBefore(child, sibling);
} else {
parent.appendChild(child);
}
}
};
See a working demo on jsFiddle.
wrapAll:
// Wrap an HTMLElement around another HTMLElement or an array of them.
HTMLElement.prototype.wrapAll = function(elms) {
var el = elms.length ? elms[0] : elms;
// Cache the current parent and sibling of the first element.
var parent = el.parentNode;
var sibling = el.nextSibling;
// Wrap the first element (is automatically removed from its
// current parent).
this.appendChild(el);
// Wrap all other elements (if applicable). Each element is
// automatically removed from its current parent and from the elms
// array.
while (elms.length) {
this.appendChild(elms[0]);
}
// If the first element had a sibling, insert the wrapper before the
// sibling to maintain the HTML structure; otherwise, just append it
// to the parent.
if (sibling) {
parent.insertBefore(this, sibling);
} else {
parent.appendChild(this);
}
};
See a working demo on jsFiddle.
You can do like this:
// create the container div
var dv = document.createElement('div');
// get all divs
var divs = document.getElementsByTagName('div');
// get the body element
var body = document.getElementsByTagName('body')[0];
// apply class to container div
dv.setAttribute('class', 'container');
// find out all those divs having class C
for(var i = 0; i < divs.length; i++)
{
if (divs[i].getAttribute('class') === 'C')
{
// put the divs having class C inside container div
dv.appendChild(divs[i]);
}
}
// finally append the container div to body
body.appendChild(dv);
I arrived at this wrapAll function by starting with Kevin's answer and fixing the problems presented below as well as those mentioned in the comments below his answer.
His function attempts to append the wrapper to the next sibling of the first node in the passed nodeList. That will be problematic if that node is also in the nodeList. To see this in action, remove all the text and other elements from between the first and second <li> in his wrapAll demo.
Contrary to the claim, his function won't work if multiple nodes are passed in an array rather than a nodeList because of the looping technique used.
These are fixed below:
// Wrap wrapper around nodes
// Just pass a collection of nodes, and a wrapper element
function wrapAll(nodes, wrapper) {
// Cache the current parent and previous sibling of the first node.
var parent = nodes[0].parentNode;
var previousSibling = nodes[0].previousSibling;
// Place each node in wrapper.
// - If nodes is an array, we must increment the index we grab from
// after each loop.
// - If nodes is a NodeList, each node is automatically removed from
// the NodeList when it is removed from its parent with appendChild.
for (var i = 0; nodes.length - i; wrapper.firstChild === nodes[0] && i++) {
wrapper.appendChild(nodes[i]);
}
// Place the wrapper just after the cached previousSibling,
// or if that is null, just before the first child.
var nextSibling = previousSibling ? previousSibling.nextSibling : parent.firstChild;
parent.insertBefore(wrapper, nextSibling);
return wrapper;
}
See the Demo and GitHub Gist.
Here's my javascript version of wrap(). Shorter but you have to create the element before calling the function.
HTMLElement.prototype.wrap = function(wrapper){
this.parentNode.insertBefore(wrapper, this);
wrapper.appendChild(this);
}
function wrapDiv(){
var wrapper = document.createElement('div'); // create the wrapper
wrapper.style.background = "#0cf"; // add style if you want
var element = document.getElementById('elementID'); // get element to wrap
element.wrap(wrapper);
}
div {
border: 2px solid #f00;
margin-bottom: 10px;
}
<ul id="elementID">
<li>Chair</li>
<li>Sofa</li>
</ul>
<button onclick="wrapDiv()">Wrap the list</button>
If you're target browsers support it, the document.querySelectorAll uses CSS selectors:
var targets = document.querySelectorAll('.c'),
head = document.querySelectorAll('body')[0],
cont = document.createElement('div');
cont.className = "container";
for (var x=0, y=targets.length; x<y; x++){
con.appendChild(targets[x]);
}
head.appendChild(cont);
Taking #Rixius 's answer a step further, you could turn it into a forEach loop with an arrow function
let parent = document.querySelector('div');
let children = parent.querySelectorAll('*');
let wrapper = document.createElement('section');
wrapper.className = "wrapper";
children.forEach((child) => {
wrapper.appendChild(child);
});
parent.appendChild(wrapper);
* { margin: 0; padding: 0; box-sizing: border-box; font-family: roboto; }
body { padding: 5vw; }
span,i,b { display: block; }
div { border: 1px solid lime; margin: 1rem; }
section { border: 1px solid red; margin: 1rem; }
<div>
<span>span</span>
<i>italic</i>
<b>bold</b>
</div>