JQuery rotate a span on clic - javascript

I'm working on my website (still need work), on the mobile nav, I have an expanding submenu, which has a span with a font character. What I want is for this character to rotate 180 degrees when clicked the first tima and go back to zero when clicked again, so far I've only been able to make it ratate the first time I click on it.
<ul>
<li class="parent"><span class="icon-house"></span>Home</li>
<li class="parent"><span class="icon-network"></span>Networks</li>
<li class="parent"><span class="icon-users"></span>Artists</li>
<li class="parent"><span class="icon-pictures"></span>Visual Art</li>
<li class="submenu parent genres">
<span class="icon-music"></span>Genres<span class="icon-arrow-down6 caret flechitauno"></span>
<ul class="children">
<li>House <span class="icon-music3"></span></li>
<li>Trance <span class="icon-music3"></span></li>
<li>Drum & Bass <span class="icon-music3"></span></li>
</ul>
</li>
<li class="parent"><span class="icon-info"></span>About this site</li>
</ul>
this is the jquery that I've been trying to use:
$(document).ready(main);
var flechitauno = 1;
//flip
$('.genres').click(function(){
if(flechitauno == 1){
$('.flechitauno').css({
transform: 'rotate(180deg)'
});
flechitauno = 0;
}else{
flechitauno = 1;
$('flechitauno').css({
transform: 'ratate(0deg)'
});
}
});
}
This is the adress of the website: http://66.68.113.215/design-3
the js file is /js/menu.js,
and the css is /css/menu.css

