How can I slide an element hidden by external CSS with Scriptaculous? - javascript

I have this menu:
<ul id="nav">
<li class="level0">Item 1</li>
<li class="level0 parent">
<a><span>Click Me!</span></a>
<div class="submenu">
<ul>
<li>Subitem 1</li>
<li>Subitem 2</li>
</ul>
</div>
</li>
</ul>
I want the submenu to be hidden when the page is loaded. When the user clicks the parent item, the submenu should appear.
When I use inline CSS like this, everything works fine.
<div class="submenu" style="display:none;">
See this demo: http://jsfiddle.net/zJk6P/ (Click on "Click me" in the bottom right to run the demo.)
When I use external CSS like this, the submenu doesn't appear anymore.
#nav div.submenu{
display: none;
}
See this demo: http://jsfiddle.net/5tNqc/4/
Why is there any difference and how can I get the sliding effect to work with external CSS?

The reason my code didn't work was that Javascript doesn't have access to external CSS style declarations. Only inline styles are accessible trough element.style.
Effect.toggle(element, 'slide'); tries to slide the element down when the element is not displayed, and up when the element is displayed. So when the element is hidden by an external style sheet, Effect.toggle will try to slide the element up, because it simply doesn't "know" the element is already hidden.
The solution is to work with class names. My final solution checks whether the element has a certain class name. When the class name is present, the element is not clicked yet, so the element is slided down and the class name is removed. All next clicks, the element is toggled.
I built and uploaded a small demonstration here: http://i.amniels.com/ext/stackexchange/2011-09/index.html

The difference is that you don't change display to be set to display: block;, which is the standard, and so it gets overridden by the external explicit definition that it should be hidden. If you add another line in the Javascript to add thisDiv.style.display = block;, and remove it at the end of hiding it, it should work just fine.
Update:
So, the reason that it doesn't show up when you have display: none; in your CSS file, is because when the Javascript animation starts, instead of setting display: block; on your div, which would make it visible, it simply removes the display property on the element entirely, so it is still affected by the external CSS.
My suggestion: if you don't want the Javascript to become more difficult, simply leave the style inline, so that it can be removed later by Javascript automatically. If you want to use an external CSS style for it, you could just add a short helper function to your Javascript to change the CSS display property to block whenever it starts, and set it to display: none after the animation is finished.

Related

Temporarily disable particular css style from javascript

I have a particularly specific question that there are many articles online but they don't answer my question.
I have a menu bar on my website where some <li> elements appear when the user is logged in. That <li> element also has an onhover dropdown styled in css with the following:
ul li:hover > ul {
display: block;
}
So what happens is, when the <li> element of the main (which has a direct child of <ul>) is hovered upon, the dropdown will appear. Pretty straightforward.
My problem is, when I hide that particular <li> element with the dropdown attached to it (through the following code within a javascript if statement), the hover style remains.
So even though the parent <li> is set to display: none;, the child dropdown can be revealed by hovering over a tiny invisible rectangle (see picture) in the header.
TLDR: is there a way I can temporarily disable that particular :hover style preferrably through javascript or jQuery?
Thanks for the help in advance.
My HTML code for anyone wondering: (I have removed unncessary stuff so it is easier to see what I mean)
<ul>
<li>Foo</li>
<li id="dropdown">
<p class="drop" id="loggedInValue"></p>
<ul class="dropdown-content">
<li>My Account</li>
<li>Logout</li>
</ul>
</li>
</ul>
When you are setting li to display: none, you can add a class to li (class-name, for example) and add :not(class-name) to the css.
See below example for reference
ul li:not(.class-name):hover > ul {
display: block;
}
P.S: I am wondering how is that little rectangle even visible, when you have set it to display: none. There is definitely some part left out when setting display to none
You could add a logged-in css class to the root html element, and predicate the hover selector on the presence of that class.
const onLoginSuccess = () => {
document.documentElement.classList.add('logged-in');
}
.logged-in ul li:hover > ul {
display: block;
}
If there should be no drop down then you should run some code similar to this.
Please let me know if this helped.
Have a good one.
const dropdown = document.querySelector('#dropdown');
dropdown.classList.remove('dropdown-styles');
Maybe you can just completely delete the element from the DOM
const dropdown = document.querySelector('#dropdown');
dropdown.parentNode.removeChild(dropdown);

Image slider in jQuery with actual slides as next/prev triggers

