What does style.display = '' actually do? - javascript

After researching this issue for a couple of hours, I found that one of the most efficient ways to toggle a page element's display (in HTML) is to do something like:
// showing
document.getElementById('element').style.display = '';
// hiding
document.getElementById('element').style.display = 'none';
Simple question: What does style.display = '' actually do?
Does it "reset" the original display property?
Or does it remove the display property, thereby using the default style for display?
..........................................
Would be nice to know: Does anyone know of any links to any kind of documentation about this?
(Yes, I have Google-d this issue, but I'm probably not entering the right search term and keep coming up with completely un-related search results.)
Thanks for any suggestions or links.

Yes, it resets the element's display property to the default by blanking out the inline "display: none", causing the element to fall back on its display property as defined by the page's ranking CSS rules.
For example, here's a <div> with the ID of "myElement".
<div id="myElement"></div>
A <div> has a setting of display:block by default. In our style sheet, suppose we specify that your <div> is to be displayed as table:
div#myElement
{
display:table;
}
Upon loading your page, the <div> is displayed as table. If you want to hide this <div> with scripting, you might do any of these:
// JavaScript:
document.getElementById("myElement").style.display = 'none';
// jQuery:
$("#myElement").toggle(); // if currently visible
$("#myElement").hide();
$("#myElement").css({"display":"none"});
All of thse have the same effect: adding an inline style property to your <div>:
<div id="myElement" style="display:none"></div>
If you wish to show the element again, any of these would work:
// JavaScript:
document.getElementById("myElement").style.display = "";
// jQuery:
$("#myElement").toggle(); // if currently hidden
$("#myElement").show();
$("#myElement").css({"display":""});
These remove the display CSS property from the inline style property:
<div style=""></div>
Since the inline style no longer specifies a display, the <div> goes back to being displayed as table, since that's what we put in the style sheet. The <div> does not revert to being displayed as block because our CSS overrode that default setting; blanking out the inline display property does not negate the rules in our style sheets.
For giggles, here's the Google query I used for verification of my answer: javascript style display empty string default
...and a couple of links where this is mentioned:
http://jszen.blogspot.com/2004/07/table-rowsrevealed.html
http://www.harrymaugans.com/2007/03/05/how-to-create-a-collapsible-div-with-javascript-and-css/
(not in the article, but in the comments section)

It sets the display style to the default value for that element. For most elements if not all, the default value is something other than none.

It removes the value for the display property so that the default value is used.
It does not reset the original display property.
If you for example have this:
<span id="test" style="display:block;">b</span>
And do this:
document.getElementById('test').style.display = 'inline';
document.getElementById('test').style.display = '';
the display style used for the element ends up being inline because that's the default for the element, it is not reset back to the style specified in the HTML code.

It sets the css for that element's display to null which essentially wipes out what was set and it reverts to its default value.

Related

Accessibility JS Function "Role" Attribute

I'm trying to write a JS function that would give empty heading elements (h1, and h2...)a “role” attribute value of “presentation”.
This is my first time working with accessibility in my projects and would love some help!
If they're empty, do they need to be there at all? The most correct thing is just to remove them.
However, you can use document.querySelectorAll() to get all the headings, then look inside each one to see whether they are empty. If they are, you can set the role attribute. The following code is very quick and dirty, but will get you some of the way.
var headings = document.querySelectorAll("h1,h2,h3,h4,h5,h6");
// iterate through each heading
Array.prototype.forEach.call (headings, function (node) {
// remove all white space
var theTextContent = node.textContent.replace(/\s/g,'');
// see if there's anything left in the string
if (theTextContent.length < 1) {
// node contains no visible text, mark it as presentation
node.setAttribute("role", "presentation");
}
} );
BUT this is a risky heuristic. Some headings might not contain text nodes, yet still appear as text on screen (e.g. they may have a background image in CSS representing a text in bitmap form). Instead of adding role="presentation" to these, you absolutely should add an aria-label with the correct heading text, otherwise you'll be violating at least two WCAG success criteria. ("Images of Text" and "Headings and Labels").
If you were using style attributes it might look something like this:
<h1 aria-label="welcome" style="background:url(welcome.png);"></h1>

Element not displayed with obj.style.display='';

I have a strange issue on a HTML page containing a span which won't be displayed:
<span id="wipThankYou">Thank you for submitting your email!</span>
It is initially hidden with the following CSS:
#wipThankYou {
display: none;
}
When a user clicks on a button, the following code is executed:
function T_show(obj) {
if ( obj !== null ) {
obj.style.display='';
}
}
var wipThankYou = document.getElementById("wipThankYou");
T_show(wipThankYou);
I can see the code being executed step-by-step in Chrome, but the span is not displayed. When I inspect the element, its CSS is not changed. I can replicate the issue on JsFiddle.
What am I doing wrong?
UPDATE
I took this code from You Might Not Need JQuery, but apparently, it is faulty. Thanks.
obj.style.display='' resets the inline style of the element. You need to specify how you want to display it if you want it to be shown. Change it to a display value and it will fix it, such as obj.style.display='inline-block'
obj.style.display='inline-block';
or whatever the display you want (inline, block...), but it shouldn't be empty.
See it here: http://jsfiddle.net/shomz/ELmqf/
obj.style.display=''; is not valid for css display as display can be :inline(default), block, inline-block (more values you can find here http://www.w3schools.com/cssref/pr_class_display.asp)
so solution for you to set style to valid value. For example obj.style.display='block';
Live example http://jsfiddle.net/a699x/2/

Javascript styling toggle doesn't work first click

I'm making this little html app with a sidebar menu that pops up on click. It works fine except that it only starts to work after the second click. On the first click nothing happens.
CSS:
#menubalk{
margin-left: -260px;
}
HTML:
<div id="menubutton">
<img src="design/images/menu.png" id="menu" onclick="toggle()" alt=""/>
</div>
<div id="menubalk">
<h5>Menu</h5>
</div>
Javascript:
function toggle () {
var el = document.getElementById("menubalk");
var kop = document.getElementById("kop");
var pag = document.getElementById("pagina");
if ( el.style.marginLeft=="-260px" ) {
el.style.marginLeft="0px";
kop.style.marginLeft="260px";
pag.style.marginLeft="260px";
} else {
el.style.marginLeft="-260px";
kop.style.marginLeft="0px";
pag.style.marginLeft="0px";
}
}
I think I might have to set the margin somewhere in the javascript also but I can't figure it out.
All help is greatly appreciated!
style.marginLeft is looking at your inline styles. As you haven't defined any inline style initially style.marginLeft is undefined.
To fix this, you could simply reverse your if/else statement:
if ( el.style.marginLeft=="0px" )
element.style only search for inline style, to get actual style you can use getComputedStyle
i.e.
if ( window.getComputedStyle(el).marginLeft=="-260px" ) {...
Reference: https://developer.mozilla.org/en-US/docs/DOM/window.getComputedStyle
Note: For IE, this only works for IE9 or above.
With this line
if(el.style.marginLeft=="-260px") {
You are checking if the inline style of the element is a specific value. However, this style is set in the css. I recommend adding a className to the menu to expand it. You can check for this classname and add/remove it accordingly:
if ( el.className == "expanded" ) {
el.className = "";
} else {
el.className = "expanded";
}
With this addition to the css:
#menubalk.expanded {
margin-left:0;
}
You say you set the menu style in the JavaScript somewhere but I would actually recommend doing that as part of your initialisation, rather than setting the left margin with CSS.
I suspect (it's hard to see without an example) that on the first click the JavaScript is going straight to the else condition because it's not recognising that you've set the margin in CSS (or elsewhere). Then on the second click, JavaScript has been used to set the left margin so it can read it and perform accordingly.

Wrapping a jquery validate span.error with nested divs

Heyo. This is my first stack overflow post because I am stumped and not finding many people who are trying to accomplish the same thing. I've tried using jquery .before(), .after(), and .wrap() to resolve this. I was initially using css :before and :after pseudo-elements, but as that won't work for legacy browsers, I've decided to use jquery.
I already have several forms on several pages with validation working. The error messages vary in length. We were using a static, one size background image on the default span element, so content was bleeding out on longer error messages. I built a flexible rounded corner series of nested divs to allow the error box to grow or shrink dynamically. The html I want to output is:
<div class="errorWrap">
<div class="errorTop"><span></span></div>
<div class="errorContent">
<span class="error">This is an error</span>
</div>
<div class="errorBottom"><span></span></div>
</div>
Here's an example of a solution I tried, but I'm still pretty new to javascript.
$('.error').before('<div class="errorWrap"><div class="errorTop"><span></span></div><div class="errorContent">');
$('.error').after('</div><div class="errorBottom"><span></span></div></div>');
Correct me if I'm wrong, but I think that I have the right idea with the jquery. But it's just kind of sitting there, not in any function being called. So I imagine that since the code isn't re-executing, it just doesn't show up. Is there an appropriate function to wrap this in? I'm certain I'm just not attacking this from the right direction. Any help is super appreciated.
the plugins "before" and "after" dont take html as string. you cannot start a div in one and close it in an other.
Either you take your current html and generate a new html string which you append where you want to or you use the "wrap" plugin http://api.jquery.com/wrap/
Using pure HTML
$(".error").html("<div class='beforeContent'>" + $(".error").html() + "</div>");
Using wrap (http://api.jquery.com/wrap/)
$(".error").wrap("<div class='beforeAndAfter'></div>");
If you want to show an error div after focus out of an input then you have to create it using html/wrap as Luke said and then you have to append it in ot the dom useing
$('.errorWrap').insertAfter('.focusedElement');
But there are other methods available to insert a new element like append/appendTo e.t.c,
I ended up fixing this problem on my own using jquery to create the div and it's nesting on pageload, the divs are generated with an error class that gives display:none. A custom errorPlacement function nests the error in the correct div. Then I used a custom validator highlight function to remove the class that hides the element. Then I used the unhighlight function to re-add the class to re-hide the div.
$(function() {
//Generate the elements and assign attributes
var errorWrap = document.createElement('div');
$(errorWrap).addClass('errorWrap hideError');
var errorTop = document.createElement('div');
$(errorTop).addClass('errorTop');
var topSpan = document.createElement('span');
var errorContent = document.createElement('div');
$(errorContent).addClass('errorContent');
var errorBottom = document.createElement('div');
$(errorBottom).addClass('errorBottom');
var bottomSpan = document.createElement('span');
//Place the elements directly after each dd element
$("dl > dd").append(errorWrap);
$("div.errorWrap").append(errorTop)
.append(errorContent)
.append(errorBottom);
$("div.errorTop").append(topSpan);
$("div.errorBottom").append(bottomSpan);
//Add custom validator defaults
$.validator.setDefaults({
errorPlacement: function(error, element) {
$(element).nextAll('.errorWrap').children('.errorContent').append(error);
},
highlight: function(element) {
$(element).nextAll('.errorWrap').removeClass('hideError');
},
unhighlight: function(element) {
$(element).nextAll('.errorWrap').addClass('hideError');
}
});
}
Although I'm sure this could have been done more shorthand, I really like this technique because I didn't have to update any of my pages that contained forms to get it to work. All of the nested divs are dynamically created by javascript, so I can include a global file to any page with forms and it will just work. Thanks for all who offered suggestions.

How can I undo the setting of element.style properties?

I have an element in my document that has a background color and image set through a regular CSS rule.
When a certain event happens, I want to animate that item, highlighting it (I'm using Scriptaculous, but this question applies to any framework that'll do the same).
new Effect.Highlight(elHighlight, { startcolor: '#ffff99', endcolor: '#ffffff', afterFinish: fnEndOfFadeOut });
The problem i'm facing is that after the animation is done, the element is left with the following style (according to FireBug):
element.style {
background-color:transparent;
background-image:none;
}
Which overrides the CSS rule, since it's set at the element level, so I'm losing the background that the item used to have...
What I'm trying to do is, in the callback function I'm running after the animation is done, set the style properties to a value that'll make them "go away".
var fnEndOfFadeOut = function() {
elHighlight.style.backgroundColor = "xxxxx";
elHighlight.style.backgroundImage = "xxxxx";
}
What I'm trying to figure out is what to put in "xxxx" (or how to do the same thing in a different way).
I tried 'auto', 'inherit', and '' (blank string), and neither worked (I didn't really expect them to work, but I'm clueless here).
I also tried elHighlight.style = ""; which, expectably, threw an exception.
What can I do to overcome this?
I know I can put a span inside the element that I'm highlighting and highlight that span instead, but I'm hoping I'll be able to avoid the extra useless markup.
Chances are you're not setting the style on the correct element. It's probably being set somewhere up the line in a parent node.
elHighlight.style.backgroundColor = "";
elHighlight.style.backgroundImage = "";
You can also remove all the default styling by calling:
elHighlight.style.cssText = "";
In any case, you'll still have to do this on the specific element that is setting these properties, which means you may need to do a recursion on parentNode until you find it.
Try
elHighlight.style.removeProperty('background-color')
elHighlight.style.removeProperty('background-image')
have you tried elHightlight.style.background = "";?
I have a highlighter code on my site and this works
function highlight(id) {
var elements = getElementsByClass("softwareItem");
for (var ix in elements){
elements[ix].style.background = ""; //This clears any previous highlight
}
document.getElementById(id).style.background = "#E7F3FA";
}
An HTML element can have multiple CSS classes. Put your highlight information inside a CSS class. Add this class to your element to highlight it. Remove the class to undo the effect.

Categories

Resources