I'm using a jQuery plugin called bPopup , which receives a jQuery object and creates a popup element.
it is constructed using an options element that looks like this:
{
modalClose: false,
modalColor: "#ffffff",
follow: [false, false] // Follow x, follow y
}
I want to change the "follow" property within the popup dynamically, without re-creating the popup or cloning it, but actually changing the existing popup.
in other words: I want the popup to follow when scrolling, and be able to pause that following when desired.
A fiddle displaying the problem:
https://jsfiddle.net/syoels/9tqcaq7m/11/
Thanks a lot in advance!
Ok. It was much simpler than I thought...
just find the popped up div, address it's 'bPopup' data attribute and change the follow property.
Working fiddle with the solution: https://jsfiddle.net/syoels/ydu5s9zu/
$(document).ready(function() {
$('#popupBtn').click(function() {
var popup_div = $('<div id="popup"><p>Holy guacamole! what a gorgeous popup!<br><br>scroll down and see if it follows you</p> <button id="stopFollowingBtn">Toggle follow</button></div>');
popup_div.bPopup({
follow: [true, true], //x, y
opacity: 0.6,
modalColor: 'greenYellow',
});
$('#stopFollowingBtn').click(function() {
var follow_x = $('#popup').data('bPopup').follow[0];
var follow_y = $('#popup').data('bPopup').follow[1];
$('#popup').data('bPopup').follow = [!follow_x, !follow_y];
});
});
});
body {
background: black;
height: 1000px;
}
#popup {
display: none;
position: absolute;
width: 140px;
height: 200px;
background: #ccc;
text-align: center;
border: 2px solid white;
border-radius: 3px;
box-shadow: 3px 3px 2px rgba(0, 0, 0, 0.2);
}
#popupBtn {
display: block;
margin: 10px auto;
}
#stopFollowingBtn {
background: red;
color: white;
font-weight: bold;
cursor: pointer;
padding: 5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-beta1/jquery.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/bPopup/0.11.0/jquery.bpopup.js"></script>
<body>
<button id="popupBtn">show popup</button>
</body>
Related
I want to style the bar before the thumb with a different color on a range input. I'v tried looking for a solution but I havent found a proper solution. This is what I need it to look like:
Chrome doesnt seem to support input[type='range']::-webkit-slider-thumb:before anymore and I am at a loss how to style it. Here's what I have so far:
input[type='range'] {
min-width: 100px;
max-width: 200px;
&::-webkit-slider-thumb {
-webkit-appearance: none !important;
background-color: #white;
border: 1px solid #gray-4;
height: 14px;
width: 14px;
&:hover,
&:focus,
&:active {
border-color: #blue;
background-color: #gray-2;
}
}
&::-webkit-slider-runnable-track {
background-color: #gray-2;
border: 1px solid #gray-4;
}
}
document.querySelectorAll(".__range").forEach(function(el) {
el.oninput =function(){
var valPercent = (el.valueAsNumber - parseInt(el.min)) /
(parseInt(el.max) - parseInt(el.min));
var style = 'background-image: -webkit-gradient(linear, 0% 0%, 100% 0%, color-stop('+ valPercent+', #29907f), color-stop('+ valPercent+', #f5f6f8));';
el.style = style;
};
el.oninput();
});
.__range{
margin:30px 0 20px 0;
-webkit-appearance: none;
background-color: #f5f6f8;
height: 3px;
width: 100%;
margin: 10px auto;
}
.__range:focus{
outline:none;
}
.__range::-webkit-slider-thumb{
-webkit-appearance: none;
width: 20px;
height: 20px;
background: #29907f;
border-radius: 50%;
cursor: -moz-grab;
cursor: -webkit-grab;
}
<input class="__range" id="rng" name="rng" value="30" type="range" max="100" min="1" value="100" step="1">
The trick in the post referenced by shambalambala is clever, but I don't think it will work in this case if you want to get something that looks exactly like the image you show. The approach there is to put a shadow on the thumb to create the different coloring to the left of the thumb. Since the shadow extends in the vertical, as well as the horizontal, direction, you also have to add overflow:hidden to the range or the track in order to clip the shadow. Unfortunately, this also clips the thumb. So if you want a thumb that extends beyond the track in the vertical dimension, such as in the image you show where the thumb is a circle with a diameter larger than the track width, this won't work.
I'm not sure there's a pure CSS solution to this problem. With JavaScript, one way around this is to make two range elements that overlap exactly. For one range element, you will see only the thumb and for one you will see only the track. You can use the shadow approach on the track element to get the different color before the thumb. You can style the thumb on the thumb range however you want, and since overflow is not set to hidden for this range element, it can extend beyond the width of the track. You can then use JavaScript to yoke the two range elements together, so that when you move the thumb on the thumb-visible element, the value of the track-visible element also changes.
For example (works in webkit browsers--will need some additional styling for other browsers):
<html>
<head>
<style>
.styled_range {
position: relative;
padding: 10px;
}
input[type=range] {
-webkit-appearance: none;
width: 600px;
background: transparent;
position: absolute;
top: 0;
left: 0;
}
input[type=range]::-webkit-slider-thumb {
-webkit-appearance: none;
}
input[type=range]:focus {
outline: none;
}
input[type=range]::-webkit-slider-runnable-track {
width: 100%;
height: 12px;
}
.track_range {
pointer-events: none;
}
.track_range::-webkit-slider-runnable-track {
background: #D0D0D0;
border-radius: 6px;
overflow: hidden;
}
.track_range::-webkit-slider-thumb {
-webkit-appearance: none;
background: transparent;
height: 1px;
width: 1px;
box-shadow: -600px 0 0 600px #666666;
}
.thumb_range::-webkit-slider-runnable-track {
background: transparent;
cursor: pointer;
}
.thumb_range::-webkit-slider-thumb {
-webkit-appearance: none;
border: 3px solid #ffffff;
border-radius: 20px;
height: 40px;
width: 40px;
background: #1180AD;
cursor: pointer;
margin: -12px 0px 0px 0px;
}
</style>
</head>
<body>
<form>
<div class="styled_range">
<input type="range" class="track_range"/>
<input type="range" class="thumb_range"/>
</div>
<br/>
<div class="styled_range">
<input type="range" class="track_range"/>
<input type="range" class="thumb_range"/>
</div>
</form>
</body>
<script>
window.onload = function() {
var styledRanges = document.getElementsByClassName('styled_range');
for (var i=0; i<styledRanges.length; i++) {
var thumbRange = null, trackRange = null;
for (var j=0; j<styledRanges[i].children.length; j++) {
var child = styledRanges[i].children[j];
if (child.className === 'thumb_range')
var thumbRange = child;
else if (child.className === 'track_range')
var trackRange = child;
}
thumbRange.oninput = function(thumbRange, trackRange) {
return function(e) {
trackRange.value = thumbRange.value;
};
}(thumbRange, trackRange);
}
}
</script>
</html>
I have 10 links and each of them is different from the others.I want when user hovers on them background image of the div changes and a tooltip text be shown on top of the links with a fade-in animation .
i have tried to make several functions using JS and it works but it's a lot of code and mostly repetitive.I want a good shortcut through all of that useless coding.
document.getElementById("d1").onmouseover = function() {
mouseOver1()
};
document.getElementById("d2").onmouseover = function() {
mouseOver2()
};
document.getElementById("d3").onmouseover = function() {
mouseOver3()
};
document.getElementById("d1").onmouseout = function() {
mouseOut1()
};
document.getElementById("d2").onmouseout = function() {
mouseOut2()
};
document.getElementById("d3").onmouseout = function() {
mouseOut3()
};
function mouseOver1() {
document.getElementById("dogs").style.background = "blue";
document.getElementById("tooltiptext1").style.visibility = "visible";
}
function mouseOut1() {
document.getElementById("dogs").style.background = "black";
document.getElementById("tooltiptext1").style.visibility = "hidden";
}
function mouseOver2() {
document.getElementById("dogs").style.background = "green";
document.getElementById("tooltiptext2").style.visibility = "visible";
}
function mouseOut2() {
document.getElementById("dogs").style.background = "black";
document.getElementById("tooltiptext2").style.visibility = "hidden";
}
function mouseOver3() {
document.getElementById("dogs").style.background = "red";
document.getElementById("tooltiptext3").style.visibility = "visible";
}
function mouseOut3() {
document.getElementById("dogs").style.background = "black";
document.getElementById("tooltiptext3").style.visibility = "hidden";
}
#dogs {
float: right;
margin-top: 5%;
background: black;
width: 150px;
height: 150px;
}
#d-list {
color: white;
direction: ltr;
float: right;
width: 60%;
height: 60%;
}
#tooltiptext1,
#tooltiptext2,
#tooltiptext3 {
color: black;
background-color: gray;
width: 120px;
height: 30px;
border-radius: 6px;
text-align: center;
padding-top: 5px;
visibility: hidden;
}
<div id="animals">
<div id="dogs"></div>
<div id="d-list">
<pre style="font-size:22px; color:darkorange">dogs</pre><br />
<pre>white Husky</pre>
<p id="tooltiptext1">Tooltip text1</p>
<pre>black Bull</pre>
<p id="tooltiptext2">Tooltip text2</p>
<pre>brown Rex</pre>
<p id="tooltiptext3">Tooltip text3</p>
</div>
</div>
Please have in mind that all of links will change same outer div object and the idea is to change the background image of that div and the tooltip shoud appear on the top of the links....so,
any ideas?
edit: added animation requested.
CSS is almost always better done in script by using classes when multiple elements are being manipulated with similar functions so I used that here. Rather than put some complex set of logic in place I simply added data attributes for the colors - now it works for any new elements you wish to add as well.
I did find your markup to be somewhat strangely chosen and would have done it differently but that was not part of the question as stated.
I took the liberty of removing the style attribute from your dogs element and put it in the CSS also as it seemed to belong there and mixing markup and css will probably make it harder to maintain over time and puts all the style in one place.
Since you DID tag this with jQuery here is an example of that.
$(function() {
$('#d-list').on('mouseenter', 'a', function(event) {
$('#dogs').css('backgroundColor', $(this).data('colorin'));
$(this).parent().next('.tooltip').animate({
opacity: 1
});
}).on('mouseleave', 'a', function(event) {
$('#dogs').css('backgroundColor', $(this).data('colorout'));
$(this).parent().next('.tooltip').animate({
opacity: 0
});
});
});
#dogs {
float: right;
margin-top: 5%;
background: black;
width: 150px;
height: 150px;
}
#d-list {
color: white;
direction: ltr;
float: right;
width: 60%;
height: 60%;
}
.dog-header {
font-size: 22px;
color: darkorange;
margin-bottom: 2em;
}
.tooltip {
color: black;
background-color: gray;
width: 120px;
height: 30px;
border-radius: 6px;
text-align: center;
padding-top: 5px;
opacity: 0;
position:relative;
top:-4.5em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<div id="animals">
<div id="dogs"></div>
<div id="d-list">
<pre class="dog-header">dogs</pre>
<pre>white Husky</pre>
<p id="tooltiptext1" class="tooltip">Tooltip text1</p>
<pre>black Bull</pre>
<p id="tooltiptext2" class="tooltip">Tooltip text2</p>
<pre>brown Rex</pre>
<p id="tooltiptext3" class="tooltip">Tooltip text3</p>
</div>
</div>
Updated
This answer was written before the question was edited to show the intended markup/styling and before all the details were included. The code has been updated to work with that structure.
I think the simplest thing is just to create a configuration object to detail the varying bits, and then use common code for the rest. Here's one approach:
const configs = [
['d1', 'tooltiptext1', 'blue'],
['d2', 'tooltiptext2', 'green'],
['d3', 'tooltiptext3', 'red'],
];
configs.forEach(([id, tt, color]) => {
const dogs = document.getElementById('dogs');
const el = document.getElementById(id);
const tip = document.getElementById(tt);
el.onmouseover = (evt) => {
dogs.style.background = color
tip.style.visibility = "visible";
}
el.onmouseout = (evt) => {
dogs.style.background = "black";
tip.style.visibility = "hidden";
}
})
#dogs{float:right;margin-top:5%;background:#000;width:150px;height:150px}#d-list{color:#fff;direction:ltr;float:right;width:60%;height:60%}#tooltiptext1,#tooltiptext2,#tooltiptext3{color:#000;background-color:gray;width:120px;height:30px;border-radius:6px;text-align:center;padding-top:5px;visibility:hidden}
<div id="animals"> <div id="dogs"></div><div id="d-list"> <pre style="font-size:22px; color:darkorange">dogs</pre><br/> <pre>white Husky</pre> <p id="tooltiptext1">Tooltip text1</p><pre>black Bull</pre> <p id="tooltiptext2">Tooltip text2</p><pre>brown Rex</pre> <p id="tooltiptext3">Tooltip text3</p></div></div>
Obviously you can extend this with new rows really easily. And if you want to add more varying properties, you can simply make the rows longer. If you need to add too many properties to each list, an array might become hard to read, and it might become better to switch to {id: 'demo', tt: 'dem', color: 'blue'} with the corresponding change to the parameters in the forEach callback. (That is, replacing configs.forEach(([id, tt, color]) => { with configs.forEach(({id, tt, color}) => {.) But with only three parameters, a short array seems cleaner.
Older code snippet based on my made-up markup.
const configs = [
['demo', 'dem', 'blue'],
['dd', 'dem1', 'green']
];
configs.forEach(([id1, id2, color]) => {
const a = document.getElementById(id1)
const b = document.getElementById(id2)
a.onmouseover = (evt) => {
a.style.background = color
b.style.visibility = "visible";
}
a.onmouseout = (evt) => {
a.style.background = "black";
b.style.visibility = "hidden";
}
})
div {width: 50px; height: 50px; float: left; margin: 10px; background: black; border: 1px solid #666; color: red; padding: 10px; text-align: center}
#dem , #dem1{visibility:hidden;}
<div id="demo">demo</div>
<div id="dem">dem</div>
<div id="dd">dd</div>
<div id="dem1">dem1</div>
my way of seeing that => zero Javascript:
div[data-info] {
display: inline-block;
margin:80px 20px 0 0;
border:1px solid red;
padding: 10px 20px;
position: relative;
}
div[data-bg=blue]:hover {
background-color: blue;
color: red;
}
div[data-bg=green]:hover {
background-color: green;
color: red;
}
div[data-info]:hover:after {
background: #333;
background: rgba(0, 0, 0, .8);
border-radius: 5px;
bottom: 46px;
color: #fff;
content: attr(data-info);
left: 20%;
padding: 5px 15px;
position: absolute;
z-index: 98;
min-width: 120px;
max-width: 220px;
}
div[data-info]:hover:before {
border: solid;
border-color: #333 transparent;
border-width: 6px 6px 0px 6px;
bottom: 40px;
content: "";
left: 50%;
position: absolute;
z-index: 99;
}
<div data-info="Tooltip for A Tooltip for A" data-bg="blue">with Tooltip CSS3 A</div>
<div data-info="Tooltip for B" data-bg="green" >with Tooltip CSS3 B</div>
I want to make sth like this:
http://codepen.io/lukejacksonn/pen/PwmwWV?editors=001
in my site, but I'm using an AngularJS.
The main problem is the JS script. It's jQuery and my problem is: will it work with AngularJS? And if yes - how to properly write this code in Controller (or Directive? - is it a DOM manipulation?)
Code from Codepen:
JS:
var $nav = $('.greedy-nav');
var $btn = $('.greedy-nav button');
var $vlinks = $('.greedy-nav .visible-links');
var $hlinks = $('.greedy-nav .hidden-links');
var breaks = [];
function updateNav() {
var availableSpace = $btn.hasClass('hidden') ? $nav.width() : $nav.width() - $btn.width() - 30;
// The visible list is overflowing the nav
if($vlinks.width() > availableSpace) {
// Record the width of the list
breaks.push($vlinks.width());
// Move item to the hidden list
$vlinks.children().last().prependTo($hlinks);
// Show the dropdown btn
if($btn.hasClass('hidden')) {
$btn.removeClass('hidden');
}
// The visible list is not overflowing
} else {
// There is space for another item in the nav
if(availableSpace > breaks[breaks.length-1]) {
// Move the item to the visible list
$hlinks.children().first().appendTo($vlinks);
breaks.pop();
}
// Hide the dropdown btn if hidden list is empty
if(breaks.length < 1) {
$btn.addClass('hidden');
$hlinks.addClass('hidden');
}
}
// Keep counter updated
$btn.attr("count", breaks.length);
// Recur if the visible list is still overflowing the nav
if($vlinks.width() > availableSpace) {
updateNav();
}
}
// Window listeners
$(window).resize(function() {
updateNav();
});
$btn.on('click', function() {
$hlinks.toggleClass('hidden');
});
updateNav();
LESS:
#color-1: #ff9800;
#color-2: #f57c00;
#color-3: #ef6c00;
body {
min-width: 320px;
padding: 30px;
background: #ff9800;
font-family: Helvetica, sans-serif;
}
h1 {
color: #fff;
font-weight: bold;
text-align: center;
margin-top: 50px;
font-size: 24px;
}
p {
color: #fff;
text-align: center;
margin-top: 10px;
font-size: 14px;
}
a {
color: #fff;
}
.greedy-nav {
position: relative;
min-width: 250px;
background: #fff;
a {
display: block;
padding: 20px 30px;
background: #fff;
font-size: 18px;
color: #color-1;
text-decoration: none;
&:hover {
color: #color-3;
}
}
button {
position: absolute;
height: 100%;
right: 0;
padding: 0 15px;
border: 0;
outline: none;
background-color: #color-2;
color: #fff;
cursor: pointer;
&:hover {
background-color: #color-3;
}
&::after {
content: attr(count);
position: absolute;
width: 30px;
height: 30px;
left: -16px;
top: 12px;
text-align: center;
background-color: #color-3;
color: #fff;
font-size: 14px;
line-height: 28px;
border-radius: 50%;
border: 3px solid #fff;
font-weight: bold;
}
&:hover::after {
transform: scale(1.075);
}
}
.hamburger {
position: relative;
width: 32px;
height: 4px;
background: #fff;
margin: auto;
&:before,
&:after {
content: '';
position: absolute;
left: 0;
width: 32px;
height: 4px;
background: #fff;
}
&:before {
top: -8px;
}
&:after {
bottom: -8px;
}
}
.visible-links {
display: inline-table;
li {
display: table-cell;
border-left: 1px solid #color-1;
}
}
.hidden-links {
position: absolute;
right: 0px;
top: 100%;
li {
display: block;
border-top: 1px solid #color-2;
}
}
.visible-links li:first-child {
font-weight: bold;
a { color: #color-1 !important; }
}
.hidden {
visibility: hidden;
}
}
HTML:
<nav class='greedy-nav'>
<button><div class="hamburger"></div></button>
<ul class='visible-links'>
<li><a target="_blank" href='https://github.com/lukejacksonn/GreedyNav'>Greedy</a></li>
<li><a href='#'>navigation</a></li>
<li><a href='#'>that</a></li>
<li><a href='#'>handles</a></li>
<li><a href='#'>overflowing</a></li>
<li><a href='#'>menu</a></li>
<li><a href='#'>elements</a></li>
<li><a href='#'>effortlessly</a></li>
</ul>
<ul class='hidden-links hidden'></ul>
</nav>
<h1>resize the window</h1>
<p>(animations with <a target="_blank" href="http://codepen.io/lukejacksonn/pen/gpOrmd">actuate</a> coming soon)</p>
will it work with AngularJS?
jQuery will work with AngularJS. It doesn't care if you use/not use AngularJS.
Likewise AngularJS feels the same way about jQuery.
For jQuery to work - It only requires a jQuery object to perform the manipulations.
For AngularJS to work - It expects the angular related properties to be intact, and not be removed by external factors like jQuery.
So will jQuery work with AngularJS - Yes.
Should you use jQuery with AngularJS - No.
And if yes - how to properly write this code in Controller (or Directive? - is it a DOM manipulation?)
Write a Directive - call it the greedy-nav-menu/greedyNavMenu or whatever you like. Pass as an attribute the menu items in an object and let the directive take care of the behavior.
I've conveniently asked you avoid jQuery and "Write a directive" that performs DOM manipulation without jQuery.
Here is what you need to perform DOM manipulation
https://docs.angularjs.org/api/ng/function/angular.element
Also to get the input for angular element - use JavaScript's document.getElementBy*
You get a subset of the jQuery library in the jqLite package - available for you to use through angular element.
If you are not satisfied with the functions in jqLite - go ahead and add jQuery but make sure they're included in the digest loop using angular applyand that you only use the jQuery inside the directive.
For further reading - http://ng-learn.org/2014/01/Dom-Manipulations/
If you also add JQuery to your page this will work fine. You could paste the code into a controller and insert add it to the HTML:
<div ng-controller="NavController">
<nav class='greedy-nav'>
...
</div>
Writing a custom directive is possible and recommended, but will be more complicated.
Also note that angular supports a subset of JQuery alreay, more on this here: https://docs.angularjs.org/api/ng/function/angular.element
You need to rewrite the jQuery code to Angular style. Say, use directive.
Although not recommended, you can simply move the jQuery code to a controller/directive. Angular provides jqLite, which is a subset of jQuery. If you load jQuery before Angular, then jqLite === jQuery.
I am working on my final for my webpage development class, I am trying to make a blog themed website. I want to make my code it so that there is a profile picture and when clicked it turns into a box and reveals a bio and some other info. I already have that part done, but now I want to make it so that when the profile picture is clicked again, it will make the box and the info disappear. I understand that there are ways and I have tried some but to no success. When I try .toggle, it just disappears it completely. Any advice would help, thank you
(JSfiddle wasn't working for me, sorry) >
CodePen
JavaScript:
$(document).ready(function() {
$('#picback').click(function() {
$('#picback').animate({
borderTopLeftRadius: 100,
borderTopRightRadius: 100,
borderBottomLeftRadius: 2,
borderBottomRightRadius: 2,
height: 460
}, 'slow');
$('#info').fadeIn('slow');
});
});
We're in 2015. Javascript or jQuery is not needed here!
Use CSS transitions and make use of :checked pseudo class. This way you can also easily set an initial state.
Fully working demo: http://codepen.io/anon/pen/mJrvXo
#visibleToggle {
display: none;
}
#picback {
background-color: #B8B8B8;
border-radius: 50%;
width: 230px;
height: 230px;
border: 2px solid white;
margin: 0 auto;
box-shadow: 0 0 5px;
text-align: center;
transition-duration: 0.6s;
}
#picback:hover {
box-shadow: 0px 0px 8px black;
cursor: pointer;
}
#profilepic {
height: 200px;
position: relative;
top: 16px;
left: 2px;
}
#profilepic:hover {
cursor: pointer;
}
#name {
font-family: 'Playball', cursive;
color: blue;
text-shadow: 0 0 3px white;
}
#age {
font-family: 'Pragati Narrow', sans-serif;
font-size: 25px;
}
#bio {
font-family: 'Roboto', sans-serif;
color: white;
}
#info {
opacity: 0;
}
#visibleToggle:checked + #picback {
border-radius: 120px 120px 2px 2px;
height: 460px;
}
#visibleToggle:checked + #picback #info {
opacity: 1;
}
<input type="checkbox" id="visibleToggle" />
<div id='picback'>
<label for="visibleToggle">
<img src='https://www.shoptab.net/blog/wp-content/uploads/2014/07/profile-circle.png' id='profilepic' />
</label>
<div id='info'>
<h2 id='name'>Joshua T. Hurlburt</h2>
<h2 id='age'>15</h2>
<p id='bio'>My name is Josh. I attend school as a freshman at Rhinelander High School. This is a project I made for my Web Page Development Final.</p>
</div>
</div>
This is what I would recommend:
Instead of performing the animations in jQuery on click, give an active class to the picture element when clicked.
Perform your animations with CSS only when the picture has the active class.
Remove the class if you click on the picture element and it exists.
I would love to give you actual code, but since it's for your final, this should give you a good starting place :) Best of luck!
Try utilizing px unit values at css , js ; checking for display property of $("#info") at click of #picback to fade in , fade out #info ; reset #picback css back to initial borderRadius , height
$(document).ready(function() {
var picback = $("#picback")
, info = $("#info");
picback.click(function() {
if (info.css("display") === "none") {
$(this).animate({
borderTopLeftRadius: 100,
borderTopRightRadius: 100,
borderBottomLeftRadius: 2,
borderBottomRightRadius: 2,
height: 460
}, 'slow');
info.fadeIn('slow');
} else {
$(this).animate({borderRadius:120,height:230}, 'slow');
info.fadeOut('slow');
}
});
});
a {
text-decoration: none;
color: black;
text-align: center;
}
#picback {
background-color: #B8B8B8;
border-radius: 120px;
width: 230px;
height: 230px;
border: 2px solid white;
margin: 0 auto;
box-shadow: 0 0 5px;
}
#picback:hover {
box-shadow: 0px 0px 8px black;
}
#profilepic {
height: 200px;
position: relative;
top: 15px;
left: 5px;
}
#name {
font-family: 'Playball', cursive;
color: blue;
text-shadow: 0 0 3px white;
}
#age {
font-family: 'Pragati Narrow', sans-serif;
font-size: 25px;
}
#bio {
font-family: 'Roboto', sans-serif;
color: white;
}
#info {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<a href='#'>
<div id='picback'>
<img src='https://www.shoptab.net/blog/wp-content/uploads/2014/07/profile-circle.png' id='profilepic'>
<div id='info'>
<h2 id='name'>Joshua T. Hurlburt</h2>
<h2 id='age'>15</h2>
<p id='bio'>My name is Josh. I attend school as a freshman at Rhinelander High School. This is a project I made for my Web Page Development Final.</p>
</div>
</div>
</a>
codepen http://codepen.io/anon/pen/zGKepE
You should use .toggleClass() for click in the image and control the states of bio (for example collapsed and expanded) directly in css.
Here's an example of a very simple solution. Other examples posted already are a bit sexier, but I just used a variable to check whether or not it's open or closed. I also added in the basic closing animation, but you'll want to fiddle with that to make it not terrible. For example I'd suggest resetting the border radius in the callback after the animation function to prevent that ugly oval effect.
$(document).ready(function() {
var dropped = false;
$('#picback').click(function() {
if (!dropped) {
$('#picback').animate({
borderTopLeftRadius: 100,
borderTopRightRadius: 100,
borderBottomLeftRadius: 2,
borderBottomRightRadius: 2,
height: 460
}, 'slow');
$('#info').fadeIn('slow');
dropped = true;
} else { // Closing animation
$('#picback').animate({
borderRadius: "50%",
height: "230px"
}, 'slow');
$('#info').fadeOut('slow');
dropped = false;
}
});
});
http://codepen.io/anon/pen/dopaJq
What you can do here is use a closure function that remembers its state:
var clickHandler = (function () {
var isOpen = false;
return function () {
isOpen = !isOpen; // Toggles between true and false
if (isOpen) {
$('#picback').animate({
borderTopLeftRadius: 100,
borderTopRightRadius: 100,
borderBottomLeftRadius: 2,
borderBottomRightRadius: 2,
height: 460
}, 'slow');
$('#info').fadeIn('slow');
} else {
// Add close animation here
}
};
})();
$('#picback').click(clickHandler);
Try this code. It adds a class when animated and then checks for it before animating.
$(document).ready(function() {
$('#picback').click(function() {
var $this = $(this);
if($this.hasClass('animated')) {
$this.removeAttr('style').removeClass('animated');
} else {
$this.animate({
borderTopLeftRadius: 100,
borderTopRightRadius: 100,
borderBottomLeftRadius: 2,
borderBottomRightRadius: 2,
height: 460
}, 'slow').addClass('animated');
$('#info').fadeIn('slow');
}
});
});
I'm trying to remove class 'active' when you click on the checkbox the 2nd time, the same way Pinterest does it for Twitter/Facebook checkboxes when a user adds a pin:
Adding 'active' class on click is easy. However, I couldn't figure how to remove it once it was added. I tried this, but it didn't work:
$(".add_link_twitter.active").click(function(e) {
$(this).removeClass(activePostTwitter);
});
I have two questions:
How to remove the 'active' css class on the 2nd click on the
checkbox?
How to disable '.add_link_twitter:hover' when the Twitter
checkbox is selected?
Thanks in advance!
Here's the jQuery:
var postTwitter = ".add_link_twitter";
var activePostTwitter = "active";
$(postTwitter).click(function(e) {
$(this).addClass(activePostTwitter);
});
Here's the html:
<label class="add_link_twitter">
<input type="checkbox" name="publish_to_twitter" class="publish_to_twitter"><span>Share on Twitter</span>
</label>
Here's the css:
.add_link_twitter{
position:absolute;
left:15px;
bottom:16px;
color: #a19486;
border: 2px solid transparent;
border-color: #F0EDE8;
border-radius: 4px;
font-size: 13px;
font-weight: bold;
cursor: pointer;
padding: 7px;
padding-top: 5px;
padding-bottom: 5px;
}
.active {
border-color: #468BD0;
color: #468BD0;
background-color: whiteSmoke;
}
.add_link_twitter:hover
{
color: #A19486;
border: 2px solid transparent;
border-color: #C2B1A2;
border-radius: 4px;
background-color: white;
padding: 7px;
padding-top: 5px;
padding-bottom: 5px;
}
Instead of
$(postTwitter).click(function(e) {
$(this).addClass(activePostTwitter);
});
use
$(postTwitter).click(function(e) {
$(this).toggleClass(activePostTwitter);
});
EDIT:
The event triggers twice per click, probably because of event propagation. To work around this, assign the handler to the input and have it change the class of its parent:
$(postTwitter + " input").click(function(e) {
$(this).parent().toggleClass(activePostTwitter);
});
Confirm jsfiddle: http://jsfiddle.net/bpfqB/
This should work for both your questions:
$(function() {
"use strict";
var $postTwitter = $("label.add_link_twitter");
$postTwitter.find("input:checkbox").click(function() {
$(this).parent().toggleClass("active");
if($("input.publish_to_twitter").is(":checked")) {
$(this).parent().removeClass("hover");
}
});
$postTwitter.hover(
function() {
if($("input.publish_to_twitter").is(":checked")) {
return;
}
$(this).addClass("hover");
},
function() {
$(this).removeClass("hover");
});
});
You need to make some changes to your CSS though, you have to do the hovering with jQuery (skip the CSS hover).
DEMO