I'm a designer, have only a slight idea about jQuery. But I love learning :) So I decided to do the below thing myself, and I can't quite get it to work.
My idea is to have a slider with actual slides as next/prev buttons. So I can go to next slide by clicking the actual next slide - the same for previous slide. I guess the picture below shows what I mean.
Desired effect
I've tried to do it this way:
assign a class .main to the main image
assign a class .prev to the partially hidden image on the left
assign a class .next to the partially hidden image on the right
And when I click .next, I change classes .main > .prev, .next > .main, .next +1 > .next.
Now I can do it one step up and it works, the classes change and it works fine. But then when I click the now-.next class, jQuery seems to not recognize it's .next now and responds to it as if it were still the .main class. The updated classes don't respond (the now- .main class still works as .next, as if jQuery was not reading the change).
Here's the HTML:
<div class="view">
<ul>
<li class="left" data-id="1"></li>
<li class="main" data-id="2"></li>
<li class="right" data-id="3"></li>
<li data-id="4"></li>
<li data-id="5"></li>
</ul>
</div>
And the script:
$(".next").click(function(){
$(this).prev().removeClass("main").addClass("prev");
$(this).removeClass("next").addClass("main");
$(this).next().addClass("next");
$(".view ul li:first").animate({marginLeft: '-=57%'});
$(".view ul li.main").animate({marginLeft: '-=15%'});
});
I guess it's toddler talk for you, but perhaps you could help me get it to work. How would you come about the matter? Any ideas?
Big thanks up front!
Cheers!
It is not really toddler talk because there are a few pitfalls you need to be aware of.
First of all, the click handler will not work for the new .next this way.
You need to use
$('body').on('click', 'li.next', function() {
instead to make it work for dynamic content.
Another problem is that you forgot to remove the .prev class
$(".prev").removeClass("prev");
Another small mistake is: $(".view ul li:first").animate({marginLeft: '-=57%'}); which always takes the first element, but after the first slide it should take the .prev instead. (so change it to li.prev).
I guess btw that you use class="prev" instead of left (typo in question).
See the full code here:
http://jsfiddle.net/a8Lf9r68/3/
And as #Mō Iđɍɨɇƶ says, you need some additional code to handle the last and first element clicks. But that depends on what you want, and I see it as outside the scope of the question.

CSS precedence, when styling with JS

This question is in regards to precedence. I have an <ul> that contains my nav items in <li> I have an id for the <ul> which I use to reference the <li> and <a> tags nested within for styling. This all works fine, but when I use JavaScript to add a class to these specific <a> tags, to change the appearance when hovering over the links nothing happens.
I know the code is correct as I have tested it, but it just seems the ID styles take precedence over the Class's in when referencing styles.
How would I go about finding a solution, one idea I have is to remove the existing ID on mouseenter before adding the class, and then visa versa on mouseleave. Is there an easier solution?
ID styles are stronger, but you can use it when adding class for styling links as well.
So, if your menu is
<ul id="main">
<li><a href=#></a></li>
</ul>
And JS adds class "hovered" to element, then use CSS
#main .hovered {
.. styles here
}
Try adding !important to the end of your css for values which require overriding.
.class { color: #fbfbfb !important; }

Why CSS :active on link doesn't make the current page link highlighted?

I have the following code below for list into master page
<div id="header">
<ul>
<li>Home</li>
<li>Page1</li>
</ul>
</div> ​
with css
#header a:hover {
color: #AA1111;
border-color: #AA1111;
}
#header a:active {
color: #AA1111;
border-color:#AA1111;
}
but the link doesn't highlight with color when page is actived .
:active does not indicate that the link will be highlighted when the current page is active.
:active is the state of the link between mouse click and mouse released on the link. Try holding your mouse down on the link to see for yourself.
To set the current page's link in a different style you will need to either give the current page link a different class and target that class in your CSS.
If you're using .NET I recommend using the various CSS menu adapters / list controls that have the option of specifying the current page menu link class.
I think you are confusing the meaning of the pseudo-selector :active. That css rule will apply when you click on the link. But if that link brings you to a new page, the anchor is no longer active.
What you need to do is add a class to the anchor depending on what page you are on. So, in default.aspx you need to make sure that you have <a class="active" href="default.aspx">Home</a>. Then, you will need to change your css rule to #header a.active.
The way you may want to setup your page:
#header li {}
#header li.active a {color: #AA1111; border-color:#AA1111;}
<div id="header">
<ul>
<li class="active">Home</li>
<li>Page1</li>
</ul>
</div>
You will need to set the active class on the li based on which page.
Demo: http://jsfiddle.net/lucuma/HT4U4/

css and javascript onmouseover type effect

When I visit some sites and take mouse pointer over some menu item, another sub menu items comes up in another panel adjacent to main menu item. Thus giving an effect like onmouseover. But when I see the source code (like View source option in IE) there is no onmouseover / onmouseout event defined in the menu item list element.
For example, in the website http://www.seoconsultants.com/ - take mouse pointer over SEO Search on the left panel or in the website http://www.znetindia.com take mouse pointer Email option on top menubar
How to get such effect using css and javascript.
Without JS, just with CSS. Take a look at the source code: http://www.seoconsultants.com/css/seo.css
/* Begin CSS Popout Menus at Left */
#menuleft ul li{position:relative;}
#menuleft li ul{position:absolute;left:180px;top:0;display:none;padding:0;}
div#menuleft ul li:hover ul{display:block;}
Basically you say: "When the mouse is hovering over a parent list element, the child list should be visible."
This is done through the use of the :hover CSS attribute attached to the CSS rule of the parent node.
Consider the following HTML code:
<div class="parent">
<span class="label">Always on!</span>
<span class="hiddenLabel">Show on Mouse</span>
</div>
You achieve the effect you mention with the following css code:
.parent .hiddenLabel {
visibility: hidden;
}
.parent:hover .hiddenLabel {
visibility: visible;
}
This basically tells the browser that when a mouse hover event occurs on the "parent" node, the nodes with the CSS class of "hiddenLabel" will appear to the user and disappear when the mouse moves off the node.
This is the best practice for achieving this effect because of the load time and processing required for the javascript to start running on the page is longer than CSS being loaded.
Here is a great write-up on pseudo selectors and what each of them do: http://css-tricks.com/pseudo-class-selectors/
Take a look at jQuery and some plugins. See this site for a list of jQuery dropdown plugins. http://www.1stwebdesigner.com/resources/38-jquery-and-css-drop-down-multi-level-menu-solutions/

Categories