Try something like this (see effect working here: https://jsfiddle.net/p1xfuc1t/):
HTML:
<li class="submenu parent genres">
<span class="icon-music"></span>Genres<span class="icon-arrow-down6 caret flechitauno"></span>
<ul class="children">
<li>House <span class="icon-music3"></span> </li>
<li>Trance <span class="icon-music3"></span></li>
<li>Drum & Bass <span class="icon-music3"></span></li>
</ul>
CSS:
#keyframes roll {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
JS
$(document).ready(function() {
$('.genres').on('click', function() {
$('.flechitauno').css(
"animation", "roll 3s"
)
});
});
Aslo check your syntax for the .css() method, it dosent seem right.
Well either this or you use an external library like: http://jqueryrotate.com/.

So, I decided to listen to jsfiddle.net/0oo0fyra/1 – timo, who asked why not use plain javascript, so I researched a little bit more and came up with this solution
For the html, I used some in-line js to trigger the function 'flip' in a separate js file, since this a tag was already styled as block with css, I decided to use it to activate the onclick function, sending the span id as an argument to the function
<span class="icon-music"></span>Genres<span class="icon-arrow-down6 caret" id="genres"></span>
In the js file 'menu.js' I defined a variable to work with the function, and the 'flip' function, I defined the starting value of the variable 'voltear to 1' outside of the function as a global one to that it won't be reassigned every time the onclick function triggers, then the function receives the id of the span and uses it to target the span, then I just wrote what I wanted my span to do
var voltear = 1
function flip(id){
if (voltear == 1) {
document.getElementById(id).style.transform = "rotate(180deg)";
voltear = 0;
}else{
document.getElementById(id).style.transform = "rotate(0deg)";
voltear = 1;
}
}

Related

removeClass() is completely deleting elements from DOM

This is a build off of my previous question: Select a child of a child
I now have a <ul> within another <ul>. The behavior is an expandable menu. I'm doing this by adding and removing classes. For some reason...on the sub list - it completely removes the <li> elements from the DOM rather than just toggling it's classes. Why would it do that!?
You can see an example below:
$(function() {
// main expansion element
$(".expander").click(function() {
var subShown = $("ul > li", this).hasClass("show");
if (!subShown) {
$(".indented", this).slideDown('100').addClass("show");
$(".caret", this).addClass("reversedCaret");
} else {
$(".indented", this).slideUp('100').removeClass("show");
$(".caret", this).removeClass("reversedCaret");
}
});
// sub expansion element
$(".sub-expander, .caret").click(function() {
var subSelectText = $(".sub-expander").text();
if (subSelectText != "More") {
$(".indented--sub", this).slideUp('100').removeClass("show");
$(".caret", this).removeClass("reversedCaret");
$(".more-or-less").text("More");
} else {
$(".indented--sub", this).slideDown('100').addClass("show");
$(".caret", this).removeClass("reversedCaret");
$(".more-or-less").text("Show Less");
}
});
// stop propagation on the link element within .expander class
$(".indented").click(function(event) {
event.stopPropagation();
});
});
.expander:hover {
cursor: pointer;
}
.sub-expander--indented {
padding: 0 0 0 23px;
}
.sub-caret {
margin-right: 75px;
}
.indented,
.indented--sub {
display: none;
}
.show {
display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
<div class="expander">
<span class="caret downCaret right visibleCaret">+</span>
<ul>
<li class="category">Item 1
</li>
<li class="indented">Item 2</li>
<li class="indented">Item 3
<ul class="sub-expander indented more" style="padding-top:
0px;">
<li class="indented--sub">Chapter 5</li>
<li class="indented--sub">Chapter 6</li>
<li class="indented--sub">Chapter 7</li>
<span class="sub-caret moreCaret visibleLessCaret right">+</span>
<li class="more-or-less less sub-expander--
indented">More</li>
</ul>
</li>
</ul>
</div>
I'm giving it a separate classname to differentiate from the main section so that they don't show on initial open, so I'm not sure why it is behaving the way it is. It seems like there is a better way to go about this but I don't know what that would be.
UPDATE: was pointed out I did not have valid HTML. Fixed it following this thread. Still broken.
UPDATE #2: It seems like the problem is .text() - so it completely erases everything? I thought it just replaced the text node, and not all of it's children. I tried .html() but it does the same thing. What method do I use to just replace text then?
UPDATE #3 - one answer suggests I needed a more specific selector. I gave the list item a class of .more-or-less but doing that, it doesn't expand at all.
You'd probably want to use a more strict selector.
In your example case you use .sub-expander to select the node of which you want to replace the text. This matches with the ul.sub-expander however.
Since you want it to replace the text of the li.sub-expander the simplest thing you could do would be to use a more specific selector:
$("li.sub-expander").text("Show Less"); or (better) give the node which contains the text you want to replace another classname, id or other identifier to prevent targeting a different element.

javascript color toggles between two links working, not resetting when they need to

I have two links popularity and new. if I click "popularity" it should turn green until I click "new". and vice versa for "new". And this works great. But thing is when I click home button that's in my navbar, the green color on the link should be gone. they should go back to the color they were before they are clicked.
my code
<div id="Space">
<ul id="shouldwork">
<li role="presentation" class="sort">
<a class="norang" href="/?sort=score&page=1" style="text-decoration:none;">popularity</a>
</li>
<li role="presentation" class="date">
<a class="updated" href="/?sort=date&page=1" style="text-decoration:none;">new</a>
</li>
</ul>
</div>
<script>
//on page load
var ul_li_a = $("ul#shouldwork>li>a");
var lastClickTag = localStorage.getItem("last_clicked");
ul_li_a.css("color", "black");
if(lastClickTag){
$("."+lastClickTag).css("color", "green")
}
$('ul#shouldwork>li').on("click", function(){
ul_li_a.css("color", "black");
$(this).children("a").css("color", "green");
localStorage.setItem("last_clicked", $(this).children("a").attr("class"));
});
</script>
and in navbar I have
<div class="navbar-header">
<a class="navbar-brand" href="{% url 'index' %}">home</a>
</div>
I would do this with an .active class in CSS in order to make it more modular and easy to understand. Then, I would change the color based on your query strings, rather than using local storage.
I didn't have a way to test this so let me know if it works. If not, let me know what error is displaying in the console. I'm sure I may have missed something in the JS.
Here is a codepen if you'd rather look at it there: http://codepen.io/anon/pen/xVGYWE?editors=1111
HTML (links are removed as they broke in codepen, added class .link for better targeting in jQuery)
<div id="Space">
<ul class="shouldwork">
<li role="presentation" class="sort">
<a class="link norang" href="#">popularity</a>
</li>
<li role="presentation" class="date">
<a class="link updated" href="#">new</a>
</li>
</ul>
</div>
CSS
.link {
color: blue;
text-decoration: none;
}
.link:hover {
color: navy;
text-decoration: none;
}
.link.active {
color: green;
}
jQuery
// change on click
var link = $('.link');
link.on("click", function(){
// remove any active classes
link.removeClass("active");
// add active class to link that was clicked
$(this).addClass("active");
});
// set up get query strings from URL
function getParameterByName(name, url) {
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
// see if the page is indeed sorted
var sort = getParameterByName('sort')
// if it has a query string of sort=score, make that active
if ( sort == "score") {
$(".sort a").addClass("active");
}
// if it has a query string of sort=date, make that active
if ( sort == "date") {
$(".date a").addClass("active");
}
Why should they go back to the original color? You never told them to.
$('.navbar-brand').on('click',function(){
ul_li_a.css("color", "black");
})
You could utilize both .addClass and .removeClass, and create another CSS class that changes the color back when you click the home button. This would be more seamless if you took the css out of your js code, and just use these two methods to switch between the classes you need on the home button click event.
edit: or what he said ^. There are many options.
Based on your problem description, and a quick scan of your code, it looks like you are properly setting the color when the two items themselves are clicked, but you have no function to handle unsetting the color when something else is clicked ... i.e. in your function that fires on-click, just check that if neither is used, clear the green color.
Alternatively, you could use something like is used here ... i.e. a conditional something along the lines of this: if(a[i].href.split("#")[0] == window.location.href.split("#")[0]). Then, just apply the green color if either of your two links are active.
Hope this helps!
If you can use ids for links, change your code as below. Check demo - Fiddle.
var ul_li_a = $("ul#shouldwork>li>a");
var lastClickTag = localStorage.getItem("last_clicked");
if(lastClickTag){
$("#"+lastClickTag).addClass('green');
}
ul_li_a.on("click", function(){
ul_li_a.removeClass('green');
$(this).addClass('green');
localStorage.setItem("last_clicked", this.id);
});
$('.navbar-brand').click( function() {
ul_li_a.removeClass('green');
$("#"+lastClickTag).addClass('green');
})
HTML:
<ul id="shouldwork">
<li role="presentation" class="sort">
<a id="norang" href=".." style="text-decoration:none;">popularity</a>
</li>
<li role="presentation" class="date">
<a id="updated" href=".." style="text-decoration:none;">new</a>
</li>
</ul>
CSS:
.green {
color: green;
}
Clearing your lastClickTag from the local storage must resolve your issue along with this code.
$('.navbar-brand').on('click',function(){
localStorage.removeItem("last_clicked");
})
remove this local storage. So your if(lastClickTag){ function will not be executed, And your color will remain black.

Hide/show div in ul with javascript

Let me start by saying I know this is a duplicate, however I couldn't find a solution by looking through previous answers so I was hoping someone can explain what I'm doing wrong with this.
This is part of a menu output by a php script:
<ul id="mtk_main_menu">
<li class="mtk_topmenu" onMouseOver="showMenu('mtk_submenu_0', 'mtk_div_submenu_0');">Manager Options
<div id="mtk_div_submenu_0">
<ul id="mtk_submenu_0">
<li class="mtk_submenu">Preferences</li>
<li class="mtk_submenu">Employee Options</li>
</ul>
</div>
</li>
with the following as my script as per https://stackoverflow.com/a/11842992, which should show each submenu when hovering its parent container
function showMenu(a,b) {
$(a).hover(
function(){
$(b).show();
},
function(){
$(b).hide();
})
}
Javascript and CSS being my weak suits, could someone tell me where my problem is? I feel like onMouseOver doesn't work the way I would expect it to. However I am still learning to manipulate the DOM, please bear with me, thank you!
Edited to reflect missingno's suggestions
For simple scenarios, i'd rather stay away from using JS
Heres how
HTML
<ul id="mtk_main_menu">
<li class="mtk_topmenu" onMouseOver="showMenu('mtk_submenu_0, mtk_div_submenu_0');">Manager Options
<div id="mtk_div_submenu_0">
<ul id="mtk_submenu_0">
<li class="mtk_submenu">Preferences</li>
<li class="mtk_submenu">Employee Options</li>
</ul>
</div>
</li>
CSS
#mtk_main_menu:before,
#mtk_main_menu:after {
content:"";
display:table;
clear:both;
}
#mtk_main_menu {
*zoom:1;
}
#mtk_main_menu > li {
position:relative;
float:left;
}
#mtk_main_menu > li > div {
position:absolute;
left:-999px;
background:grey;
}
#mtk_main_menu > li:hover > div {
left:0;
}
That will do the trick
Fiddle: http://jsfiddle.net/Varinder/7pXSw/
Edit
If you really want to go the JS way - heres how:
HTML
<ul id="mtk_main_menu">
<li class="mtk_topmenu" onMouseOver="showMenu('mtk_submenu_0, mtk_div_submenu_0');">Manager Options
<div id="mtk_div_submenu_0">
<ul id="mtk_submenu_0">
<li class="mtk_submenu">Preferences</li>
<li class="mtk_submenu">Employee Options</li>
</ul>
</div>
</li>
CSS
#mtk_main_menu:before,
#mtk_main_menu:after {
content:"";
display:table;
clear:both;
}
#mtk_main_menu {
*zoom:1;
}
#mtk_main_menu > li {
position:relative;
float:left;
}
#mtk_main_menu > li > div {
position:absolute;
display:none;
/*left:-999px;*/
background:grey;
}
#mtk_main_menu > li:hover > div {
/*left:0;*/
}
JS
function showMenu( args ) {
var arguments = args.split(",");
var submenuWrapper = arguments[1].replace(" ", "");
var $subMenuWrapper = $( "#" + submenuWrapper );
$subMenuWrapper.show();
var $menuItem = $subMenuWrapper.closest("li");
$menuItem.on("mouseout", function() {
$subMenuWrapper.hide();
$(this).off("mouseout");
});
}
Fiddle: http://jsfiddle.net/Varinder/vnwy3/1/
You are calling the event handler with a single string parameter instead of two. Try changing
showMenu('mtk_submenu_0, mtk_div_submenu_0')
into
showMenu('mtk_submenu_0', 'mtk_div_submenu_0')
Additionally, inside your script you should use are using literal strings instead of using your parameters
//This looks for an element of class "a"
$("a").hover(
//This uses the contents of the `a` variable instead:
$(a).hover(
Finally, your function is using 'mtk_submenu_0' as a jquery selector. This searches for a class instead of an id. Change the selector to add a "#" on front or change your jquery logic to not need ids (for example, you could create selectors to search for the first div and ul descendants of the current element.
By doing what you are doing, every time the onMouseOver event is triggered, you're attaching the jQuery hover event. Each time you're attaching another listener.
Instead, initialize your event on document ready:
$(function () {
$("#tk_div_submenu_0").hover(
function(){
$("#mtk_submenu_0").show();
},
function(){
$("#mtk_submenu_0").hide();
})
);
});
That will initialize it when the document is ready, and it will initialize it once.
Then just remove your onMouseOver event from the HTML.
<li class="mtk_topmenu">Manager Options ... </li>
First, you're going the long way around the problem. jQuery has a built in toggle method that performs the show/hide for you. Secondly you're putting the hover call on the child element of the item you're trying to show on hover. Here's an updated version of your code:
<ul id="mtk_main_menu">
<li class="mtk_topmenu" onMouseOver="showMenu(this,'mtk_div_submenu_0');">
Manager Options
<div id="mtk_div_submenu_0">
<ul id="mtk_submenu_0">
<li class="mtk_submenu">Preferences</li>
<li class="mtk_submenu">Employee Options</li>
</ul>
</div>
</li>
</ul>
JS:
function showMenu(a,b) {
var divStr = '#' + a.id + " div";
$(divStr).toggle();
}
I used the hover event on the LI element as it makes more sense in this case.
Here it is in a fiddle: http://jsfiddle.net/3Ecrq/
One thing I find strange about your code is that the first div you mention, mtk_submenu_0, is inside the div you are showing / hiding, mtk_div_submenu_0. Once you hide the outer div, the inner div cannot be 'hovered over', thus preventing it from being shown again.
To ensure the inner div does not get hidden, try something like this:
HTML:
<ul id="mtk_main_menu">
<li class="mtk_topmenu">Manager Options
<div id="mtk_div_submenu_0">
<ul id="mtk_submenu_0">
<li class="mtk_submenu">Preferences</li>
<li class="mtk_submenu">Employee Options</li>
</ul>
</div>
</li>
Javascript:
$(document).ready(function() {
$('.mtk_topmenu').hover(
function() {
$('#mtk_div_submenu_0').show();
},
function() {
$('#mtk_div_submenu_0').hide();
});
});
Because of your line:
<li class="mtk_topmenu" onMouseOver="showMenu('mtk_submenu_0', 'mtk_div_submenu_0');">
I assumed you were looking to have the mtk_div_submenu_0 div show / hide whenever the text Manager Options is moused over. Hopefully this helps!

Show a div when a link with a class is clicked

I am wanting to show/fadein a <div> with an ID of "signInHold" when the <li> "Sign In" is clicked using the class signInActive on the <li>.
<ul class="nav1">
<li class="nav2">
Home
</li>
<li class="nav2">
Settings
</li>
<li class="nav2">
Download
</li>
<li class="nav2 signInActive">
Sign In
</li>
</ul>
Could you please also tell me if I need to add:
<script src="http://code.jquery.com/jquery-latest.js"></script>
You can do this with jQuery, or you can do it with straight CSS using the transition property; it's entirely up to you and the needs of your project.
jQuery will give you far better cross-browser support:
$(".nav1").on("click", ".signInActive", function () {
$(".bar").fadeIn();
});
Or, you could do it with CSS:
.foo {
opacity: 0;
}
.foo.activated {
transition: opacity 2s;
opacity: 1;
}
And simply toggle the class:
var element = document.querySelector(".signInActive");
var target = document.querySelector(".myDIV");
element.addEventListener("click", function () {
target.classList.toggle("activated");
}, false);
If you're going to use jQuery (in the head)
<script src="http://code.jquery.com/jquery-latest.js"></script>
<script>
$(document).ready(function() {
$("#signInHold").hide();
$(".signInActive").click(function() {
$("#signInHold").fadeToggle("slow"); <--This targets the div with ID signInHold
});
});
</script>
I think this is what you're looking for:
$('.signInActive').click(function () { $('#signInHold').show(); });
This assumes you do load jQuery, of course.
Yes you need to add jquery
Add the class signIn to your li and now when you click the div will appear
and the class signInActive added to you
<li class="nav2 signIn">
Sign In
</li>
$(document).ready(function(){
$('.signIn').click(function(){
$('#signInHold').fadeIn(300);
$(this).addClass('signInActive');
});
});

Define number of visible elements

Some introduction:
Hello, i wanted to ask, if there is an easy way, to know how many of "tabs" are visible for user when he clicks on some button?
Description of what i have so far:
http://jsfiddle.net/L7bPc/7/
Here, on jsfiddle, you can see example of tabs i am thinking of, when you widen or narrow the width, more or less tabs are visible (rest disappears thanks to "overflow:hidden;").
Question:
My question is, is there any easy way to get to know, how many tabs are visible once clicking on red square in top right corner?
Explanation of what i want to achieve:
Why? Because i will try to generate a list of "not visible" tabs, once clicked on red square later (i will style it properly ofcourse). I want it to look similar to many programs with tabs, when there are too many of them, you can find a little arrow on the end of it, to expand the rest of tabs, in drop down menu.
I am asking how to know how many tabs are visible, and how many not (so i know which to generate after clicking on it in dropdown), i am NOT asking how to create the dropdown.
This part is generated by php, getting data from MySQL database, and style them in css to look like tabs (i didn't use php in jsfiddle, just plain html):
<div class="tabs">
<ul>
<li id=090NCI class='active'><a href='#' class='active'><span class='active'>090NCI</span></a></li>
<li id=061PPP><a href='#'><span>061PPP</span></a></li>
<li id=072KWM><a href='#'><span>072KWM</span></a></li>
<li id=057ALS><a href='#'><span>057ALS</span></a></li>
<li id=099AKG><a href='#'><span>099AKG</span></a></li>
<li id=090WPW><a href='#'><span>090WPW</span></a></li>
<li id=020MSM><a href='#'><span>020MSM</span></a></li>
<li id=014LSP><a href='#'><span>014LSP</span></a></li>
<li id=010AAV><a href='#'><span>010AAV</span></a></li>
<li id=080MKS><a href='#'><span>080MKS</span></a></li>
<li id=006ALS><a href='#'><span>006ALS</span></a></li>
<li id=007KSG><a href='#'><span>007KSG</span></a></li>
<li id=091AOW><a href='#'><span>091AOW</span></a></li>
<li id=004ALO><a href='#'><span>004ALO</span></a></li>
<li id=003WWW><a href='#'><span>003WWW</span></a></li>
<li id=002KSO><a href='#'><span>002KSO</span></a></li>
<li id=001NWD><a href='#'><span>001NWD</span></a></li>
</ul>
<div style="position: absolute; right:5px; top:26px; background: red; color:red; width:20px; height: 20px;" onclick="dosomething()"></div>
</div>
Any tips? Solutions might be both, in jQuery and javascript, no big difference for me.
Try this:
$("#redbox").click(function() {
var visibleLis = $("li").filter(function() {
var offset = $(this).offset();
return $(document.elementFromPoint(offset.left, offset.top)).closest(this).length > 0;
});
alert(visibleLis.length);
});
http://jsfiddle.net/L7bPc/11/
If you defined the .tabs to fully vertically contain the tabs, you can use far more optimized version:
$("#redbox").click(function() {
var boundingBox = $(".tabs")[0].getBoundingClientRect(),
bbRight = boundingBox.left + boundingBox.width,
bbBottom = boundingBox.top + boundingBox.height,
bbLeft = boundingBox.left,
bbTop = boundingBox.top;
var visibleLis = $("li").filter(function() {
var box = this.getBoundingClientRect(),
left = box.left,
top = box.top,
right = box.left + box.width,
bottom = box.top + box.height;
return left >= bbLeft && right <= bbRight && top >= bbTop && bottom <= bbBottom;
});
alert(visibleLis.length);
});
http://jsfiddle.net/L7bPc/13/

Categories

Resources