I wanted to create side tab slide outs for two subdivisions of our company on the new version of the website I'm working on. After a lot of research, I decided to make it relatively simple (or so I thought).
I created a div (#CMTabWrap, 245px) that wrapped around two other divs: #CMContent (200px) and #BNOCM_tab (45px). I set the margin for #CMTabWrap to -200px (the width of #CMContent), leaving only the tab showing. The HTML and CSS are working fine.
Beneath the divs in my HTML, I put the code below. On click, it should test the class of the object and move it in or out (as appropriate) by the width of the content, either making the whole kit and kaboodle visible or reducing it to just the tab.
I want to say that I ran the code through JSLint, and read several questions here along the same lines. I applied some of the fixes, but still nothing is happening. I have a feeling it's something obvious -- I'm not quite intermediate with JS and slightly more than a noob. Any help appreciated.
<script type="text/javascript">
/*global $, jQuery, alert*/
$(function(){
$("#BNOCM_tab").click(function () {
$('#BNOCM_tab').addClass('in');
var contentWidth = $('#CMContent').width();
if ($(this).is('.out')) {
$(this).removeClass('out').addClass('in');
$("#CMTabWrap").animate(
{"left": '+=' + contentWidth},
"slow"
);
}
if ($(this).is('.in')) {
$(this).removeClass('in').addClass('out');
$("#CMTabWrap").animate(
{"right": '-=' + contentWidth},
"slow"
);
});
});
</script>
Inside your click-function this refers to the clicked element, so $(this) and $("#BNOCM_tab") is always the same. Also your second if should be an else, because now you just swap the classes from "in" to out as #wwwmarty pointed to. So yours (inside $(document).ready) could look like this:
<div id="BNOCM_tab" class="out"></div> // add class 'out to the tab
var $Wrap = $("#CMTabWrap"), // create a jQuery object only once, store it
$Tab = $("#BNOCM_tab");
$Tab.click(function () {
var contentWidth = $('#CMContent').width();
// use .hasClass() for class check, note there's no dot in the name
if ($Tab.hasClass('out')) {
$Tab.removeClass('out').addClass('in');
$Wrap.animate({left: '+=' + contentWidth}, "slow");
} else {
$Tab.removeClass('in').addClass('out');
$Wrap.animate({left: '-=' + contentWidth}, "slow");
};
});
If that won't work, add the relevant part of your html to your question or/and make a fiddle and post what exactly went wrong.
Related
I'm trying to create an element in a Wordpress site where a piece of content begins partway down the screen, and sticks to the top of the screen when the user scrolls down.
I've tried various things, and none of them have worked. The most recent attempt uses Javascript to give and take away a class to the content I'm trying to move/fix.
The code is
jQuery( document ).ready(function($) {
alert( "test1!" );
var wrap = $("#wrap");
wrap.on("scroll", function(e) {
if (this.scrollTop > 147) {
wrap.addClass("fix-search");
alert("test2");
} else {
wrap.removeClass("fix-search");
}
});
});
The file is enqueuing properly since the first test alert ("test1" fires, but "test2" doesn't fire as I scroll down the screen. I've had that same piece of code working in a modified version of the original code on codepen (http://codepen.io/anon/pen/NqKKVN) so I can only assume this is something weird with Wordpress interacting with Javascript.
So yeah, anyone know a way to either do that I'm wanting to do in a way that will work with wordpress, or to get the above piece of code working properly?
EDIT: This has been solved. For the reference of anyone else with the same problem the piece of code that eventually worked was
jQuery( document ).ready(function($) {
var scrollTop = $(window).scrollTop();
function scrollUpdate() {
var scrollTop = $(window).scrollTop();
var wrap = $("#menu-all-pages");
if (scrollTop > 147) {
wrap.addClass("fix-search");
console.log("Menu at top");
} else {
wrap.removeClass("fix-search");
console.log("Menu at set point");
}
console.log(scrollTop);
}
window.onscroll = scrollUpdate;
});
I have implemented a similar solution in my blog a few years ago. I got it working by scripting this way:
Add a variable scrollTop which would contain the value in pixels
scrolled from the window top.
var scrollTop = $(window).scrollTop();
See, I use jquery function scrollTop applied to the selected object "window". It would return the value scrolled from the very top of the browser. It does work on Wordpress, I have tried it on my blog.
Put this code in a function scrollUpdate. We'll call it later to update
the scroll value from top
function scrollUpdate() {
var scrollTop = $(window).scrollTop();
}
The function should also contain all the logic checking the scrollTop value and thus applying styles and etc.
Let's make this function be called on every scroll.
window.onscroll = scrollUpdate;
Try it yourself!
P.S. I got a weird feeling, but you should better use hide / show instead of adding a whole css class to the page.
What I am trying to do is have four links that each will display and hide a certain div when clicked. I am using slideToggle and I was able to get it to work with really sloppy and repetitive code. A friend of mine gave me a script he used and I tried it out and finally was able to get something to happen. However, all it does is hide the div and wont redisplay. Also it hides all the divs instead of just the specific one. Here is a jsfiddle I made. Hopefully you guys can understand what I am trying to do and help! Thanks alot.
Here is the script I'm using.
$(document).ready(function () {
$(".click_me").on('click', function () {
var $faq = $(this).next(".hide_div");
$faq.slideToggle();
$(".hide_div").not($faq).slideUp();
});
});
http://jsfiddle.net/uo15brz1/
Here's a link to a fiddle. http://jsfiddle.net/uo15brz1/7/
I changed your markup a little, adding id attributes to your divs. The jquery, gets the name attribute from the link that's clicked, adds a # to the front, hides the visible div, then toggles the respective div. I also added e.preventDefault to stop the browser from navigating due to the hash change. As an aside, javascript don't require the $ prefix.
$(document).ready(function () {
$(".click_me").on('click', function (e) {
e.preventDefault();
var name = $(this).attr('name');
var target = $("#" + name);
if(target.is(':visible')){
return false; //ignore the click if div is visible
}
target.insertBefore('.hide_div:eq(0)'); //put this item above other .hide_div elments, makes the animation prettier imo
$('.hide_div').slideUp(); //hide all divs on link click
target.slideDown(); // show the clicked one
});
});
Welcome to Stack Overflow!
Here's a fiddle:
http://jsfiddle.net/uo15brz1/2/
Basically, you need a way to point to the relevant content <div> based on the link that's clicked. It would be tricky to do that in a robust way with your current markup, so I've edited it. The examples in the jquery documentation are pretty good. Spend some time studying them, they are a great way to start out.
I'm building a website which relies on jQuery effects and I have a problem with the jQuery Slide effect.
I'm using that through a toggle function for the moment, but that will change in a later stage.
The fact is that I'm hinding an element when a certain action is executed. When you use the function slide the content beneath those elements moves when the animation is completed to take up the free space which was created with the effect.
The problem is that the content is only moved as soon as the animation is completed. Is there any way to move the content when the animation is still running. With other words, I want to move the content together with the animation, but I don't want to call the slide function on my element that should move with it.
I've created a JSFiddle to demonstrate the problem: http://jsfiddle.net/6Lg9vL8m/6/
Edit: Question update and fiddle
Here's an update to the question, and please see my original updated fiddle.
When you execute the slide effect in jQuery UI, see the bottom example on my fiddle, the box is moved up, and is somewhere placed behind an invisible screen (tough to explain).
With the animate function, see the top example in my fiddle, the area is shrinked, and that's something which I want to avoid. I want to achieve the effect such as 'Slide' does, but the content under the box must move up immediately with the animation, and not after the animation has been completed.
Edit: Reworked the correct answer in a plugin.
Thanks to the answers I've received here, I found the correct code, modified a bit, and created a plugin from it which I'll place here.
The plugin is called 'Curtain' and can be described as rising the requested element as a curtain and thus move it out of the way.
Here's the source code:
(function($) {
$.fn.curtain = function(options, callback) {
var settings = $.extend( {}, $.fn.curtain.defaults, options);
var tabContentsHeight = $(this).height();
$(this).animate({height:0}, settings.duration);
$(this).children().animate({'margin-top':'-' + tabContentsHeight + 'px'}, settings.duration, function() {
$(this).css({"margin-top":0});
if ($.isFunction(callback)) {
callback(this);
}
});
return this; // Allows chaining.
};
$.fn.curtain.defaults = {
duration: 250
};
}(jQuery));
The plugin can be called like this:
element.curtain({ duration: 250 }, function() {
// Callback function goes here.
});
If someone has remarks or a better way to solve this problem, please share it in the comments.
You can do it by using the animate function like this:
$('#square').on('mousedown', function(e) {
$(this).animate({height:-200},2500);
});
Demo
Updated code to create a "curtain raising" like animation:-
$('#square').on('mousedown', function(e) {
$(this).animate({height:-200},2500);
$(this).children().animate({"margin-top":"-400px"},2500, function() {
$(this).css({"margin-top":0})
});
});
CSS:
`#square{
overflow:hidden;
}`
Demo 2
This is the effect you wanted?
$('#square').on('click', function(e) {
$(this).animate({height :0},2500 );
});
I have a problem with a vertical scroll page where I'm using (intending to, that is) two nested quickscroll functions.
This is how it's supposed to look: - just remove the scrollbar in your mind. I'm just using
overflow:scroll
here to manually check on things.
Since JS isn't my forte (I have only very basic knowledge of it), I just got a piece of code that worked similarly, reverse engineered it by removing as much as I could from the HTML and CSS until I was left with the bare function, and plugged it into my own page in terms of the needed HTML and CSS as well as the code. I'm not using anything proprietary and I'm including author links, hoping that I'm on the safe side there (?)
So, the main scroll is a vertical one and inside one of the vertical sections I'm using this 'reverse engineered' horizontal quickscroll code.
The new (nested) script cancels out the main one. Any ideas how to fix this?
The main (vertical scroll) is the following:
<script>
$(document).ready(function() {
$('a.panel').click(function () {
$('a.panel').removeClass('selected');
$(this).addClass('selected');
/* I added this to hide the menu during scroll and I'm mighty proud of myself! :) */
$('.menu').addClass('hide');
$('.book_arrow').addClass('hide');
current = $(this);
$('body').scrollTo($(this).attr('href'), 2600, function(){
$('.menu').removeClass('hide');
$('.book_arrow').removeClass('hide');
});
return false;
});
});
</script>
It comes with these two linked files:
<script type="text/javascript" src="js/jquery-1.3.1.min.js"></script>
<script type="text/javascript" src="js/jquery.scrollTo.js"></script>
The conflicting code is a bit longer:
<script>
// initialize scrollable and return the programming API
var api = $("#scroll").scrollable({
items: '#tools'
// use the navigator plugin
}).navigator().data("scrollable");
// this callback does the special handling of our "intro page"
api.onBeforeSeek(function(e, i) {
// when on the first item: hide the intro
if (i) {
$("#intro").fadeOut("slow");
// dirty hack for IE7-. cannot explain
if ($.browser.msie && $.browser.version < 8) {
$("#intro").hide();
}
// otherwise show the intro
} else {
$("#intro").fadeIn(1000);
}
// toggle activity for the intro thumbnail
$("#t0").toggleClass("active", i == 0);
});
// a dedicated click event for the intro thumbnail
$("#t0").click(function() {
// seek to the beginning (the hidden first item)
$("#scroll").scrollable().begin();
});
</script>
...and it links to this file:
<script src="http://cdn.jquerytools.org/1.2.7/full/jquery.tools.min.js"></script>
Does it matter where in the HTML I place all these chunks? In isolation, both scripts are working.
I've read about a seemingly similar case here and I'm thinking that maybe in my case I'm also dealing with variables that are 'occupied' by one of the functions, but I'm not exactly sure what to change and where.
I'm absolutely positively looking forward to learning a major lesson from this problem! :)
Hoping that it doesn't cause the Stack to Overflow, I'll add some more (my solution) to my journey. Maybe it helps posterity to follow my learning curve...
I was able to get the nested quick scroll (as I call it) to work properly. Still a rookie in JS, I played around with that bit of script I had gotten and modified - the one that worked vertically - and stuffed the other, similar, script for the (inner) horizontal scroll into that first script! YAY! It worked. Here's how the final script looks:
<script>
$(document).ready(function() {
$('a.panel').click(function () {
$('.book_arrow').fadeOut();
## which prevents the vertical page flying past a lot of nav during scroll down ##
$('.fluid_centerbox').addClass('hide');
$('.fluid_centerbox').fadeOut();
## which makes the scroll smooth cause what's {display:none;} isn't going to be recalculated
and also lets the viewer appreciate the background images during scroll. the 'hide' is
instant and the .fadeOut is animated. Don't ask me why it worked best in this order! ##
current = $(this);
$('body').scrollTo($(this).attr('href'), 2600, function(){
$('.book_arrow').fadeIn();
$('.fluid_centerbox').fadeIn(), 40000;
});
return false;
});
$('a.panell').click(function () {
current = $(this);
$('.long_wrap').scrollTo($(this).attr('href'), 2600, function(){
});
return false;
});
## the panell is not a typo but a way to distinguish both scroll button types ##
});
</script>
And while I'm posting this, I see that in the inner quick scroll, there's an empty
function(){});
Maybe later I'll try to get rid of it, if possible.
I have a menu composed of three options.
Clicking on one causes a container div to "FadeInDown".
Then, its contents "FadeIn".
Clicking on another menu item or anywhere else on the page causes the
contents to "FadeOut" then container div to "FadeOutUp".
Here is the fiddle that I have been testing jsfiddle
$(document).ready(function() {
$('.container').each(function() {
animationHover(this,'.fadeInDown');
});
});
I'm not very familiar with jQuery and have been trying to use animate-css to get me along. Thanks for any help and tips in advance and welcome coding criticism :)
My answer is mainly based on JQuery and its animate function (http://api.jquery.com/animate/) . Here is the fiddle :
http://jsfiddle.net/awmat/7/
I use JavaScript objects like fadeInDown to animate the container.
var fadeInDown = {
opacity:1,
top: "50px"
};
And i use the complete callback function of animate to make the content appear after the container.
To manage several div (one for each menu item), I use id as selectors, but since the "click and display" function remains the same, I used a "builder" : (this uses a closure, so if you're not familiar with JavaScript, you may have to read several times to understand what is going on)
var menuClickCallbackBuilder = function(menuItem){
var container = $('#container' + menuItem);
var content = container.find('.content');
var showContent = function(){
content.animate({opacity:1},{duration:1000});
};
return function() {
var activeContainer = $('.active');
var hideContainer = function(){
activeContainer.animate(fadeOutUp,1000);
};
activeContainer.find('.content').animate({opacity:0},{duration: 1000, complete : hideContainer});
activeContainer.removeClass("active");
if(activeContainer[0] != container[0])
{
var timeout = activeContainer[0] ? 2000 : 0 ;
setTimeout(function(){
container.animate(fadeInDown,{duration : 1000, complete :showContent});
},timeout);
container.addClass("active");
}
}
};
This way, when you add the add the click callbacks, you can just do :
$(document).ready(function(){
// note that menuClickCallbackBuilder(1) returns a function
// again if you're not familiar with JS, you may have to re-read menuClickCallbackBuilder
$('#menuLink1').on('click', menuClickCallbackBuilder(1));
$('#menuLink2').on('click', menuClickCallbackBuilder(2));
$('#menuLink3').on('click', menuClickCallbackBuilder(3));
});
Some improvements you can bring to this :
Factor the durations into a variable (e.g animationDurationInSeconds) so that if you want to change the speed of the animation, you only have 1 thing to change. (#Huangism: and right after you did that, make animation faster so that it gets more dynamic)
(From #Huangism) : stop it from going crazy when people cicks on the menu 10 times really fast
Actually, I think you don't need 3 different containers, you could do it with just one container (though I don't know if it would be considered an improvement)
There is probably a way to use CSS classes instead of fadeInDown and fadeOutUp JS objects. That would be cleaner, I think you should keep styles in CSS as much as you can.
There is no need for different IDs for menu items, you could do the exact same thing with a loop.
Whatever your imagination wants to add