I have this HTML code :
<ul class="menu">
<li>Home <span class="icon home"></span><div class="clear"></div></li>
<li class="sub">Projects <span class="icon project"></span>
<div class="clear"></div>
<ul class="sub-menu">
<li>Mfrsht.com</li>
<li>Mawsuaty.com</li>
<li>Dzlng.com</li>
<li>Money(Ctrl)</li>
</ul>
</li>
<li>Ideas <span class="icon idea"></span><div class="clear"></div></li>
<li>Services <span class="icon service"></span><div class="clear"></div></li>
<li>About us <span class="icon about"></span><div class="clear"></div></li>
<li>Contact <span class="icon contact"></span><div class="clear"></div></li>
</ul>
and this Javascript code :
$(".menu > li").not(".menu > li.sub").css( {backgroundPosition: "0px 0px", height: "30px"} )
.mouseover(function(){
$(this).stop().animate({backgroundPosition:"(-167px 0px)", height: "36px"}, {duration:500})
})
.mouseout(function(){
$(this).stop().animate({backgroundPosition:"(0px 0px)", height: "30px"}, {duration:200, complete:function(){ $(this).css({backgroundPosition: "0px 0px"})
}})
})
$(".menu > li.sub").css( {backgroundPosition: "0px 0px"} )
.mouseover(function(){
$(this).stop().animate({backgroundPosition:"(-167px 0px)"}, {duration:500})
})
.mouseout(function(){
$(this).stop().animate({backgroundPosition:"(0px 0px)"}, {duration:200, complete:function(){ $(this).css({backgroundPosition: "0px 0px"})
}})
})
$(".sub").hover(function() {
$(this).animate({height: "150px"}, "slow", "", function () {
$(this).children("ul.sub-menu").slideDown("slow");
});
}, function() {
$(this).animate({height: "30px"}, "slow");
$(this).children("ul.sub-menu").slideUp("slow");
});
the Menu is working fine but sometimes I found it lag or there is some lateness so I want to improve it and make it better.
Note: I'm using background position plugin.
DEMO
Any suggestions? or do you think this good and no need to modify it?
Couple of things to consider:
Use mouseenter / mouseleave instead of mouseover / mouseout to actually get handlers fired when necessary (since you don't care if muse moves cursor within area of menu item - only which item cursor entered and leaved).
Use .stop(true) before running new animations in event handlers. You're already doing it in couple of places, but you've missed some spots (and you're not clearing the animation queue). Try to randomly move cursor around whole menu, then stop and watch the chaos. Event handlers are firing here and there, some items are "hovering", some items are showing submenus, just to be hidden a sec later. By passing true to stop function, you're telling jQuery to clear animation queue for matched object.
You might also consider using second argument for .stop(), which will tell jQuery to just go ahead and set state in which object would be after completting whole animation. That (passing that second argument) would however depend on how you tweak your code, so don't just do that - check if that's a desirable effect in here.
Related
I'm trying to do a transition on a list item:
HTML
<ul>
<li class="resume"><i class="fa fa-file-text-o"></i> Resumé</li>
<li><i class="fa fa-instagram"></i> Bio</li>
<li id="backtoprojects" class="is-hidden"></i> Back to Projects</li>
</ul>
Javascript
$('#backtoprojects').removeClass('is-hidden');
// hide back-to-projects-button on click of "backtoproject"
$('#backtoprojects a').on('click', function(){
hasher.setHash();
$('#backtoprojects').addClass('is-hidden');
});
$('[data-type="projectDie"]').click(function() {
$('body').removeClass('projectLoaded');
return false;
})
;
CSS
.navbar ul li.is-hidden {
display: none;
}
So right off the bat the "Back to Projects" is hidden, it appears when a project is clicked on, and if you click on "Back to Projects" again it hides itself. I tried swapping display:none for opacity or visibility but you can still see the spacing as if "Back to Projects" was still there. I envisioned the "Back to Projects" link to slide in from the right as the entire <ul> is float: right.
Try something like this:
$('#backtoprojects').hide();
$('a').on('click', function(){
$('#backtoprojects').show('slow');
});
$('#backtoprojects').on('click', function(){
$(this).hide('slow');
});
Full code here: https://jsfiddle.net/hdbj2rec/1/
Or you can use CSS to hide #backtoprojects initially.
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;
}
}
I'm new here and new to JavaScript and JQuery.
I've been working on a little script to get a part of my page switching videos from Youtube.
The problem I have is when a thumbnail has the class of 'selected' added I want to disable the click function to stop the video reloading - is there a simple way around this?
I attempted to put another bit of JQuery in to find the item with the 'selected' class and return false but I know this is wrong because that will stop the default browser behaviour and not the click event.
Also I'd be very grateful for explanations on code suggestions and also suggestions to improve/streamline my JQuery code.
Thanks in advance!
HTML:
<iframe id="vid" width="980" height="551" src="http://www.youtube.com/embed/hziG9Nr6KHU?&rel=0&controls=4&wmode=transparent&modestbranding=1&rel=0&showinfo=1" frameborder="0" allowfullscreen></iframe>
<ul id="videos">
<li id="one">
<a class="selected" href="http://www.youtube.com/embed/hziG9Nr6KHU?&rel=0&controls=2&wmode=transparent&modestbranding=1&rel=0&showinfo=1&autoplay=1 ">
<img src="http://placehold.it/320x180" />
<span class="AGreg">Vid1</span>
</a>
</li>
<li id="two" class="left">
<a href="http://www.youtube.com/embed/V1bFr2SWP1I?&rel=0&controls=2&wmode=transparent&modestbranding=1&rel=0&showinfo=1&autoplay=1 ">
<img src="http://placehold.it/320x180" />
<span class="AGreg">Vid12</span>
</a>
</li>
<li id="three" class="left">
<a href="http://www.youtube.com/embed/XLgYAHHkPFs?&rel=0&controls=2&wmode=transparent&modestbranding=1&rel=0&showinfo=1&autoplay=1 ">
<img src="http://placehold.it/320x180" />
<span class="AGreg">Vid3</span>
</a></li>
</ul>
CSS:
iframe#vid{width:980px;height:551px;}
.selected img{
opacity: 0.4;
filter: alpha(opacity=40); /* For IE8 and earlier */}
#videos .cursorD a{cursor:default!important}
#videos a:hover img{
opacity: 0.4;
filter: alpha(opacity=40); /* For IE8 and earlier */}
ul#videos{margin:20px 0;padding:0;}
ul#videos img{}
ul#videos li{float:left;width:320px;}
ul#videos li.left{margin:0 0 0 10px}
JQUERY:
$(document).ready(function(){
$("ul#videos li a").click(function(){
$("iframe").attr("src", $(this).attr("href"));
$(this).closest('ul#videos').find('.selected').removeClass('selected');
$(this).parent().addClass('selected cursorD');
return false;
})
});
CODEPEN: http://codepen.io/PixelsPencil/pen/uljzy
You could remove the event handler on the clicked video like you want to, but that requires a bit of code. An easier and (i.m.h.o. more elegant) solution is to adjust your selector / event handler hookup so it only gets executed on elements that do not have the class "selected":
$(document).ready(function(){
$("ul#videos li a:not('.selected')").click(function(){
$("iframe").attr("src", $(this).attr("href"));
$(this).closest('ul#videos').find('.selected').removeClass('selected');
$(this).parent().addClass('selected cursorD');
return false;
})
});
I have to confess, I didn't test it and I'm not 100% sure on the evaluation priority of :xyz() type selectors. To be more certain of what is happening, you could either change the single selector to a selector chain:
$("ul#videos").find("li").find("a:not('.selected')").click( ... );
or even better, hook the event handler to a parent object, but only have it trigger on distinct elements (also expressed through a selector):
$("ul#videos").on("click", "li a:not('.selected')", function() { ... });
This has the added charm that the handler will automatically work for lis that are added after wiring the event handler.
This seemed to work - asked a few people for help and a colleague came up with this still not sure why/how this works but it does.
var VideoLoader = {
registerClickHandlers: function() {
$("ul#videos li a").click(VideoLoader.showSelectedVideo);
},
showSelectedVideo: function() {
if(!VideoLoader.checkVideoIsAlreadyPlaying(this)) {
$("iframe").attr("src", $(this).attr("href"));
$(this).closest('ul#videos').find('.selected').removeClass('selected cursorD');
$(this).parent().addClass('selected cursorD');
}
return false;
},
checkVideoIsAlreadyPlaying: function(clickedObject) {
return $(clickedObject).parent().hasClass("selected");
}
};
$(document).ready(VideoLoader.registerClickHandlers);
Updated my Codepen here: http://codepen.io/PixelsPencil/pen/uljzy
thanks for replying again! I've had a play and put something up on jsfiddle but think it's more broke now than it ever was haha. When I click something with notselected class all thumbs change class and when I click a selected class the video loads in the parent instead of switching the attr in the iframe - any ideas where I've gone wrong?? jsfiddle.net/wvPnA
So today I wanted to make a simple animation that would make the button grow when I hover over the button, and shrink when I take the mouse off the button. I tried using this simple JQuery code, but the problem is that if I put the animation speed on slow, running on and off the button multiple times would create multiple queues of the animations, which will run long after my mouse has already left the button.
Is there a way to kill the queue after shrinking it if the mouse leaves the button? Obviously I would like to kill the queue after the button shrinks for the animation to be effective.
Related HTML:
<div id="global-nav">
<ul id="top-nav">
<li class="nav-list"><a class="nav" href="http://images6.fanpop.com/image/photos/33400000/Cats-cats-33441067-1280-800.jpg">Link1</a></li>
|
<li class="nav-list"><a class="nav" href="http://images4.fanpop.com/image/photos/16100000/-cats-16140154-1920-1080.jpg">Link2</a></li>
|
<li class="nav-list"><a class="nav" href="http://learningfromdogs.files.wordpress.com/2010/09/cats-in-sink.jpg">Link3</a></li>
|
<li class="nav-list"><a class="nav" href="http://25.media.tumblr.com/55b8c778e82b28aef27be5d6da8eaa7e/tumblr_meysfu2tM91qzv52ko1_500.jpg">Link4</a></li>
</ul>
</div>
Related JavaScript:
$(document).ready(function() {
$(".nav").mouseover(function() {
$(this).animate({
paddingTop:'6px',
paddingRight:'4px',
paddingBottom:'6px',
paddingLeft:'4px'
},"slow");
}).mouseout(function() {
$(this).animate({
paddingTop:'3px',
paddingRight:'2px',
paddingBottom:'3px',
paddingLeft:'2px'
},"slow");
});
});
JSFiddle: http://jsfiddle.net/76tna/
Please excuse the other CSS, cat text, and HTML. I am referring to the buttons in the nav bar. (If you're curious, this is for my younger sister.)
You need to .stop() the current animation before starting the next one, otherwise it will queue as you currently observe.
TRY THIS FIDDLE
You need to use the stop function, but if you look at the docs you see that you have to remember to input true to the function to clear the queue because it defaults to false.
$(document).ready(function() {
$(".nav").stop(true).mouseenter(function() {
$(this).animate({
paddingTop:'6px',
paddingRight:'4px',
paddingBottom:'6px',
paddingLeft:'4px'
},"slow");
}).mouseout(function() {
$(this).stop(true).animate({
paddingTop:'3px',
paddingRight:'2px',
paddingBottom:'3px',
paddingLeft:'2px'
},"slow");
});
});
$(document).ready(function() {
$(".nav").mouseover(function() {
$(this).css({
paddingTop:'6px',
paddingRight:'4px',
paddingBottom:'6px',
paddingLeft:'4px',
transition: 'padding 0.3s ease'
});
}).mouseout(function() {
$(this).css({
paddingTop:'3px',
paddingRight:'2px',
paddingBottom:'3px',
paddingLeft:'2px',
transition: 'padding 0.3s ease'
});
});
});
This code works perfectly except when you click on a link, The page is redirected before jquery has a change to visually animate the margin back to zero. Is there a way to prevent the redirect until after jquery animates the margin back to zero?
HTML
<div id="sidebar">
<div class="navigation">
<ul>
<li><img src="dbs/images/home.png" title="" width="40" height="38" />به عقب</li>
<li>فیلم ها</li>
<li>وزارتخانه ها ایران زنده</li>
<li>پرستش</li>
<li>جوانان</li>
<li>کودکان</li>
<li>پزوهش ها</li>
<li>دانشکده مسیح</li>
<li>زنان</li>
<li>کلیپ های سری</li>
</ul>
</div>
</div>
JS
$('.navigation a li').click(function () {
$('.slider').animate({
marginLeft: 0
}, 500);
});
.animate() takes a callback function like so:
$('.navigation a li').click(function () {
$('.slider').animate({
marginLeft: 0
}, 500,function() {
//thing to do when you animation is finished e.g.
location.href = 'http://redirect.to.url';
});
});
For complete documentation, check out the (extremely useful) jQuery docs:
http://api.jquery.com/animate/
Firstly, your HTML is invalid. Put the links inside the list items, not the other way around. Adjust your selector accordingly (.navigation li a).
Next, now that you're setting the event on the link rather than the list item, make your handler:
Prevent the default event
Add a callback to the animation, so that when the animation is over the page goes to this.getAttribute('href').
That should do it.
Stop the event propagation from li click handler.
$('.navigation a li').click(function (e) {
$('.slider').animate({
marginLeft: 0
}, 500);
e.stopPropagation();
});