Adding and removing classes depending on other elements - javascript

So I have carousel with slides (works on fullPage.js):
<div id="myContainer">
<div class="section" data-anchor="skynet">
<div class="slide one" data-anchor="main">
Slide 1
</div>
<div class="slide two" data-anchor="about_us">
Slide 2
</div>
<div class="slide three" data-anchor="faq">
Slide 3
</div>
<div class="slide four" data-anchor="news">
Slide 4
</div>
</div>
</div>
And I have some blocks with backgrounds
<div class="bg-main" id="bgOne"></div>
<div class="bg-main" id="bgTwo"></div>
<div class="bg-main" id="bgThree"></div>
<div class="bg-main" id="bgFour"></div>
Slides swaps by adding class active to blocks with class .one, .two etc.
I try to add class to blocks with background depend on active slide. For example - if .slide.two has class .active, add class to block #bgTwo.
Here my current JS. It doesn't work:
<script type="text/javascript">
$(document).ready(function(){
if ( $('#myContainer .one').hasClass('active') ) {
$('.bg-main').removeClass('active');
$('#bgOne').addClass('active');
} else if ( $('#myContainer .two').hasClass('active') )
{
$('.bg-main').removeClass('active');
$('#bgTwo').addClass('active');
}
});
</script>

Use the callback onSlideLeave
Demo
$(document).ready(function() {
$('#fullPage').fullpage({
onSlideLeave: function(link, secIdx, sldIdx, dir, next) {
$('.test .bg-main').removeClass('active');
$('.test .bg-main').eq(next).addClass('active');
}
});
});
.slide {
text-align: center
}
.test {
position: fixed;
top: 75%;
right:calc(50% - 220px);
}
.bg-main {
height: 30px;
width: 100px;
background: grey;
display:inline-block;
text-align:center;
outline:1px solid #fff;
margin:0;
}
.one,
#bgOne.active {
background: #fc0;
}
.two,
#bgTwo.active {
background: #f00;
}
.three,
#bgThree.active {
background: #0f0;
}
.four,
#bgFour.active {
background: #00f;
}
<link href='https://cdn.jsdelivr.net/jquery.fullpage/2.9.4/jquery.fullpage.min.css' rel='stylesheet'>
<div id="fullPage">
<div class="section" data-anchor="skynet">
<div class="slide one" data-anchor="main">
Slide 1
</div>
<div class="slide two" data-anchor="about_us">
Slide 2
</div>
<div class="slide three" data-anchor="faq">
Slide 3
</div>
<div class="slide four" data-anchor="news">
Slide 4
</div>
</div>
</div>
<div class='test'>
<div class="bg-main active" id="bgOne">1</div>
<div class="bg-main" id="bgTwo">2</div>
<div class="bg-main" id="bgThree">3</div>
<div class="bg-main" id="bgFour">4</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src='https://cdn.jsdelivr.net/jquery.fullpage/2.9.4/jquery.fullpage.min.js'></script>

So i found out that fullpage.js use event afterSlideLoad. So thats my solution:
<script type="text/javascript">
$(document).ready(function() {
$('#myContainer').fullpage({
anchors: ['skynet'],
menu: '#menu',
scrollingSpeed: 500,
normalScrollElements: '.modal',
scrollOverflow: true,
afterSlideLoad: function( anchorLink, index, slideAnchor, slideIndex){
var loadedSlide = $(this);
if(slideIndex == 0){
$('.bg-main').removeClass('active');
$('#bgOne').addClass('active');}
if(slideIndex == 1){
$('.bg-main').removeClass('active');
$('#bgTwo').addClass('active');}
if(slideIndex == 2){
$('.bg-main').removeClass('active');
$('#bgThree').addClass('active');}
if(slideIndex == 3){
$('.bg-main').removeClass('active');
$('#bgFour').addClass('active');}
}
})
});
</script>
Class is added only after the slide is changed, and not during the process itself. The background does not change as fast as I'd like, but this is the best thing I could achieve.

