I am trying to write a simple toggle function in Javascript. What it does is take an element, a style name, and a desired value. If the current value of that style on the element is the empty string, that means it hasn't been set, so we set it to the given value. Otherwise, set it to the empty string to disable it.
My code is below:
function toggleStyle(el, styleName, value) {
if (el.styleName === '')
{
el.styleName = value;
}
else
{
el.styleName = '';
}
}
However, I'm unsure how I call this function if I want to toggle the visbility of a box. I know to directly change the visibility: I would normally do:
var box = document.getElementById("box");
box.style.display = "none";
But how would I call my toggleStyle to do this? I've tried writing:
toggleStyle (box, display, "none");
toggleStyle (box, style.display, "none");
toggleStyle (box.style, display, "none");
but nothing seems to work.
bracket notation is what you need and you need to pass strings.
function toggleStyle(el, styleName, value) {
if (el.style[styleName] !== value) { //better to check that it is not the value you have
el.style[styleName] = value;
} else {
el.style[styleName] = '';
}
}
var btn = document.querySelector("button")
var div = document.querySelector("#foo")
btn.addEventListener("click", function () {
toggleStyle(div, "display", "none")
});
<button type="button">Click Me</button>
<div id="foo">FOO</div>
Where would this fail? Color codes are one thing, but this is the basic step in the right direction.
You should write it like this instead:
function toggleProp(obj, prop, value){
obj[prop] = obj[prop] ? "" : value;
}
toggleProp(box.style, "display", "none");
You should also learn how to use the debugger:
From this we can see that it was because the variable display is not defined before using it.
Two things:
First, change your toggleStyle function so that it modifies the element's style property directly, and use bracket notation to dynamically access the property element of the style object:
function toggleStyle(el, styleName, value) {
if (el.style[styleName] === '') {
el.style[styleName] = value;
} else {
el.style[styleName] = '';
}
}
Second, pass a string of the style property when you use toggleStyle:
toggleStyle(box, "display", "none"); // display needs to be in quotes
Related
My onclick function won't fire unless it is clicked twice. I am very new to javascript but so far i trie moving around the var obj line, and changing the =="none" to "none"?"empty"; which are both things I didn't understand but saw other people did to fix this problem. Neither worked.
+
function showDiv(id){
var obj = document.getElementById(id);
if( obj.style.display == "none") {
obj.style.display='block'
}
else{
obj.style.display='none'
}
}
<div id="show1">
Roughly 2-3 months.
</div>
Your problem is, that you use the style property of the element directly. Assuming, that you did not set obj.style.display = "none"; in your code explicitly, the value remains undefined until the first click. After the first click it is set and everything works like you want it to.
To solve it use getComputedStyle() to access the element's style. This includes all styles set via CSS:
function showDiv(id){
var obj = document.getElementById(id),
compStyle = window.getComputedStyle( obj );
if( compStyle.display == "none") {
obj.style.display='block'
} else {
obj.style.display='none'
}
}
You should use strict equal operators to prevent from undefined style rule.
I would rather use addEventListener instead of onclick to keep my code cleaner, here is a jsfiddle with my version (some extras as dataset and triple conditional are there, but they are not necessarily needed in your example)
var showDiv = function (ev) {
var id = ev.currentTarget.dataset.id;
var obj = document.getElementById('show' + id);
obj.style.display = (obj.style.display === "none") ? 'block' : 'none';
};
http://jsfiddle.net/mindcookin/06nvkay7/4/
What is the correct way of addressing the id of an element in an if statement condition?
if($('id').val() == Reset)
var Submit_Status = $("#Reset").val();
else
var Submit_Status = $("#Nb_var97").val();
Thanks,
Neil P.
Since I can't see your HTML I'm going to post a simple example:
<div id="myID"></div>
if($("div").attr("id") == "myID")
{
//do stuff
}
if($('someSelector').attr('id') == 'Reset')
var Submit_Status = $("#Reset").val();
else
var Submit_Status = $("#Nb_var97").val();
if ( $('div').attr('id') == 'Reset' ) {
// do something
}
If you're trying to check the value of the ID property then you can get it using the attr method.
For example, if you were looping through all of the elements with the class foo and wanted to check for the id bar you could do this in your loops:
...
var id = item.attr("id");
if(id == 'bar')
{
}
Here's an example where all divs on the page are selected and each one has it's ID checked in turn:
var divs = $('div');
divs.each(function(index, value) {
var id = $(value).attr('id');
if(id == 'foo')
{
// Do foo work
}
else if(id == 'bar')
{
// Do bar work
}
Working example: http://jsfiddle.net/gZHMD/1/
Using a short form (ternary/conditional operator) instead of if
// element could be any html element but inputs have val and div, spans and suchlike don't have val
var Submit_Status = $('element').attr('id') == 'Reset' ? $("#Reset").val() : $("#Nb_var97").val();
Also, if you have multiple elements, then you have to select specific one, an example here.
Let's say I have many of these in my content div : <cite class="fn">blabla</cite>
How can I check every cite tag's content (in this case: blabla) with class fn to see if it equals to "sometext" then change it's color to red ?
Very simple.
$('cite.fn:contains(blabla)').css('color', 'red');
Edit: though that will match "blablablabla" as well.
$('cite.fn').each(function () {
if ($(this).text() == 'blabla') {
$(this).css('color', 'red');
}
});
That should be more accurate.
Edit: Actually, I think bazmegakapa's solution is more elegant:
$('cite.fn').filter(function () {
return $(this).text() == 'blabla';
}).css('color', 'red');;
You can make use of the amazing .filter() method. It can take a function as its parameter, which will reduce the jQuery collection's elements to those that pass its test (for which the function returns true). After that you can easily run commands on the remaining elements:
var searchText = 'blabla';
$('cite.fn').filter(function () {
return $(this).text() === searchText;
}).css('color', 'red');
jsFiddle Demo
You could potentially do something like:
$('cite.fn').each(function() {
var el = $(this);
if (el.text() === 'sometext') {
el.css({ 'color' : 'red' });
}
});
This fires a function against each cite that has the class fn. That function checks if the current cite's value is equal to 'sometext'.
If it is, then we change the CSS color (text-color) property to red.
Note I'm using jQuery in this example, as you've specifically tagged your question jQuery. Ignore the downvote, this was applied before I edited a typo that I'd made (el.val() rather than el.text())
Without jQuery:
var elms = document.querySelectorAll("cite.fn"), l = elms.length, i;
for( i=0; i<l; i++) {
if( (elms[i].innerText || elms[i].textContent) == "blabla") {
elms[i].style.color = "red";
}
}
Here's the JavaScript code you can find everywhere when you want to hide/show an element:
function sh(_id, _val) {
if (document.getElementById) {
document.getElementById(_id).style.display = _val;
}
else {
if (document.layers) {
document._id.display = _val;
}
else {
document.all._id.style.display = _val;
}
}
}
function hide(_id) {
sh(_id, 'none');
}
function show(_id) {
sh(_id, 'block');
}
The problem is the "show" function: it forces to "block". If I use a table with tr's and td's, when I want to display them I don't them to be displayed as "block" but to restore to their initial state.
How should I do?
How would you do?
If you want to restore their default display value, you can assign an empty string to it:
element.style.display = '';
If you want the one assigned through CSS for example, you have to store it somewhere, e.g. in an id -> display map or as data- attribute.
The easiest way would be to use jQuery and .show() http://api.jquery.com/show/
The second easiest way would be to wrap the table in a div.
If not I would try to store the initial value of display somewhere (if html5 the a "data-" attribute) if not in some other hidden element
If the point of your exercise is to learn more about DOM, then you may disregard this answer. But if the point is to get some UI to work, then:
My suggestion would be to use jquery. If you did, all of the code you showed would disappear altogether, and you would hide/show elements like this:
$('#' + id).hide()
$('#' + id).show()
If you want to stick with low level DOM api, then you'll have to save away the prior value (block or whatever) of style.display, so you can restore it later. And you can do that. But you'll keep having to write code like that, considering all kinds of cases, when someone has already written code that does that, and they're giving it away for free.
var previousDisplay = {};
function sh(_id, _val) {
if (document.getElementById) {
document.getElementById(_id).style.display = _val;
}
else {
if (document.layers) {
if(!previousDisplay[_id]){
previousDisplay[_id] = document._id.display;
}
document._id.display = _val;
}
else {
if(!previousDisplay[_id]){
previousDisplay[_id] = document.all._id.style.display;
}
document.all._id.style.display = _val;
}
}
}
function hide(_id) {
sh(_id, 'none');
}
function show(_id) {
var style = previousDisplay[_id];
if(!style){
style = 'block';
}
sh(_id, style );
}
This is my script :
window.onload = function (){
var title = document.getElementsByTagName('h1')[0].id = "heading1";
document.getElementById(title).onclick = function (e){
var para = this.nextSibling.style.display = 'block';
var newVal = (para == "block") ? "none" : "block";
alert(newVal);
}
}
The result I need is for the alert value to toggle from block to none and back. But I am always getting "none". What is the problem with my code?
window.onload = function () {
var firstH1 = document.getElementsByTagName('h1')[0];
firstH1.id = "heading1";
firstH1.onclick = function() {
var currentValue = this.nextSibling.style.display;
this.nextSibling.style.display = (currentValue == "none") ? "block" : "none";
}
}
Note a few things: I simplified your element fetching because it doesn't make sense to fetch an element, assign it an id, then use that id to find that same element again.
I also switched block/none ordering, because if no style is displayed then it would be blank -- and your first click would assign block to it - and it would not disappear. This way it does.
Well, para will always be "block", and therefore newVal will always be "none". So that behavior is expected. What are you trying to do? you are not toggling the property with your curent code.