I have a website with different sections. I have jQuery to slide between these sections.
But now I have a link in a section which points to another section.
HTML:
<div class="section" id="one">
<div class="row">
<p>This is some text</p>
</div>
<div class="row">
<img src="button"/>
</div>
</div>
<div class="section" id="tow">
<div class="row">
<p>This is some text</p>
</div>
<div class="row">
<img src="button"/>
</div>
</div>
<div class="section" id="ordernow">
<div class="row">
<p>This is some text</p>
</div>
<div class="row">
<img src="button"/>
</div>
</div>
<div class="section" id="four">
<div class="row">
<p>This is some text</p>
</div>
<div class="row">
<img src="button"/>
</div>
</div>
jQuery:
// onclick on an object with class "section" scroll to this object
$('div.section').click(function() {
$.scrollTo($(this), 800);
});
function scrollOrderNow(){
$('html,body').animate({
scrollTop: $("#ordernow").offset().top
}, 1000);
}
The problem is that if I click on the link scrollOrderNow() the page slides to the order page and than back to the section because the link is in that section.
Could you please help me figure this out?
Thank You!
You can use a single click handler and determine what to do based on which element was clicked inside the section. For this, it's best to distinguish the clickable element by giving it a class:
<div class="section" id="four">
<div class="row">
<p>This is some text</p>
</div>
<div class="row">
<img src="button" class="scroll-to-order"/>
</div>
</div>
The the click handler code:
$('div.section').on('click', function(evt) {
var $target = $(evt.target);
if ($target.is('.scroll-to-order')) {
// the image itself was clicked, so scroll to ordernow
$('html,body').animate({
scrollTop: $("#ordernow").offset().top
}, 1000);
} else {
// something else inside the section was clicked, scroll to section
$.scrollTo($(this), 800);
}
});
You'll need to put return false to your scrollOrderNow() function.
function scrollOrderNow(){
$('html,body').animate({
scrollTop: $("#ordernow").offset().top
}, 1000);
return false;
}
This way, your links will not react and the hash will not be appended to the URL, leaving the page where it is.
Related
I am using this accordion script for an FAQ page: http://www.snyderplace.com/demos/accordion.html
It's great except for one problem which is especially evident on mobile devices. When you click on a question and it has a lot of content inside, it expands upwards off the screen, to where you have to scroll up to see the question and the beginning of the content.
Ideally I'd like to have it to where the script scrolls the question to the top of the page/viewport when you click on it. If anyone has an idea of what to tweak in the script that would be amazing!
You may try something like this. You don't need a plugin for an accordion:
Edited version with icons, default open, and touch enabled scroll to top
https://jsfiddle.net/07fdq3t1/10/
Add the class show to the one you want to open.
This could probably be written more efficiently as there's repeating code, but it should work.
jQuery
$(document).ready(function() {
$('.accordion').click(function(){
if($(this).next('.container').is(':visible')) {
$(this).removeClass('show');
$(this).next('.container').slideUp();
}
else {
$('.accordion').find('.container:visible').slideUp();
$('.accordion').removeClass('show');
$(this).addClass('show');
$(this).next('.container').slideDown();
}
});
$('.accordion').on( "touchstart", function(){
if($(this).next('.container').is(':visible')) {
$(this).removeClass('show');
$(this).next('.container').slideUp();
}
else {
$('.accordion').find('.container:visible').slideUp();
$('.accordion').removeClass('show');
$(this).addClass('show');
$(this).next('.container').slideDown();
$('html, body').animate({
scrollTop: $(this).offset().top
}, 200);
}
});
});
HTML
<div class="accordion">Heading<span></span></div>
<div class="container">
<div class="content">
<div>Sample Content</div>
<p>Content here....</p>
</div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
<div class="content">
<div>Sample Content</div>
<p>Content here....</p>
</div>
</div>
<div class="accordion show">Heading<span></span></div>
<div class="container">
<div class="content">
<div>Sample Content</div>
<p>Content here....</p>
</div>
</div>
<div class="accordion">Heading<span></span></div>
<div class="container">
<div class="content">
<div>Sample Content</div>
<p>Content here....</p>
</div>
</div>
Note you will need to include jQuery in your code.
I'm trying to write JQuery for a set of animated info boxes. Clicking on the title div.info-box__title should open the adjacent div.info-box__content and at the same time close any other open div.info-box__content
Update - should have specified, I also need ALL boxes to close when user clicks outside any .info-box.
Update 2 - Fiddle here: https://jsfiddle.net/q9orfsoy/
The markup is like this:
<section id="info-box-3" class="info-box">
<div class="centerer">
<div class="info-box__close"></div>
<div class="info-box__title">
<h1>Title</h1>
</div>
<div class="info-box__content">
<p>content</p>
</div>
</div>
</section>
I always struggle with execution order issues with JS. What I have so far are two functions:
Opening:
$('.info-box__title').bind("click touchstart", function() {
// close the others and open this one
if($(this).next('.info-box__content').css('display') == 'none') {
$(this).next('.info-box__content').slideDown();
$(this).parents('.info-box').addClass('open');
$(this).parents('.info-box.open').siblings().children('.info-box__title').hide();
}
});
Closing:
// hide all when click anywhere else in the document
$(document).bind("click touchstart", function(event) {
// exclude the one that's currently open
if(!$(event.target).closest('.info-box.open').length){
$('.info-box__content').slideUp(function(){
$(this).parents('.info-box').removeClass('open');
});
}
});
What this code does is closes all the info-box__content divs when you click outside them. But if you click on another info-box__title it just opens that as well without closing the rest.
(Initially I thought adding a class of .open to the one that's opened would be enough, but I guess I've run into execution order issues?)
What's the best/recommended way to deal with something like this?
Try utilizing .index() , jsfiddle https://jsfiddle.net/q9orfsoy/1/
var titles = $(".info-box__title");
var content = $(".info-box__content");
titles.on("click touchstart", function(e) {
if ($(this).next(".info-box__content")
.is(":visible")) {
$(this).next(".info-box__content")
.slideUp()
} else {
content.slideUp()
.eq($(this).index(".info-box__title"))
.slideDown()
}
});
// ALL boxes to close when user clicks outside any `.info-box`
$(document).on("click touchstart", function(e) {
if ($(e.target).is(".info-box, .info-box *")) {
return
}
else {
content.slideUp()
}
})
.info-box__content {
display: none;
}
.info-box {
border: 1px solid black;
padding; 20px;
margin:20px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<section id="info-box-1" class="info-box">
<div class="centerer">
<div class="info-box__close"></div>
<div class="info-box__title">
<h1>Title 1</h1>
</div>
<div class="info-box__content">
<p>content</p>
</div>
</div>
</section>
<section id="info-box-2" class="info-box">
<div class="centerer">
<div class="info-box__close"></div>
<div class="info-box__title">
<h1>Title 2</h1>
</div>
<div class="info-box__content">
<p>content</p>
</div>
</div>
</section>
<section id="info-box-3" class="info-box">
<div class="centerer">
<div class="info-box__close"></div>
<div class="info-box__title">
<h1>Title 3</h1>
</div>
<div class="info-box__content">
<p>content</p>
</div>
</div>
</section>
Close all then open the one you want with the this object.
$('.info-box__title').click(function() {
$('.info-box__content').hide(); //or perform closing action
$(this).siblings('.info-box__content').show(); //or perform opening action
});
To close when clicking outside of any info box,
$('body').not('.info-box').click(function() {
$('.info-box__content').hide(); //or perform closing action
});
Here is a solution.
$('.info-box__title').click(function() {
var sibling = $(this).siblings('.info-box__content');
if(!sibling.is(':visible')){
$('.info-box__content:visible').slideUp();
sibling.slideDown(); }
else sibling.slideUp();
});
$(document).bind("click touchstart", function(e)
{
var open_content = $(".info-box__content:visible");
if (!open_content.parent().is(e.target)
&& open_content.parent().has(e.target).length === 0)
{
open_content.slideUp();
}
});
.info-box__title{background:grey;}
.info-box__content{
height:100px;
display:none;
background:red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<section id="info-box-3" class="info-box">
<div class="centerer">
<div class="info-box__close"></div>
<div class="info-box__title">
<h1>Title</h1>
</div>
<div class="info-box__content">
<p>content</p>
</div>
</div>
</section>
<section id="info-box-4" class="info-box">
<div class="centerer">
<div class="info-box__close"></div>
<div class="info-box__title">
<h1>Title</h1>
</div>
<div class="info-box__content">
<p>content</p>
</div>
</div>
</section>
<section id="info-box-5" class="info-box">
<div class="centerer">
<div class="info-box__close"></div>
<div class="info-box__title">
<h1>Title</h1>
</div>
<div class="info-box__content">
<p>content</p>
</div>
</div>
</section>
You could do:
$(document).bind("click touchstart", function(event) {
var $openBox = $(event.target).closest('.open');
$('.info-box__content').not($openBox).slideUp(function(){
$(this).parents('.info-box').removeClass('open');
});
});
This will select all boxes other than the one related to the click event.
Bonus explanation
The reason your current solution doesn't work is that your just checking to see if the open box exists, since it does, it then closes all elements with the class `.info-box__content'. Hope that makes sense!
Easily slideUp all class while using stop() to slideDown() or slideToggle() target section:
$('.info-box__title').click(function() {
$('.info-box__content').stop().slideUp();
$(this).find('.info-box__content').stop().slideDown();
});
$('body').not('.info-box').click(function() {
$('.info-box__content').stop().slideUp();
});
I have a series of "product" divs in a grid, each of which is clickable. When one is clicked, the corresponding "product info" DIV slides down to reveal the corresponding product info. I have it working somewhat but I'm having a couple of issues.
How can I make it so that when one set of info is showing, but ANOTHER "product" div is clicked, the current info slides into hidden status, the product info is switched and THEN the new info is revealed. Make sense?
If the code below doesn't make sense, the direct link is here
This is the HTML for the hidden info. The class 'selected_show' is styled with "display:none;" to start:
<section>
<div class=selected_show>
<div>
<div class="product_info grassone piece_info">
<img src="./images/detail_info/astronomical.jpg">
<div>
<p>Short description of the piece...</p>
</div>
</div>
</div>
<div>
<div class="product_info competitive piece_info">
<img src="./images/detail_info/astronomical.jpg">
<div style="background:red;">
<p>Short description of the piece...</p>
</div>
</div>
</div>
<div>
<div class="product_info magpie piece_info">
<img src="./images/detail_info/astronomical.jpg">
<div style="background:blue;">
<p>Short description of the piece...</p>
</div>
</div>
</div>
</div>
</section>
This is where the info is chosen:
<section>
<div class="piece woodcut">
<p>GRASSONE</p>
</div>
<div class="piece woodcut">
<p>COMPETITIVE</p>
</div>
<div class="piece woodcut">
<p>MAGPIE</p>
</div>
</section>
This is the script for the effect:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
<script type="text/javascript">
$('a.showinfo').click(function(e){
e.preventDefault();
$("html, body").animate({ scrollTop: 100 }, "slow");
$(".selected_show").slideToggle();
var a_href = '.'+ $(this).attr('href');
$('.product_info').hide();
$(a_href).show();
});
</script>
Ideas?
Use the slideToggle's callback:
$(".selected_show").slideToggle(1000, function(){
$('.product_info').hide();
});
<div id="wrapper">
<div class="accordionButton">Personal Information</div>
<div class="accordionContent">
Personal text
</div>
<div class="accordionButton">Experience</div>
<div class="accordionContent">
Experience information
</div>
<div class="accordionButton">Training</div>
<div class="accordionContent">
No skills
<div class="accordionButton">Career</div>
<div class="accordionContent">
Never had a job
</div>
<div class="accordionButton">Referers</div>
<div class="accordionContent">
None.
</div>
</div>
This code works how i want it to. It is a horizontal accordion. However, when it is loaded on my webpage, they content divs have to be hidden for my jquery to work.
Jquery:
$(document).ready(function() {
// When div is clicked, hidden content divs will slide out
$('div.accordionButton').click(function() {
$('div.accordionContent').slideUp('normal');
$(this).next().slideDown('normal');
});
// Close all divs on load page
$("div.accordionContent").hide();
});
If i don't hide the divs, all the divs display. Is there any way to display the 1st page without changing too much of my jquery or would i have to set different class names for the button and the content so that when a specified button is clicked, the affiliated content will slide out for that button div?
You can use jquery selector for first div and set it as show(). Something like :
$('div.accordionContent:first').show();
I think you have to try this:-
<script type="text/javascript">
$.fn.accordion = function(settings) {
accordion = $(this);
}
$(document).ready(function($) {
$('div.accordionContent').click(function() {
if($(this).next().is(":visible")) {
$(this).next().slideDown();
}
$('div.accordionContent').filter(':visible').slideUp();
$(this).next().slideDown();
return false;
});
});
</script>
Why not use slideToggle() instead of IF statements....
Try this very simple solution
HTML
<div class="accordion-container">
<div class="accordion-content">
<div class="accordion-title">Title</div>
<div class="accordion-toggle">Toggle content</div>
</div>
<div class="accordion-content">
<div class="accordion-title">Title</div>
<div class="accordion-toggle">Toggle content</div>
</div>
<div class="accordion-content">
<div class="accordion-title">Title</div>
<div class="accordion-toggle">Toggle content</div>
</div>
</div>
jQuery
$('.accordion-content .accordion-title').on('click', function(){
$(this).toggleClass('active');
$('.accordion-title').not($(this)).removeClass('active');
$(this).next().slideToggle();
$(".accordion-toggle").not($(this).next()).slideUp();
});
Ive made a fiddle of my problem here.
http://jsfiddle.net/E9cUS/1/
JavaScript:
$('.top').click(function () {
var thisPage = $(this).closest('.yesNoItem');
$('.yesNoTick').stop().animate({"opacity" : 1},400, function () {
thisPage.find('.no .top').stop().animate({"opacity" : 0},400, function () {
$(this).css("display", "none");
});
});
});
$('.yesNoNext').click(function () {
$(this).closest('.yesNoItem').stop().animate({"opacity" : 0},400, function () {
//This isnt working? Please advise?
$(this).next('.yesNoItem').stop().animate({"opacity" : 1},400);
});
});
HTML:
<div id="stage">
<div class="yesNoOuter">
<div class="yesNoItem" style="opacity:1;">
<div class="yesNoContainer yes">
<div class="top">
<div class="yesNoTick"></div>
</div>
<div class="bottom">
</div>
</div>
<div class="yesNoContainer no">
<div class="top">
<div class="yesNoTick"></div>
</div>
<div class="bottom">
<p>Text 1</p>
<div class="yesNoNext">More</span>
</div>
</div>
</div>
<div class="yesNoItem">
<div class="yesNoContainer yes">
<div class="top">
<div class="yesNoTick"></div>
</div>
<div class="bottom">
</div>
</div>
<div class="yesNoContainer no">
<div class="top">
<div class="yesNoTick"></div>
</div>
<div class="bottom">
<p>Text 2</p>
<div class="yesNoNext">More</span>
</div>
</div>
</div>
</div>
</div>
I've also put the line of code thats not working.
Bascially it is hiding the element that I want, but not fading the next one in...
Can any one advise based upon my code? Many thanks!
You had an error in your markup
<div class="yesNoNext">More</span>
if you correct that, next() works http://jsfiddle.net/E9cUS/2/
I think your HTML got messed up. The second .yesNoItem element is not a sibling but a child of the first .yesNoItem element (right click -> inspect element).
Probably because of <div class="yesNoNext">More</span> (opening div, closing span). The browser will attempt to correct this automatically and just ignore the closing span tag (at least this seems to be the case if you inspect the DOM).
If you correct your HTML it should work (at least it should select the right element).
If they are actually supposed to be nested, then .next() is the wrong method anyways.