jQuery show hide sliding panel from left side - javascript

I want a panel to slide from left edge of browser when clicking a button and hide the panel when clicking the same button (toggle).
Html
<div class="panel">
</div>
»
CSS
.panel {
width:300px;
float:left;
height:550px;
background:#d9dada;
position:relative;
left:-300px;
}
.slider-arrow {
padding:5px;
width:10px;
float:left;
background:#d9dada;
font:400 12px Arial, Helvetica, sans-serif;
color:#000;
text-decoration:none;
position:relative;
left:-300px;
}
jquery
$(function(){
$('.slider-arrow.show').click(function(){
$( ".slider-arrow, .panel" ).animate({
left: "+=300"
}, 700, function() {
// Animation complete.
});
$(this).html('«').removeClass('show').addClass('hide');
});
$('.slider-arrow.hide').click(function(){
$( ".slider-arrow, .panel" ).animate({
left: "-=300"
}, 700, function() {
// Animation complete.
});
$(this).html('»').removeClass('hide').addClass('show');
});
});
It is showing the panel but not hiding the panel. Any problem with the selectors used?
http://jsfiddle.net/Paramasivan/eHded/1/

As others have said with jQuery once the document is initialized its only looking for elements that initially existed. For that reason your .show function was being run every time.
Instead of looking for a click event on .slider-arrow.show you can just look at .slider-arrow and then check for the classes once it has been clicked like in this example.
$(function(){
$('.slider-arrow').click(function(){
if($(this).hasClass('show')){
$( ".slider-arrow, .panel" ).animate({
left: "+=300"
}, 700, function() {
// Animation complete.
});
$(this).html('«').removeClass('show').addClass('hide');
}
else {
$( ".slider-arrow, .panel" ).animate({
left: "-=300"
}, 700, function() {
// Animation complete.
});
$(this).html('»').removeClass('hide').addClass('show');
}
});
});
http://jsfiddle.net/eHded/4/

Since you are using jQuery to manipulate the "show" and "hide" after the DOM has loaded, jQuery doesn't know those elements exist.
Event handlers are bound only to the currently selected elements; they must exist on the page at the time your code makes the call...
I suggest using jQuery's on() in order to delegate events and select dynamically generated classes, like so:
$(document).on('click','.slider-arrow.show',function(){
....
});
$(document).on('click','.slider-arrow.hide',function(){
....
});
http://jsfiddle.net/eHded/2/

I think you can manage the action choosing from the active anchor class like this:
$(function(){
$('.slider-arrow').click(function(){
var anchor = this;
var removeClass = "show";
var addClass = "hide";
var diff = "+=300";
var arrows = "«";
if($(anchor).hasClass("hide")){
diff = "-=300";
removeClass = "hide";
addClass="show";
arrows = '»';
}
$( ".slider-arrow, .panel" ).animate({
left: diff
}, 700, function() {
// Animation complete.
$(anchor).html(arrows).removeClass(removeClass).addClass(addClass);
});
});
});
So you've got only one animation function.
Here is the updated fiddle: http://jsfiddle.net/eHded/5/

You should try using .slideToggle(), put inside a .click(function(){/*in here*/}).

