Javascript styling toggle doesn't work first click - javascript

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.

Related

How to bind to 'inview' event on multiple elements

I'm playing around with Velocity.js and jquery.inview, and I want all the titles on my page to slideDownIn when they come into view. This code works fine for the first title:
$('.movies-title').bind('inview', function(event, isInView, visiblePartX, visiblePartY) {
if (isInView) {
// element is now visible in the viewport
if (visiblePartY == 'top') {
// top part of element is visible
} else if (visiblePartY == 'bottom') {
// bottom part of element is visible
} else {
// whole part of element is visible
$(this).velocity("transition.slideDownIn", 500);
}
} else {
// element has gone out of viewport
$(this).velocity("reverse");
}
});
If I copy and paste the above several times and replace .movies-title with the classes of the other titles, it works as I want it to.
However, that seems like a lot of extra code. I tried changing $('.movies-title') to $(.movies-title, .tv-title, .books-title) but then the animation only works for the last element in the list. I also tried adding a new class called .title to all of the titles and changing .movie-title to .title but that didn't work either.
What am I doing wrong? How can I condense the code?
The best solution is to use a single class on each of these elements since they have something so in common. You might just add title as a class type and apply it to that class.
<div class="title movie-title"></div>
I know you mentioned this in your question, but I can't see why this wouldn't work.
Try using delegate instead of bind for multiples. Also make a unified class for all of them (I just used title)
so like this -
$('body').delegate('.title','inview', function(event, isInView, visiblePartX, visiblePartY) {
Edit - sorry linked wrong fiddle initially
see fiddle http://jsfiddle.net/d1g7sLxq/3/

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/

How to dynamically change CSS using JS

I am working on complicated animation, I am trying to add effects by adding another class based on the val I am getting.
I have different css classes, and I wanna know how to dynamically add them this way.
.. Class="box bottom right"
when I add new class (eg: red).
It should be in my code this way:
.. Class="box bottom right red"
I am trying to change the css based on value I am calculating.
var els=2;
function changeColor(els) {
if (els>0) {
$("box bottom right").addClass("red");
} else{
$("box bottom right").addClass("green");
};
}
Here is code:
http://jsfiddle.net/BB6ED/1/
You need to use . to target elements by class as well as calling your function on page load:
var els=2;
function changeColor(els) {
if (els>0) {
$(".box.bottom.right").addClass("red");
} else{
$(".box.bottom.right").addClass("green");
};
}
changeColor(els);
Updated Fiddle

javascript/css: change display property

I want to change display without documentGetElementById if possible but the following is not working.
html
Instructions<div id="showfaq1" style="display:none;">Open Box. Remove device. </div>
javascript:
function toggleFaq(faqid) {
//alert(faqid);
var divname = "showfaq"+faqid;
//alert(divname);
divname.style.display="block";
}
Can anyone tell me what I am doing wrong?
Thank you.
I can't get why you do not want to use getElementById, but...
If you have elements in order like this
Instructions
<div id="showfaq1" style="display:none;">Open Box. Remove device. </div>
Instructions
<div id="showfaq2" style="display:none;">Open Box. Remove device. </div>
...
Instructions
<div id="showfaqN" style="display:none;">Open Box. Remove device. </div>
You may use
Instructions
function toggleFaq(obj) {
obj.nextElementSibling.style.display = 'block';
}
In your code divname is a variable containing a string "showfaq1", which doesn't have style property.
To change the style of an element you need a reference to that element which you can obtain using document.getElementById(divname):
function toggleFaq(faqid) {
//alert(faqid);
var divname = "showfaq"+faqid;
//alert(divname);
document.getElementById(divname).style.display="block";
}
If you have an allergy to document.getElementById, you may use document.querySelector('[id="' + divname +'"]');, but its support is not as good as the former, and it's slower.
Posting a separate answer as it has no impact on my previous one. But you could make the base mechanism without JS at all, then use one of the JS-based solutions to fix it in broken browsers if needed:
HTML
Instructions
<div id="showfaq1">Open Box. Remove device. </div>
CSS
a + div { display:none; }
a:focus + div, a + div:target { display:block; }
DEMO

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