The following code is an example of open and close actions of a sidebar, where some CSS values should be updated to correctly show the sidebar.
function openNav() {
document.getElementById("sidebar").style.width = "250px";
document.getElementById("mainContent").style.marginLeft = "250px";
document.getElementById("codePanel").style.marginLeft = "10px";
}
function closeNav() {
document.getElementById("sidebar").style.width = "0";
document.getElementById("mainContent").style.marginLeft = "0px";
document.getElementById("codePanel").style.marginLeft = "40px";
}
Now I ask myself if there is a better way to do this if I eg update more different styles?
Because in this code, I would need to add more and more similar looking lines of code which looks really clunky.
If you add an initial class to all your elements that you want to update
<div id="sidebar" class="update"></div>
<div id="codePanel" class="update"></div>
Then add some styles (be aware of style specificity)
#sidebar.update {
width : 200px;
}
#sidebar.update.updated {
width : 250px;
}
#codePanel.update.updated {
color : red;
}
You can easily add that class to multiple elements in a loop
var elems = document.querySelectorAll('.update');
elems.forEach(function(elem) {
elem.classList.add('updated');
});
as the other members mentioned it is better to use class, what I want to add is
that you can create those css classes based on specific style for example create a class called marginLeft50 which sets the left margin to 50 so whenever you want to update an element css you can simply do $('sidebar').addClass('marginLeft50');
keep in mind that you can add multiple classes to a single element, and since you mention jquery in your tags, jquery takes care of looping through all the targeted elements and updating each one of them
and as simply you can $('selector').removeClass('className') whenever you need to
Related
I found the code to add a single button on the leaftlet map to the topleft corner. But now I want to add multiple buttons one after another.
Is it possible to insert multiple buttons inside the following code?
I also have tried to use checkbox/radio buttons. But I dont know how to add labels to the checkbox and button.
And add checked/unchecked properties for them.
Thanks.
My Code here:
var customControl = L.Control.extend({ options: {position: 'topleft'},onAdd: function (map) {
var container = L.DomUtil.create('div', 'leaflet-bar leaflet-control leaflet-control-custom');
onAdd: function (map) {
var container = L.DomUtil.create('input','my-button btn');
container.type="button";
container.title="x";
container.value = "x";
container.label = "x";
container.style.backgroundColor = 'white';
container.style.backgroundSize = "30px 30px";
container.style.width = '40px';
container.style.height = '40px';
container.style.borderRadius = "25px";
container.style.padding = "0";
container.style.margin = "10px";
container.onclick = function(){
console.log('buttonClicked');
}
return container;}});
You can create as many Leaflet "controls" as you wish. You can insert them at any corner, and they will simply "stack up" (with a 10px margin if I remember correctly) in a vertical column in the given corner.
As for the content of each control, it is purely HTML and CSS. In your code you are using Leaflet's utility L.DomUtil.create(), but you could have also simply used the native document.createElement() (but would have to add the class in a separate line) or even jQuery DOM utility (with which you can directly write an HTML string).
Then you can build complex content (with inputs, associated labels, etc.). Just look for HTML tutorials / JavaScript that build DOM nodes.
In CSS we can do:
div { font-size:20px }
To set the default font size for all divs. Is there a way to change default styles for elements with JavaScript?
Alternately, how could I find and set the above style rule? You can find classes by searching document.styleSheets[0].cssRules by name, but I don't know how to find the style for div.
EDIT:
Oops, the answer is in my question.
My confusion arose from attempting to alter rules that were set for multiple elements at once.
So you would be able to find and alter the CSS rule for div as above.
What I don't know is how you'd alter the rule for multiple definitions:
div,span { font-size:20px }
You can't find the rule by searching for div, span or div,span.
You can use style.fontSize property for setting font size using javascript. The code will look like
document.getElementById("//id here").style.fontSize = "50px"; //size
See an example here
well if you want to change the style of an determinated div you have to do this in you javascript code
getElementById('div_register').setAttribute("style","font-size:20px");
in this way you are getting de div by its id, and setting a style that you want, you can set differents styles with these and will save code space as declare one by one the style you want...i hope i helped you :-D
With the help of javascript you can change the DOM properties. You can create one outer div and give it some name/id. Then, loop through all inner divs and update the css style attributes.
innerDivs = document.getElementById('odivID').getElementsByTagName('div');
for (var i = innerDivs.length-1; i >= 0; i--) {
innerDivs[i].style.fontSize = "25px";
}
You can do this by n number of ways, but I recommend to use class name:
style
div.my-style {
font-size:20px;
}
script
...
var divs = document.getElementsByTagName('div');
var len = divs.length;
var cn;
if(len --) do {
cn = divs[len].className;
if(cn) {
cn += ' my-style';//<-- spaces to separate with the existing class names, if any
} else {
cn = 'my-style';
}
divs[len].className = cn;
} while(len --);
...
Note: Applying style to all divs will apply to those divs as well on the same page which you don't want to do.
You could create your own css style rule that override the default one.
either
create <style> in <header> using javascript
or, link external css file <link>
please see fiddle using first method: http://jsfiddle.net/b8Hn7/
var myStyle = document.createElement("style");
myStyle.innerText = 'div { font-size: 40px; }';
document.head.appendChild(myStyle);
The above code overrides the default style by creating same rule but place after the default style, there is no need to "locate" the default style and change it.
U can try it with create 'style' dom like my under code:
html:
</div>
js:
var style = document.createElement('style');
style.innerText = 'div{width:100px;height:100px;border:1px solid #c4e;}';
document.body.appendChild(style);
I have a Element with the id="somID";
For Example:
Html:
<div id='somID' ></div>
Css :
#somID{ width:500px;height:500px}
and i have a class named : maximize.
So,
.maximize{width:100% !important; height:100% !important; }
Now dynamically i added the class .maximize to my div #somID
And after that i wanna get the width and height of my #somID by calling with its ID like,
$('#somID').width() or .height()
but i want to take the actual height of element that is defined in its ID but i get the .maximize in result not the height or width that is in #somID.
Any buddy have any idea ? That how to retrieve the height of div#somID if it contains .maximize ??
The problem is, there can be many, many selectors that are applied to a given element, with different specificities. There is no API that allows you to request a property from a selector in CSS - it simply wouldn't make much sense.
Having said that, you can create a hack to solve that issue:
function getOriginalDimensions(id) {
var $a = $("<div>", {id:id});
$("body").append($a);
var width = $a.width();
var height = $a.height();
$a.remove();
return {width:width, height:height};
}
console.log(getOriginalDimensions("somID")); // returns {width:500, height:500}
The above works with your example HTML and CSS.
JSFiddle
This basically creates an element with the same ID, appends it to the body, reads the dimensions and deletes it immediately. This is necessary because the div will have no size if it is just kept as a document fragment and not added to the DOM, because the CSS will not get applied.
In theory you could expand this function to make it work with other selectors.
However bear in mind this is a nasty hack and you should reconsider your approach.
A. Make your measurements and save them as .data attributes of the element :
var $el = $('#somID');
$el.data('original_dims', {
height: $el.height(),
width: $el.width()
}
B. Add class that changes the dimensions of the element :
$el.addClass('maximise');
C. Retrive the original dimensions whenever they are needed
var h = $el.data('original_dims').height;
var w = $el.data('original_dims').width;
How should I do this in Javascript?
// CSS
*::-moz-selection{
background:transparent;
}
I tried these but doesn't really works:
// Javascript
document.mozSelection = "transparent";
document.body.mozSelection = "transparent";
You can add a rule to the stylesheet.
// Get the first stylesheet
var ssheet = document.styleSheets[0];
if ("insertRule" in ss) {
ss.insertRule('#yourdivcontainer::-moz-selection { background: transparent; }', 0);
}
IMO, it's not a good practice anyway. You should create a CSS class with the selection color and change the class itself via JS instead of the style.
:: selectors are for pseudo-elements, CSS objects that don't correspond to actual element nodes. Because there is no element node to match ::-moz-selection, you can't style it directly on an element's .style.background property.
Instead you would have to insert a new stylesheet rule duplicating the above CSS (see this question for a couple of methods of doing that).
I'm currently extending the lavalamp plugin to work on dropdown menus but I've encountered a small problem. I need to know the offsetWidth of an element that is hidden. Now clearly this question makes no sense, rather what I'm looking for is the offsetWidth of the element were it not hidden.
Is the solution to show it, grab the width, then hide again? There must be a better way...
The width of an element that has CSS visibility: hidden is measurable. It's only when it's display: none that it's not rendered at all. So if it's certain the elements are going to be absolutely-positioned (so they don't cause a layout change when displayed), simply use css('visibility', 'hidden') to hide your element instead of hide() and you should be OK measuring the width.
Otherwise, yes, show-measure-hide does work.
The only thing I can think of is to show it (or a clone of it) to allow retrieval of the offsetWidth.
For this measurement step, just make its position absolute and its x or y value a big negative, so it will render but not be visible to the user.
You can use the following function to get the outer width of an element that is inside a hidden container.
$.fn.getHiddenOffsetWidth = function () {
// save a reference to a cloned element that can be measured
var $hiddenElement = $(this).clone().appendTo('body');
// calculate the width of the clone
var width = $hiddenElement.outerWidth();
// remove the clone from the DOM
$hiddenElement.remove();
return width;
};
You can change .outerWidth() to .offsetWidth() for your situation.
The function first clones the element, copying it to a place where it will be visible. It then retrieves the offset width and finally removes the clone. The following snippet illustrates a situation where this function would be perfect:
<style>
.container-inner {
display: none;
}
.measure-me {
width: 120px;
}
</style>
<div class="container-outer">
<div class="container-inner">
<div class="measure-me"></div>
</div>
</div>
Please be aware that if there is CSS applied to the element that changes the width of the element that won't be applied if it's a direct descendant of body, then this method won't work. So something like this will mean that the function doesn't work:
.container-outer .measure-me {
width: 100px;
}
You'll either need to:
change the specificity of the CSS selector ie. .measure-me { width: 100px; }
change the appendTo() to add the clone to a place where your CSS will also be applied to the clone. Ensure that where ever you do put it, that the element will be visible: .appendTo('.container-outer')
Again, this function assumes that the element is only hidden because it's inside a hidden container. If the element itself is display:none, you can simply add some code to make the clone visible before you retrieve it's offset width. Something like this:
$.fn.getHiddenOffsetWidth = function () {
var hiddenElement $(this)
width = 0;
// make the element measurable
hiddenElement.show();
// calculate the width of the element
width = hiddenElement.outerWidth();
// hide the element again
hiddenElement.hide();
return width;
}
This would work in a situation like this:
<style>
.measure-me {
display: none;
width: 120px;
}
</style>
<div class="container">
<div class="measure-me"></div>
</div>
Two options:
position the element outside the viewport (ex: left:-10000px)
use visibility: hidden or opacity: 0 instead of hide().
Either way will work as hiding the element but still being able to get the computed width. Be careful with Safari on thi, it's awfully fast and sometimes too fast...
Actual jQuery plugin!
Usage:
console.log('width without actual: ' + $('#hidden').width());
console.log('width with actual: ' + $('#hidden').actual('width'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.actual/1.0.19/jquery.actual.min.js"></script>
<div style="width: 100px; display: none;">
<div id="hidden"></div>
</div>
If you know the element to be the full width of a parent element another approach is to create a recursive method:
es5:
var getWidth;
getWidth = function($el){
return $el.offsetWidth || getWidth($el.parentElement);
}
var width = getWidth(document.getElementById('the-element'));
es6:
let getWidth
getWidth = ($el) => $el.offsetWidth || getWidth($el.parentElement)
const width = getWidth(document.getElementById('the-element'))
What I did was ;
by the time hiding that element, stored its width in its dataset.
It only will work for you if you can hide programmatically.
ie.
When Hiding ;
var elem = $("selectorOfElement");
elem.dataset.orgWidth = elem.clientWidth;
Later when getting ;
var elem = $("selectorOfElement");
var originalWidthWas = elem.dataset.orgWidth;
thats because its hidden via display: none; What ive done in the past is to make a "reciever" div which i use absolute positioning on to get it off the page. Then i load the new element into that, grab the dimensions and then remove it when im done - then remove the reciever when im done.
Another thing you can do is to not use hide(); but to instead set visibility: hidden; display: ; However this means the blank area will be rendered wherever the node is attached.
var $hiddenElement = $('#id_of_your_item').clone().css({ left: -10000, top: -10000, position: 'absolute', display: 'inline', visibility: 'visible' }).appendTo('body');
var width = parseInt($hiddenElement.outerWidth());
$hiddenElement.remove();
I try to find working function for hidden element but I realize that CSS is much complex than everyone think. There are a lot of new layout techniques in CSS3 that might not work for all previous answers like flexible box, grid, column or even element inside complex parent element.
flexibox example
I think the only sustainable & simple solution is real-time rendering. At that time, browser should give you that correct element size.
Sadly, JavaScript does not provide any direct event to notify when element is showed or hidden. However, I create some function based on DOM Attribute Modified API that will execute callback function when visibility of element is changed.
$('[selector]').onVisibleChanged(function(e, isVisible)
{
var realWidth = $('[selector]').width();
var realHeight = $('[selector]').height();
// render or adjust something
});
For more information, Please visit at my project GitHub.
https://github.com/Soul-Master/visible.event.js
demo: http://jsbin.com/ETiGIre/7
Sorry I am late to this conversation. I am surprised no one has mentioned getComputedStyle. (Note this only works if the CSS sets a width value)
Grab the element:
let yourEle = document.getElementById('this-ele-id');
and use the function:
getComputedStyle(yourEle).width
This returns a string so you will have to remove the numbers from the string.
This works even when the element's display style is set to none.
Other articles to read about this includes here at zellwk.com