So I'm creating a page about user-submitted recipes. Some users have submitted a short quote about the recipe, others have not. I wanted to have the quote, if it exists, to display when the user hovers over the image of the recipe.
Right now, I'm using this:
$(".recipe").hover(function(){
$(".slider-submit").hide();
$(".slider-description").show();
},
function(){
$(".slider-submit").show();
$(".slider-description").hide();
});
The first problem is that it changes for all the recipes, not just the one that is hovered on. The second problem is, I'm unsure how to check if the 'slider description' exists for that recipe or not.
Here is a fiddle of what I'm working on. I'm still learning JQuery so give me any tips, please!
Change your JS like this:
$(".recipe").hover(function(){
$(this).find(".slider-submit").hide();
$(this).find(".slider-description").show();
},
function(){
$(this).find(".slider-submit").show();
$(this).find(".slider-description").hide();
});
This way you will only target the sliders that belong to the element that is being hovered over, instead of target them all.
Here's one solution with checking for non existent descriptions as well as using a more efficient hover function:
$(".recipe").hover(function(){
if ($(".slider-description",this)[0]){
$(".slider-submit",this).toggle();
}
$(".slider-description",this).toggle();
});
It uses the lesser known $(selector, context) notation to only select the text elements within the hovered .recipe element.
JS Fiddle
The trick is to use this that gets passed in with the hover event to find the elements inside.
$(".recipe").hover(function() {
$(this).find(".slider-submit").hide();
$(this).find(".slider-description").show();
},
function() {
$(this).find(".slider-submit").show();
$(this).find(".slider-description").hide();
});
.recipe {
position: relative;
display: inline-block;
white-space: nowrap;
overflow-y: hidden;
font-family: 'Nunito', sans-serif;
font-weight: 600;
text-align: center
}
.slider-text {
position: absolute;
bottom: 0;
width: 200px;
padding: 0% 3% 3% 3%;
color: white;
white-space: normal;
background: rgba(0, 0, 0, 0.45);
overflow: hidden;
z-index: 100;
margin-left: 3px;
}
.slider-text:not(.asparagus-slider) {
padding: 6% 3% 3% 3%;
}
.slider-text>h3 {
font-size: 15px;
}
#asparagus {
font-size: 14px;
padding: 0% 3% 3% 3%;
}
.slider-info {
padding-bottom: 30px;
}
.slider-description {
display: none;
}
#chili-img,
#asparagus-img,
#macCheese-img,
#noBakePie-img {
width: 200px;
height: 200px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-fluid">
<div class="row">
<div class="col-md-3 recipe">
<div class="slider-text">
<h3>Bear Creek Chili</h3>
<p class="slider-submit">
Submitted by: Dottie User
</p>
</div>
<img id="chili-img" src="http://mystateoffitness.com/wp-content/uploads/2016/07/big-game-chili.jpg">
</div>
<div class="col-md-3 recipe">
<div class="slider-text asparagus-slider">
<h3 id="asparagus">Beer Battered Asparagus with Lemon Herb Dipping Sauce</h3>
<p class="slider-submit">
Submitted by: Chris User
</p>
<p class="slider-description">
<em>"This is the only way that I can enjoy asparagus"</em>
</p>
</div>
<img id="asparagus-img" src="http://food.fnr.sndimg.com/content/dam/images/food/fullset/2007/9/10/0/IP0211_Beer_Battered_Asparagus.jpg.rend.hgtvcom.616.462.jpeg">
</div>
<div class="col-md-3 recipe">
<div class="slider-text">
<h3>Mac n' Cheese</h3>
<p class="slider-submit">
Submitted by: Annette User
</p>
</div>
<img id="macCheese-img" src="https://images-gmi-pmc.edge-generalmills.com/c41ffe09-8520-4d29-9b4d-c1d63da3fae6.jpg">
</div>
<div class="col-md-3 recipe">
<div class="slider-text">
<h3>No Bake Peanut Butter Pie</h3>
<p class="slider-submit">
Submitted by: Shari User
</p>
<p class="slider-description">
<em>"This recipe makes enough for two pies - one for your guests and one just for you!"</em>
</p>
</div>
<img id="noBakePie-img" src="http://cdn2.tmbi.com/TOH/Images/Photos/37/300x300/exps17834_CCT1227369D54B.jpg">
</div>
</div>
</div>
To expound on Lixus, the issue that you're facing is that in jQuery, when you do a selection, you are selecting EVERYTHING in the DOM. What you wanted to do is limit your selection scope.
For example, look at the following JS:
$(".slider-submit").hide(); // Global selection
$(this).find(".slider-submit").hide(); // Limit search to only descendants of "this"
In jQuery, generally when you enter into a function passed into a jQuery object (like the event handler in the "hover" function) the this context will be the DOM element and not the jQuery object, so wrapping this with jQuery will give you the jQuery object like normal.
I updated your JSFiddle with this code. https://jsfiddle.net/bkyn40f8/5/
Related
I created an UI where when the user scrolls down the page, 4 grid boxes appears with a "fade in" effect, but when we go up the page, then we scroll down the page again, the animation appears again, while precisely, I don't want the animation to be done several times, but only when the boxes have appeared once.
Here is my code:
const grid_objs = document.querySelectorAll('._grid-obj');
observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.intersectionRatio > 0) {
entry.target.style.animation = `grid-obj .8s ${entry.target.dataset.delay} forwards ease`;
} else {
entry.target.style.animation = "none";
}
});
});
grid_objs.forEach((grid_obj) => {
observer.observe(grid_obj);
});
#import url('https://fonts.googleapis.com/css2?family=Inter:wght#300;400;500;600;700;800&display=swap');
.n-sec__ {
min-height: 100vh;
display:grid;
max-height:100%;
}
._box {
background:#f4f4f4;
border-radius: 10px;
position: relative;
}
._grid {
display: grid;
grid-template-columns: auto auto;
min-width: 100%;
}
._grid ._grid-obj {
display: grid;
margin: 1em;
padding: 2em;
max-width: 800px;
opacity: 0;
}
._grid ._grid-obj ._grid-title {
color:#000000;
font-family: 'Inter', sans-serif;
}
._grid ._grid-obj ._grid-p {
font-weight: 300;
color:#000000;
padding: 0.5em 0;
font-size: 10pt;
line-height: 1.1em;
}
<section style="height:100vh;"></section>
<section class="n-sec__ ">
<div class="_container ">
<div class="_grid">
<div class="_grid-obj _box" data-delay="0s">
<h5 class="_grid-title _z">Community</h5>
<p class="_grid-p _z">Take advantage of a dynamic and caring community, present to propel you to the top of your ladder in your artistic journey. Mainly based on sharing, forge links between passionate or professional artists.</p>
<p class="_grid-p">Feel like the best at us (but stay yourself).</p>
</div>
<div class="_grid-obj _box" data-delay=".5s">
<h5 class="_grid-title">Share</h5>
<p class="_grid-p">Sharing is above all our priority, that's what our network represents. Indeed, we want to implement a realization of things that only very few people perceive. You have to know how to share and recognize your work as it is.</p>
<p class="_grid-p">So don't be shy, and show your work to other artists.</p>
</div>
<div class="_grid-obj _box" data-delay="1s">
<h5 class="_grid-title">Security</h5>
<p class="_grid-p">Your projects will always be fine at Nosfera, and uploaded on a secure server owned by otux.cloud. Regarding your account, your password is encrypted and neither the administrative team has access to it.</p>
<p class="_grid-p">So you can sleep soundly.</p>
</div>
<div class="_grid-obj _box" data-delay="1.4s">
<h5 class="_grid-title">Customization</h5>
<p class="_grid-p">Manage your projects as you wish with our system dedicated to artistic organization.</p>
<p class="_grid-p">Manage your projects as you wish with our system dedicated to artistic organization. You have the ability to create the lists you want, reorganize your dashboard, pin the projects you want, and many more!</p>
</div>
</div>
</div>
</section>
I don't know why it is not working in the jsfiddle but it normally does.
once your desired behavior takes place the first time, you can call unobserve() on the observer to stop it from being observed. ( https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/unobserve )
I have a button that looks like this:
<button class="button-global button-a" id="more" target="1">More Info</button>
It triggers expanded text with this:
$('.p2').hide();
$('#more').click(function (ev) {
var t = ev.target
$('#expanded' + $(this).attr('target')).toggle(50, function(){
console.log(ev.target)
$(t).html($(this).is(':visible')? 'Simplify' : 'More Info')
});
return false;
});
I want this link (only the aboutus link):
<a class="pcnav navlinks" href="#aboutus-target">About Us</a>
to also trigger the expanded text when clicked but not if expanded is already visible, I don't want the text to change on aboutus like it does for the button,
(made it more straightforward for new people seeing the post as it's gotten a bit confusing)
Any help would be great!
Class Driven jQuery
Multiple <a> & <button> Solution
Each <a>, <button>, & <section class='content...'> has:
one "common static class": .x
two "shared state classes": .on and .off
In order to control different tags with the same set of classes, CSS/jQuery selectors are declared as combos thereby establishing specific behavior for multiple tags while sharing a class that allows easy access to all of the tags as a group. Review the comments in the CSS section of Demo 2 for details.
Fiddle✱
Demo 2
Details are commented in demo.
$('.more').on('click', function() {
// Get the #id of the closest article.p
var page = $(this).closest('.p').attr('id');
// Toggle .on/.off on all .x within article.p
$(`#${page} .x`).toggleClass('on off');
});
/*
Exclude .link.on to ensure click event is only
triggered when .off class is assigned to .link
*/
$('.link').not('.on').on('click', function() {
/*+ Expand .content located within the same .p
var page = $(this).closest('.p').attr('id');
$(`#${page} .x`).addClass('on').removeClass('off');
//-*/
//*- Expand .content located at this.href
var jump = $(this).attr('href');
$(`${jump} .x`).addClass('on').removeClass('off');
//-*/
// Scroll to this.href
$('html, body').animate({
scrollTop: $(jump).offset().top
}, 550);
});
html {
overflow-y: scroll;
overflow-x: hidden;
}
html,
body {
background: #fff;
padding: 20px;
font: 400 small-caps 16px/1.45 Arial;
}
main {
display: flex;
flex-flow: column nowrap;
justify-content: center;
align-items: center;
}
article {
background: none;
display: table;
width: 100%;
}
nav,
section,
footer {
background: #222;
color: #fc3;
padding: 20px;
text-align: center;
font-size: 1rem;
margin: 0 auto;
width: 300px;
}
nav {
padding: 10px 20px;
margin: 0em auto -0.5em;
border-top-right-radius: 8px;
border-top-left-radius: 8px;
}
section p {
text-align: left;
}
footer {
padding: 15px 20px 10px;
margin: -2.8em auto 2.25em;
border-bottom-right-radius: 8px;
border-bottom-left-radius: 8px;
}
.link,
footer b {
font-size: 1.5rem;
color: #fc3;
}
nav b {
display: inline-block;
font-size: 1.5rem;
width: 1em;
}
button {
background: #fc3;
color: #000;
border: none;
border-radius: 5px;
padding: 8px 14px;
font: inherit;
font-size: 1.2rem;
cursor: pointer;
width: 150px;
}
/*
The next four rulesets demonstrate how only two
classes can be shared between multiple tags and still
provide different behavior and purpose.
*/
.content.off {
max-height: 0;
font-size: 0;
color: transparent;
opacity: 0;
transition: color 0.65s, max-height 0.95s, font-size 0.95s, opacity 2.5s;
}
.content.on {
height: auto;
max-height: 5000px;
font-size: 1.1rem;
color: #fc3;
opacity: 1;
transition: all 0.75s;
}
.more.off::before {
content: 'More Info';
}
.more.on::before {
content: 'Simplify';
}
<main id='doc'>
<article id='p1' class='p'>
<nav>
<a class="link x off" href="#p2">Next</a>
</nav>
<section>
<button class="more x off"></button>
</section>
<section class="content x off">
<p>A wonderful serenity has taken possession of my entire soul, like these sweet mornings of spring which I enjoy with my whole heart.</p>
<p>I am alone, and feel the charm of existence in this spot, which was created for the bliss of souls like mine.</p>
<p>I am so happy, my dear friend, so absorbed in the exquisite...</p>
</section>
<footer>
<b>1</b>
</footer>
</article>
<article id='p2' class='p'>
<nav>
<a class="link x off" href="#p1">Prev</a>
<b>|</b>
<a class="link x off" href="#p3">Next</a>
</nav>
<section>
<button class="more x off"></button>
</section>
<section class="content x off">
<p>One morning, when Gregor Samsa woke from troubled dreams, he found himself transformed in his bed into a horrible vermin.</p>
<p>He lay on his armour-like back, and if he lifted his head a little he could see his brown belly, slightly domed and divided by arches into stiff sections.</p>
<p>The bedding was hardly...</p>
</section>
<footer>
<b>2</b>
</footer>
</article>
<article id='p3' class='p'>
<nav>
<a class="link x off" href="#p2">Prev</a>
</nav>
<section>
<button class="more x off"></button>
</section>
<section class="content x off">
<p>The quick, brown fox jumps over a lazy dog. DJs flock by when MTV ax quiz prog.</p>
<p>Junk MTV quiz graced by fox whelps. Bawds jog, flick quartz, vex nymphs.</p>
<p>Waltz, bad nymph, for quick jigs vex! Fox nymphs grab quick-jived waltz. Brick quiz whangs jumpy veldt fox. Bright vixens jump; dozy fowl quack.</p>
</section>
<footer>
<b>3</b>
</footer>
</article>
</main>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Single <a> & <button> Solution
Ternary Conditions
The following demo assigns the click event to both button and link individually. A ternary condition is structured like so:
variable = condition ? TRUE : FALSE;
. Also, .class (.more) is used instead of #id (#more) as a better alternative, but it is not necessary.
Demo 1
$('.content').hide();
$('.more').on('click', function() {
var txt = $(this).text() === 'Simplify' ? 'More Info' : 'Simplify';
$(this).text(txt);
$('.content').toggle();
});
$('.navLink').on('click', function() {
$('.content').show();
$('.more').text('Simplify');
});
<button class="more">More Info</button><br>
<a class="navLink" href="#about">About Us</a>
<p class='content'>
Content.
</p>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
✱A fork of Ryan Wheale's nicely styled Fiddle.
You will want to trigger the click event for the #more button. Something like this:
$('a[href="#aboutus-target"]').click((ev) => {
ev.preventDefault();
$('#more').trigger('click');
});
If you only want the nav item to expand the text and never collapse the text, you will need to do something like this:
$('a[href="#aboutus-target"]').click((ev) => {
ev.preventDefault();
const $more = $('#more');
const $targ = $('#expanded' + $more.attr('target'));
// only if the target is not visible
if( !$targ.is(':visible') ) {
$more.trigger('click');
}
});
Here is a fiddle showing it working:
https://jsfiddle.net/tvbhfom8/
I know it's a little late, but I think this may add something here.
The solution without javascript: use <details> tag:
<details>
<summary>Epcot Center</summary>
<p>Epcot is a theme park at Walt Disney World Resort featuring...</p>
</details>
I've seen some custom Scrollbard but don't work for what I need...
I have a div element with dynamic text, sometimes there is lots of text so scroll bars shows up, I wonder if is possible to overflow: hidden; and have an image (arrow pointing down) that when clicked, the div will scroll down normally like when using the browsers scrollbar.
I have seen lots of this: https://grsmto.github.io/simplebar, all have scroll bars on the side, none has what I want.
Here it is (only the basics):
function scrollDown() {
var cuttentOffsetTop = $('#inner').offset().top
$('#inner').offset({top: (cuttentOffsetTop - 10)})
}
#container {
width: 100%;
height: 300px;
background-color: gray;
overflow-y: hidden;
position: relative;
}
.item {
width: 100%;
height: 100px;
background-color: violet;
}
.item + .item {
margin-top: 10px;
}
#scroll-down {
background-color: forestgreen;
color: white;
margin-bottom: 10px;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="scroll-down" onclick="scrollDown()">Click here to scroll down</div>
<div id="container">
<div id="inner">
<div class="item">1</div>
<div class="item">2</div>
<div class="item">3</div>
<div class="item">4</div>
<div class="item">5</div>
<div class="item">6</div>
<div class="item">7</div>
<div class="item">8</div>
<div class="item">9</div>
<div class="item">10</div>
</div>
</div>
If you need an explanation - just ask.
Have you actually attempted to create this? Provide code that you have attempted so that we may edit that, as opposed to writing the whole thing for you. You didn't make it entirely clear if you wanted to jump down to a position, slowly scroll down while the button is held down, or what exactly so I'll provide a few different types.
window.scrollTo(0, 100);
If you know how far down you want to jump, you could use this. Alternately, using HTML you can do the following to jump to a specific part of a page.
Jump to element with id jumpLocation
You just have to google it better. Look at element.scrollTop method, more here. And a thread from stackoverflow..
I am trying to make a page scale or mobile compatible I think is the term. The problem with my page right now is that it looks good at a certain size but when I drag the browser, the background picture of my page covers the "Services" Title the <section> portion.
Here is the jsFiddle: http://jsfiddle.net/eg18dfy0/4/ Not sure how useful this would be as local files are not included in here.
Normal:
Dragging:
Here is my code:
HTML snippet the matters:
<header>
<div class="background_image">
</div>
<div class="welcome-text-container">
<div class="row">
<div class="welcome-text1">Welcome!</div>
<div class="welcome-text2">BE GOOFY, TAKE A PICTURE!</div>
<div class="btn-row">
TELL ME MORE
</div>
</div>
</div>
</header>
<!-- services -->
<section id="services">
<div class="container">
<div class="service-title">Services</div>
<div class="service-caption">What we'll do for you</div>
</div>
</section>
CSS:
.background_image {
background-image: image-url("header-bg.jpg");
background-size: contain;
background-repeat: no-repeat;
width: 100%;
height: 0;
padding-top: 66.64%;
position: absolute;
/* (img-height / img-width * width) */
/* (853 / 1280 * 100) */
}
/* Services */
#services {
padding-top: 110px;
margin-top: 75px;
}
.service-title {
text-align: center;
font-size: 55px;
font-weight: 700;
}
.service-caption {
text-align: center;
font-size: 20px;
}
This should solve your problem:
Fiddle illustrating fix
You're setting your background image in a div that's getting higher stacking priority based on document flow, so it's overlapping your subsequent divs.
Here's the CSS I added to solve the problem:
.container > div.background-image {
z-index: 1;
}
.container > div {
position: relative;
z-index: 2;
}
There are better ways to do this (i.e. not creating a separate div for a background image), but this will solve your issue without major changes to document structure.
All credit to http://placehold.it for the placeholder image. It's a life-saver if you're going to be solving CSS issues on StackOverflow.
I'm trying to make a div that I have on top of another div show up when you click on something.
This is the code for the two divs, without all the stuff that's within each:
<div id="randomarticle_enlarge">
<h1></h1>
<h4></h4>
<p></p>
<p></p>
</div>
<div class="bodybag">
<h1></h1>
<h4></h4>
<p></p>
<p></p>
</div>
Then I have css for each, of course:
.bodybag {
width:960px;
}
#randomarticle_englarge {
height:750px;
width:960px;
position:absolute;
z-index:2;
margin-top:1px;
padding-left:20px;
padding-right:20px;
display: none;
}
Am I supposed to have the bodybag class have a z-index and a position:relative? Because even though I don't it's working (at this point).
Anyway, I have this script written that's doing exactly what I want it to do:
$(document).ready(function() {
$('.popular').click(function() {
$('#textmask').fadeTo( 'fast', 0.1);
$('#backgroundmask').css('background-color', 'white');
});
});
And all I want to happen next is that as the textmask and the backgroundmask fade in/change as they should and do, is for the randomarticle_enlarge div to show up.
I've tried using .toggle and .toggleClass and .slideToggle and .show but nothing is working.
Absolute positioning must be relative to a container. In order to absolutely position something you need to indicate what it's absolutely positioned to. Something along these lines.
<div id="randomarticle_englargeContainer">
<div id="randomarticle_englarge">
</div>
<div class="bodybag">
</div>
</div>
#randomarticle_englargeContainer {
position: relative;
}
.bodybag {
position: absolute;
left: 0;
top: 0;
}
When copying everything from above I have no issues using $('#randomarticle_englarge').toggle();. Check your browser's console for errors; you might find the answers there.
I'm not exactly sure about what would you like to do with the divs, but I created an example for you, maybe this is what you want:
LIVE DEMO
So there is two divs. The 2nd div covers the 1st one. Clicking on a 'button' hides the 2nd div, so the 1st one reveals. Clicking again the 'button', the 2nd div appears and covers the 1st one again.
HTML:
<div class="popular">Click me!</div>
<div class="container">
<div id="randomarticle_enlarge">
<h1>A</h1>
<h4>B</h4>
<p>C</p>
<p>D</p>
</div>
<div class="bodybag">
<h1>E</h1>
<h4>F</h4>
<p>G</p>
<p>H</p>
</div>
</div>
CSS:
.container {
position: relative;
}
.bodybag {
width: 100px;
height: 200px;
background-color: red;
}
#randomarticle_enlarge {
width: 100px;
height: 200px;
background-color: green;
position: absolute;
top: 0;
left: 0;
}
.hide {
display: none;
}
jQuery:
$(document).ready(function() {
$('.popular').click(function() {
$('#randomarticle_enlarge').toggleClass('hide');
});
});