When you write $('.slider-arrow.hide').click(func....., that binds the click event at the time that code is first ran (probably when the document is ready). If you change the DOM later on (ie. add the .hide class) you need to re-bind the click event.
You need to use jQuery's .on() method instead (http://api.jquery.com/on/).
$(document).on('click', '.slider-arrow.show', function() { /*.......*/ });
$(document).on('click', '.slider-arrow.hide', function() { /*.......*/ });
A better alternative altogether however would be to use CSS3 transitions and jQuery's .toggleClass()
.panel {
left: -300px;
transition: left 1s;
/* other styles... */
}
.panel.expand {
left: 0;
}
$('.slider-arrow').click(function() {
$('.panel').toggleClass('expand');
}

For this task I use SlideReveal jQuery plugin.
After you include the library the setup is as easy as:
<div id='slider'>Hello World!!</div>
<button id='trigger'>Trigger</button>
<script>
$('#slider').slideReveal({
trigger: $("#trigger")
});
</script>
Please refer to documentation for more details and live samples.

Related

Why document selector doesn't work for mouseenter event?

Here is my code:
$.fn.right = function() {
return $(document).width() - (this.offset().left + this.outerWidth());
}
$(document).ready(function(){
$('a').bind('mouseenter', function() {
var self = $(this);
this.iid = setTimeout(function() {
var tag_name = self.text(),
top = self.position().top + self.outerHeight(true),
right = self.right();
$('body').append("<div class='tag_info'>Some explanations about "+tag_name+"</div>");
$(".tag_info").css({top: top + "px", right: right + "px"}).fadeIn(200);
}, 525);
}).bind('mouseleave', function(){
if(this.iid){
clearTimeout(this.iid)
$('.tag_info').remove();
}
});
});
body{
padding: 20px;
direction: rtl;
}
a {
color: #3e6d8e !important;
background-color: #E1ECF4;
padding: 2px 5px;
}
.tag_info{
position: absolute;
width: 130px;
height: 100px;
display:none;
background-color: black;
color: white;
padding: 10px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a>long-length-tag</a>
<a>tag</a>
It works fine. But in reality, the content (those tags) will be created later. I mean they will be created as an ajax response. So $('a') doesn't select them.
Now I'v written it like $(document).bind('mouseenter', 'a', function(){ ... }) to make that working even for the DOM which is created after page loading.
But as you see in this fiddle, it doesn't work. Does anybody know what's the problem and how can I fix it?
You need to bind the event with .on(). This works for future elements as well.
$(document).on('mouseenter', 'a', function(){ ... });
And, as #Gregg has answered, .bind() has been replaced by .on(). That's the actual cause why your fiddle doesn't work.
The on() function has replaced bind() since jQuery 1.7. If you read the documentation, you'll note that live() was actually used for delegate events like what you're trying to achieve while the bind() method was not; binding events to elements that will be added to the DOM later. The on() function can do this. Either from the document itself or from a direct descendent.
When anchor tag are being created in response of your AJAX call, put id in it like this:
$('body').append("<div class='tag_info' id='myTag'>Some explanations about "+tag_name+"</div>");
and then you can bind event mouseenter or mouseleave like this:
$('#myTag').bind('mouseenter', function(){
alert('Mouse Enter in your Anchor Tag');
}).bind('mouseleave', function(){
alert('Mouse leave');
});

Jquery on click show mouseleave hide sidebar

Hi i need some with the this script i manage to show the panel with the mouseclick but i wanted when my mouse leave the panel it will close it
this is the sample http://jsfiddle.net/jikey/w9s7pt25/
$(function(){
$('.slider-arrow').click(function(){
if($(this).hasClass('show'))
{
$( ".slider-arrow, .spanel" ).animate({
right: "+=182"
}, 700, function() {
// Animation complete.
});
$(this).html('<img src="images/sideclose.png" />').removeClass('show').addClass('hide');
}
else
{
$( ".slider-arrow, .spanel" ).animate({
right: "-=182"
}, 700, function() {
// Animation complete.
});
$(this).html('<img src="images/sideopen.png" />').removeClass('hide').addClass('show');
}
});
});
Here you need to write 2 methods.
jQuery click to display the section on clicking on the arrow and jQuery onmouseleave to hide the section on coming out of the section.
I suggest you to display the slideopen.png and slideclose.png files in the (background style) CSS with respect to the classes.
Method 1: on click
jQuery Code:
$('.slider-arrow').on("click", function(){
if($(this).hasClass('show')){
$( ".slider-arrow, .panel" ).animate({
right: "+=300"
}, 700, function() {
// Animation complete.
}); $(this).html('«').removeClass('show').addClass('hide');
}
});
Method 2: on mouse leave
jQuery Code:
$(".panel").on("mouseleave", function(){
if(!$('.slider-arrow.show').hasClass('show')) {
$( ".slider-arrow, .panel" ).animate({
right: "-=300"
}, 700, function() {
// Animation complete.
});
$(".slider-arrow").removeClass('hide').addClass('show');
}
});
Demo link: http://jsfiddle.net/w9s7pt25/7/
What you can do is add a seperate mouseout function as illustrated in this jsfiddle. The problem with your code was that the mouseover event only acts on .slider-arrow once, changes the class to hide and then expects another mouseover to read that it needs to be hidden.
$(function () {
$('.slider-arrow').mouseover(function () {
if ($(this).hasClass('show')) {
$(".slider-arrow, .panel").animate({
right: "+=300"
}, 700, function () {
// Animation complete.
});
$(this).html('«').removeClass('show').addClass('hide');
}
});
$('.panel').mouseout(function () {
if ($('.slider-arrow').hasClass('hide')) {
$(".slider-arrow, .panel").animate({
right: "-=300"
}, 700, function () {
// Animation complete.
});
$('.slider-arrow').html('»').removeClass('hide').addClass('show');
}
});
});
Hope it makes sense.
You can use mouseout or mouseleave. I guess you would add some elements in panel. So mouseout fires when the pointer moves out of child element as well, while mouseleave fires only when the pointer moves out of the bound element
$('.panel').mouseleave(function() {
if($('.slider-arrow').hasClass('hide')){
$( ".slider-arrow, .panel" ).animate({
right: "-=300"
}, 700);
$('.slider-arrow').html('&raquo').removeClass('hide').addClass('show');
}
});
You can attach the jquery .mouseleave() function on the panel and let it execute only when the panel is visible also add a class like 'visible' to keep state of the visibility of your panel like so: http://jsfiddle.net/gakuru/d2qnrm2x/
$('.panel').on('mouseleave',function(){
if($(this).hasClass('visible')){
$( ".slider-arrow, .panel" ).animate({
right: "-=300"
}, 700, function() {
// Animation complete.
});
$('.slider-arrow').html('»').removeClass('hide').addClass('show');
$('.panel').removeClass('visible');
}
});

Animation only for hovered element

Trying to do some trick with my post information.
When I hover mouse on one element - all elements became active.
How can I made this animation only to hovered element?
Tried it:
$('.post-pic-holder').find('.post-info').hover(function(){
$(this).animate({bottom:'0'},200);
},function(){
$(this).animate({bottom:'-30px'},200);
});
http://jsfiddle.net/fresa150/8ftnF/
You need to target specific descendant, e.g:
$(document).ready(function(){
$('.post-pic-holder').hover(function(){
$(this).find('.post-info').animate({bottom:'0'},200);
},function(){
$(this).find('.post-info').animate({bottom:'-30px'},200);
});
});
--DEMO--
FYI, jQuery hover method accepts in/out handler:
$('.post-pic-holder').hover(function (e) {
$(this).find('.post-info').animate({
bottom: e.type === "mouseenter" ? 0 : -30
}, 200);
});
--DEMO--
But could be done only in CSS for browser which support CSS3 transition:
.post-info {
transition: bottom 200ms;
}
.post-pic-holder:hover .post-info {
bottom: 0;
}
--DEMO CSS--
Try this:
$(document).ready(function(){
$('.post-pic-holder').hover(function(){
$(this).first().animate({bottom:'0'},200);
},function(){
$(this).first().animate({bottom:'-30px'},200);
});
});

jquery animate then stop

Struggling a bit with jquery animate.
At the moment, if I continue to click button, clearly it shifts the object to the right 50px every time
$( ".button" ).click(function() {
$( "#object" ).animate({opacity: 1,right: "+=50",}, 500, function() {}
);
Is there a way of ensuring that one click moves it once, then a second click does not move it?
ie. a rule that moves it to right:50px and thats it, rather than + 50px?
Any assistance hugely appreciated!!
Use .one()
$( ".button" ).one('click',function() {
Fiddle Demo
You can use one():
$(".button").one('click', function () {
$("#object").animate({
opacity: 1,
right: "+=50",
}, 500, function () {
});
});
or I'd suggest you to disable the button to let your users know about your intention here:
$(".button").click(function () {
var $this = $(this);
$("#object").animate({
opacity: 1,
right: "+=50",
}, 500, function () {
$this.prop("disabled",true);
});
});

I've got a problem with a toggling sidebar using jQuery

I'm trying to create a simple toggling sidebar using jquery, where it expands and contracts when a button is pressed. The button also changes to another type of button when pressed. The sidebar will expand, but for some reason, it will not move back to it's original position.
You can see a copy of the javascript and html at http://www.jqueryhelp.com/viewtopic.php?p=4241#4241
Here is the working code, thanks Bendeway! :D
$(".btn-slide").live('click', function(e){
e.preventDefault();
$("#sidebar").animate({opacity: "show", left: 250}, "slow");
$(this).toggleClass("btn-slide").toggleClass("active");
});
$(".active").live('click', function(e){
e.preventDefault();
$("#sidebar").animate({opacity: "hide", left: 100}, "slow");
$(this).toggleClass("btn-slide").toggleClass("active");
});
try instead of right use left with a negative number. in addition I would recommend using preventDefault instead of returning false.
$(".active").click(function(e){
e.preventDefault();
$("#sidebar").animate({opacity: "hide", left: -250}, "slow");
$(this).toggleClass("btn-slide");
});
Update
Another piece i just noticed is that your attaching a click event to the .active button, when the document is ready, but there is no .active button when the document is ready that comes in after you change it. There are a couple options here.
First is to use the new live feature of jquery 1.3
$(".btn-slide").live('click', function(e){
e.preventDefault();
$("#sidebar").animate({opacity: "hide", left: 250}, "slow");
$(this).toggleClass("btn-slide").toggleClass("active");
});
$(".active").live('click', function(e){
e.preventDefault();
$("#sidebar").animate({opacity: "hide", left: -250}, "slow");
$(this).toggleClass("btn-slide").toggleClass("active");
});
The other option would be to have set the click event on a different modifier (eg. on the id, maybe).
<span>News <img src="img/overlay.png" id="sliderButton" class="btn-slide" alt="" /></span>
then use this to handle the click
$("#sliderButton").click(function(e){
e.preventDefault();
$(this).is('.btn-slide').each(function() {
$("#sidebar").animate({opacity: "show", left: 250}, "slow");
});
$(this).is('.active').each(function() {
$("#sidebar").animate({opacity: "hide", left: -250}, "slow");
});
$(this).toggleClass("active").toggleClass('btn-slide');
});
or even more concise
$("#sliderButton").click(function(e){
e.preventDefault();
var animationSettings = {opacity: "show", left: 250};
if ($(this).hasClass('active') )
{
animationSettings = {opacity: "hide", left: -250};
}
$("#sidebar").animate(animationSettings , "slow");
$(this).toggleClass("active").toggleClass('btn-slide');
});
The final option that I can think of would be to set the click events after you change them, but I wouldn't do that so I'm not going to supply a sample.
Lastly, I would put in alert into your active callback and make sure that your active button event is actually firing.
The way your logic is written, I think you need to do a 'toggleClass' on both classes inside your click handlers which will add one and remove the other. For example, when your "active" item is clicked you toggle (add) the btn-slide class, but this will leave the "active" class in place too.
Of course instead of using "toggleClass" you could also use "addClass" and "removeClass" to be more explicit.
I recommend using a tool like Firebug to watch what's happening inside your DOM.
$(document).ready(function(){
$(".btn-slide").click(function(){
$("#sidebar").animate({opacity: "show", left: "250"}, "slow");
$(this).toggleClass("active"); // add class
$(this).toggleClass("btn-slide"); // remove class
return false;
});
});
$(document).ready(function(){
$(".active").click(function(){
$("#sidebar").animate({opacity: "hide", right: "250"}, "slow");
$(this).toggleClass("active"); // remove class
$(this).toggleClass("btn-slide"); // add class
return false;
});
});
This works.
$(document).ready(function(){
$(".btn-slide").click(function(){
$("#sidebar").slideToggle("slow");
$(this).toggleClass("active"); return false;
});
});
$(function() {
var ecswitch = 1;
/* prevent the annoying scroll back up thing */
$("#ec").click(function(e) {
e.preventDefault();
var x = $("#main").width(); // get element width
var y = $("#main").height(); // get element height
if (ecswitch == 1) {
$("#main").animate({
opacity: 0,
hieght: "0",
width: "0"
}, 1300);
ecswitch = 0;
} else {
$("#main").animate({
opacity: 1,
hieght: y,
width: x
}, 1300);
ecswitch = 1;
}
});
});
#main {
height: 200px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="content">
Expand / Contract
<div id="main">
Watch Me Shrink Or Grow
</div>
</div>
I chose to do this a little differently. this initializes with the height of our experiment being 200px and the width is automatic. When you click the hyperlink the experiment is hidden in 1.3 seconds and a switch is set to 0. when you click again it comes back over a period of 1.3 seconds and the switch gets set back to 1. like a light switch. I used the animate here because a simple fade or hide got me bored...
The reason why I got the widths and heights of the element before zero-ing them was if said width:100%" and height: "100%" in my animate it would set it to 100% of the page's width and height...we don't want that.
NOTE: I am also using the opacity over a time period. quite nice for fading as well :)

Categories

Resources