The perfect solution is to extend the fullpage.js to handle the feature.
This is a workaround:
<script type="text/javascript">
var updateClasses = function(){
var activeClass = 'active';
var eq = $('#myContainer').children(activeClass).eq();
var bgMain = $('.bg-main').removeClass(activeClass);
bgMain.eq(eq).addClass(activeClass);
};
$(document).ready(function(){
$(".fp-controlArrow").on("click.updateClasses", function(){
updateClasses();
});
});
</script>

Related

jQuery - progressivly showing div

I would like to show some divs, one by one, with a sliding effect from the left or right part of the screen. So far i'm stuck between this
<button id='animer'>animer</button>
<div class="left">from left</div>
<div class="right">from right</div>
<div class="left">from left</div>
<div class="right">from right</div>
<script>
$(function() {
$('.left, .right').hide();
$('#animer').click(function() {
$(".left").toggle("slide", {direction: "left"}, 500);
$(".right").toggle("slide", {direction: "right"}, 500);
});
});
</script>
and that
<button id='animer'>animer</button>
<div class="all">from left</div>
<div class="all">from right</div>
<div class="all">from left</div>
<div class="all">from right</div>
<script>
$(function() {
$('.all').hide();
$('#animer').click(function() {
$('.all').first().show('slow', function showNextOne() {
$(this).next('.all').show('slow', showNextOne);
});
});
});
</script>
But i need this to work no matter the divs order, because the "left" or "right" items will come randomly.
Help will be much appreciated as i am not as competent as i wished in jQuery. ^^
The following uses the all variable to keep a list of all of the divs. When the button is clicked, the slideNext() function is executed, checking the class of the current item to decide on toggle direction, and specifying slideNext (itself) as the function to run when the toggle is complete.
$(function() {
var all = $('.left, .right').hide();
$('#animer').click(function() {
var i = 0;
(function slideNext() {
if (i < all.length) {
var current = all.eq(i);
current.toggle("slide", {
direction: current.hasClass("left") ? "left" : "right"
}, 500, slideNext);
}
i++;
})();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.9.2/jquery-ui.min.js"></script>
<button id='animer'>animer</button>
<div class="left">from left</div>
<div class="right">from right</div>
<div class="left">from left</div>
<div class="right">from right</div>
You can use index from each() loop for delay and set direction based on condition if current div hasClass() left or not.
$(function() {
$('div').hide();
$('#animer').click(function() {
$('div').each(function(i) {
let dir = $(this).hasClass('left') ? 'left' : 'right';
$(this).delay(i * 1000).toggle('slide', {direction: dir})
})
});
});
h1 {
font-family: Helvetica, Arial;
font-weight: bold;
font-size: 18px;
}
body {
text-align: center;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.js"></script>
<h1>HTML Slider Test</h1>
<button id='animer'>animer</button>
<div class="left">from left</div>
<div class="right">from right</div>
<div class="left">from left</div>
<div class="right">from right</div>

fullpage.js, having larger sections and disable scrolling on some sections

jQuery plugin I am using with full documentation:
https://github.com/alvarotrigo/fullPage.js
What I want: I am trying to have my second section disabled for the full page snap effect and also have it a larger height than a regular section (150vh etc.).
Problems: I have attempted it by adding it a new height to section 2
.ok{
width:100%;
height:2000px;
border:1px solid black;
}
and also found some methods in the documentation to cancel the section snap:
$.fn.fullpage.setAutoScrolling(false);
but when I scroll up and down, some of the sections snap back way too quick and is not fluid anymore.
(For example, scroll down to Section 2 then try scrolling to Section 1, it snaps back too quick)
My Fiddle: https://jsfiddle.net/jzhang172/kemtmm9a/30/
$('#fullpage').fullpage({
sectionsColor: ['yellow', 'orange', '#C0C0C0', '#ADD8E6'],
afterLoad: function(anchorLink, index){
var loadedSection = $(this);
if(index == 1){
$.fn.fullpage.setAutoScrolling(true);
}
//using index
if(index == 2){
$.fn.fullpage.setAutoScrolling(false);
}
if(index == 3){
$.fn.fullpage.setAutoScrolling(true);
}
//using anchorLink
if(anchorLink == 'secondSlide'){
alert("Section 2 ended loading");
}
}
});
.section {
text-align:center;
}
.ok{
width:100%;
height:2000px;
border:1px solid black;
}
.la{
height:200%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/alvarotrigo/fullPage.js/master/jquery.fullPage.js"></script>
<div id="fullpage">
<div class="section">One</div>
<div class="section la">
<div class="slide">Two 1</div>
<div class="slide">Two 2</div>
</div>
<div class="section fp-auto-height"><div class="ok"></div>Three</div>
<div class="section">Four</div>
</div>
I think issue with your js code , check with below snippet
$('#fullpage').fullpage({
sectionsColor: ['yellow', 'orange', '#C0C0C0', '#ADD8E6'],
anchors: ['firstPage', 'secondPage', '3rdPage', '4thpage'],
menu: '#menu',
scrollingSpeed: 1000,
afterLoad: function(anchorLink, index){
var loadedSection = $(this);
//using index
if(index == 2){
$.fn.fullpage.setAllowScrolling(false);
}
//using anchorLink
if(anchorLink == 'secondSlide'){
alert("Section 2 ended loading");
}
}
});
.section {
text-align:center;
}
.ok{
width:100%;
height:2000px;
border:1px solid black;
}
.la{
height:200%;
}
<div id="fullpage">
<div class="section">One</div>
<div class="section">
<div class="slide">Two 1</div>
<div class="slide la">Two 2</div>
</div>
<div class="section fp-auto-height"><div class="ok"></div>Three</div>
<div class="section">Four</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/alvarotrigo/fullPage.js/master/jquery.fullPage.js"></script>

Refactoring jQuery repeating pattern

I have painted my self into a corner in order to quickly prototype.
What's the best way to refactor the following jQuery code? Its functionality is to toggle between some sidebar navigation items. I need it to be more dynamic in order to be scalable.
Would you add the IDs inside the if statements, in an array and iterate through them? Use variables? Create a function and call it on the html side onClick? No matter what I think of, it stills leads to a bunch of repeating code.
Thank you!
// TOGGLING LEFT NAVIGATION
$('#settingsClick').click(function() {
if( $('#addContainer, #noteContainer, #logoContainer, #themeContainer').is(':visible') ) {
$('#addContainer').slideUp(350);
$('#noteContainer').slideUp(350);
$('#logoContainer').slideUp(350);
$('#settingsContainer').slideDown(350);
$('#themeContainer').slideUp(350);
} else {
$('#settingsContainer').slideToggle(350);
}
});
$('#addClick').click(function() {
if( $('#settingsContainer, #noteContainer, #logoContainer, #themeContainer').is(':visible') ) {
$('#settingsContainer').slideUp(350);
$('#noteContainer').slideUp(350);
$('#logoContainer').slideUp(350);
$('#addContainer').slideDown(350);
$('#themeContainer').slideUp(350);
} else {
$('#addContainer').slideToggle(350);
}
});
$('#noteClick').click(function() {
if( $('#settingsContainer, #addContainer, #logoContainer, #themeContainer').is(':visible') ) {
$('#settingsContainer').slideUp(350);
$('#addContainer').slideUp(350);
$('#logoContainer').slideUp(350);
$('#noteContainer').slideDown(350);
$('#themeContainer').slideUp(350);
} else {
$('#noteContainer').slideToggle(350);
}
});
$('#logoClick').click(function() {
if( $('#settingsContainer, #addContainer, #noteContainer, #themeContainer').is(':visible') ) {
$('#settingsContainer').slideUp(350);
$('#addContainer').slideUp(350);
$('#noteContainer').slideUp(350);
$('#logoContainer').slideDown(350);
$('#themeContainer').slideUp(350);
} else {
$('#logoContainer').slideToggle(350);
}
});
$('#themeClick').click(function() {
if( $('#settingsContainer, #addContainer, #noteContainer, #logoContainer').is(':visible') ) {
$('#settingsContainer').slideUp(350);
$('#addContainer').slideUp(350);
$('#noteContainer').slideUp(350);
$('#logoContainer').slideUp(350);
$('#themeContainer').slideDown(350);
} else {
$('#themeContainer').slideToggle(350);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<a id="settingsClick">Click Me</a><br>
<div id="settingsContainer">Content...</div>
<br><br>
<a id="addClick">Click Me</a><br>
<div id="addContainer">Content...</div>
<br><br>
<p> Etc... Etc....</p>
You should group using the common CSS class, i.e. header and content. Using the established relationship you can target the others content holder and content associated with the current clicked header element.
$('.container .header').on('click', function() {
//Get the current element
var $this = $(this);
//find the content
var $content = $this.closest('.container').find('.content'); //$this.next()
//get all contents
var content = $('.container .content');
//Slide up others
content.not($content).slideUp(350);
//Slide down
$content.slideToggle(350);
});
.content {
display: none
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="header" id="settingsClick">Click Me</div>
<div class="content" id="settingsContainer">Content...</div>
</div>
<div class="container">
<div class="header" id="addClick">Click Me</div>
<div class="content" id="addContainer">Content...</div>
</div>
<div class="container">
<div class="header" id="noteClick">Click Me</div>
<div class="content" id="noteContainer">Content...</div>
</div>
the best bet would be to do it like so
$(document).on('click', ".trigger", function() {
var sibling_content = $(this).siblings(".content");
if (!sibling_content.hasClass('active')) {
$(".content").slideUp('slow').removeClass('active');
sibling_content.slideDown('slow').addClass('active');
} else {
sibling_content.slideUp('slow').removeClass('active');
}
})
.trigger {
background-color: red;
color: white;
font-size: 16px;
}
.content {
background-color: blue;
color: white;
font-size: 16px;
padding: 20px 0;
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="trigger">trigger</div>
<div class="content">content</div>
</div>
<div class="container">
<div class="trigger">trigger</div>
<div class="content">content</div>
</div>
<div class="container">
<div class="trigger">trigger</div>
<div class="content">content</div>
</div>
<div class="container">
<div class="trigger">trigger</div>
<div class="content">content</div>
</div>

detect click, check attribute value and text inside, and display element

I need to detect click of an element(.menuitem), check the text it contains.
And then based on the attribute(is-checked), hide or show other elements.
I need this only when clicking that other button.
<div class="items">
<div class="menuitem" is-checked="true">
<div class="ytp-menuitem-label">Button 1</div></div>
<div class="menuitem" is-checked="false">
<div class="ytp-menuitem-label">Button 2</div></div>
</div>
<div class="element">some content</div>
<div class="element">some more content</div>
$('.menuitem').click(function () {
if ($('.menuitem').text().trim() === "Button 2"){
if ($('[is-checked="true"]'))
$('.element').css('display', 'block');
if ($('[is-checked="false"]'))
$('.element').css('display', 'none'); }
});
Here's a JSFIDDLE, of what I have:
$('.menuitem').click(function() {
console.log($(this).text().trim())
if ($(this).text().trim() === "Button 2") {
if ($(this).attr('is-checked') == 'true') {
$('.element').css('display', 'block');
} else {
$('.element').css('display', 'none');
}
}
});
.items {
height: 30px;
margin-bottom: 5px;
}
.menuitem {
float: left;
margin-right: 10px;
border: 1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="items">
<div class="menuitem" is-checked="true">
<div class="ytp-menuitem-label">Button 1</div>
</div>
<div class="menuitem" is-checked="false">
<div class="ytp-menuitem-label">Button 2</div>
</div>
</div>
<div class="element">some content</div>
<div class="element">some more content</div>
<div class="element">even more content</div>
Use $(this).attr('is-checked') to get the value
Also use $(this).text().trim() to get the text of clicked element
You've got it a tad wrong, your if statement isn't actually looking at the element which was clicked. Try something along these lines:
$('.menuitem').click(function () {
// $(this) is a reference to the element which was clicked
if ($(this).attr('is-checked') == "true")
$('.element').css('display', 'block');
if ($(this).attr('is-checked') == "false")
$('.element').css('display', 'none');
});

Create Backdrop on Hover

I am currently trying to create functionality exactly as displayed in my JSFIDDLE, Basically to hover over a div and then to have a backdrop beneath that div along with a slide down panel also above the backdrop. the only issue is that the functionality is very buggy and barely works in internet explorer.
Here is the JS:
function darken(panelOpen){
if(panelOpen){
if(jQuery('#menu-backdrop').length){
jQuery("#menu-backdrop").stop().fadeIn(300);
}else{
jQuery(document.body).stop().append(jQuery('<div id="menu-backdrop" class="modal-backdrop"></div>').css('opacity',0.7).hide().fadeIn(300));
}
}else{
jQuery(".modal-backdrop").stop().fadeOut(300);
}
} //Backdrop
jQuery(document).ready(function(e) {
var bioId;
jQuery('.personnel').mouseover(function () {
jQuery(this).css('z-index','1050');
darken(true);
bioId = '#personnel-bio-'+this.id.replace( /[^\d.]/g,'');
var bio = '#personnel-bio-'+this.id.replace( /[^\d.]/g,'');
if(jQuery(bio).is(':visible')){
}else{
jQuery(bio).slideDown(300);
}
}); //dropdown function
jQuery(".wrap").mouseleave(function () {
darken(false);
if(jQuery(bioId).is(':visible')){
jQuery(bioId).slideUp(300);
}else{
}
setTimeout(function() {
jQuery('.personnel').css('z-index','0');
}, 300);
}); // slide up function
});
and the CSS:
.personnel {
position:relative;
}
.personnel-bio {
display:none;
padding:1.2em;
position:relative;
z-index:1050;
margin-bottom:15px;
background:#FFF;
}
And then Finally the HTML:
<div class="wrap">
<div id="personnel-1" class="pull-left personnel">
<div class="personnel-inner">
<div class="thumbnail">
<img src="http://placehold.it/330x290"/>
</div>
<div class="thumbnail-title">
<h4>LAbel</h4>
</div>
</div>
</div>
<div class="clearfix"></div>
<div id="personnel-bio-1" class="personnel-bio">
<h5><strong>Pieter Strydom</strong></h5>
<p>loerm ipsum.</p>
</div>
</div>
I am not quiet Sure what I am doing incorrectly. So Any Help at all will be Greatly Appreciated.
I have tidied up the code a bit, removed unnecessary calls to z-index and stop
The modal-backdrop is in the DOM from the beginning now which also helps to speed things up. The initial CSS is set on that with opacity:0.7; and display:none;
Should work a lot more fluid now.
http://jsfiddle.net/hBB97/2/
HTML:
<div id="menu-backdrop" class="modal-backdrop"></div>
<div class="wrap">
<div id="personnel-1" class="pull-left personnel">
<div class="personnel-inner">
<div class="thumbnail">
<img src="http://placehold.it/330x290" />
</div>
<div class="thumbnail-title">
<h4>Label</h4>
</div>
</div>
</div>
<div class="clearfix"></div>
<div id="personnel-bio-1" class="personnel-bio">
<h5><strong>Pieter Strydom</strong></h5>
<p>loerm ipsum.</p>
</div>
</div>
Javascript:
function darken(panelOpen, personnelContainer) {
if (panelOpen) {
personnelContainer.css('z-index', '1050');
jQuery(".modal-backdrop").fadeIn(300);
} else {
jQuery(".modal-backdrop").fadeOut(300);
personnelContainer.css('z-index', '0');
}
} //Backdrop
jQuery(document).ready(function (e) {
var bioId;
jQuery('.personnel').mouseover(function () {
darken(true, $(this));
bioId = '#personnel-bio-' + this.id.replace(/[^\d.]/g, '');
var bio = '#personnel-bio-' + this.id.replace(/[^\d.]/g, '');
if (jQuery(bio).is(':visible')) {} else {
jQuery(bio).slideDown(300);
}
}); //dropdown function
jQuery(".personnel").mouseleave(function () {
darken(false, $(this));
if (jQuery(bioId).is(':visible')) {
jQuery(bioId).slideUp(300);
}
}); // slide up function
});
CSS:
.personnel {
position:relative;
}
.personnel-bio {
display:none;
padding:1.2em;
position:relative;
z-index:1050;
margin-bottom:15px;
background:#FFF;
}
.modal-backdrop {
display:none;
opacity:0.7;
}

Categories

Resources