How to format my jQuery - javascript

I have managed to setup a background image on hover of another element using this great forum! As I am new to jQuery and javascript, I am struggling to format adding additional effects on hover. e.g. I don't just want to use an append on the background-image I also want to do a background-size:cover; append and a transition: all 0.33s ease. How would I go about adding this to the current syntax?
$(document).ready(function() {
//Preload
$('<img/>').hide().attr('src', '../img/background-experience.jpg').load(function(){
$('body').append($(this));
});
$('.btn').hover(function() {
$('body').css('background-image', 'url("../img/background-experience.jpg")');
}, function() {
$('body').css('background', '');
});
});
EDIT: FOLLOWING HELP FROM NOEL
Added using custom class which may be a better solution now having issues with the transition this is my scss code.
body {
background: $black;
color: $white;
font-family: $default-font;
font-weight: 600;
transition: all 0.33s ease;
}
.my-custom-class {
background-image:url('https://yt3.ggpht.com/-V92UP8yaNyQ/AAAAAAAAAAI/AAAAAAAAAAA/zOYDMx8Qk3c/s900-c-k-no-mo-rj-c0xffffff/photo.jpg');
background-size:cover;
}

You can just put everything in a css class that you can add to your body on hover of the button. This requires two things: (1) defining the css rule; then (2) adding, removing this on hover.
Below is a sample code to show this in action. Hope this helps!
$('.btn').hover(function() {
$('body').addClass('my-custom-class');
}, function() {
$('body').removeClass('my-custom-class');
});
.my-custom-class {
background-image:url('https://yt3.ggpht.com/-V92UP8yaNyQ/AAAAAAAAAAI/AAAAAAAAAAA/zOYDMx8Qk3c/s900-c-k-no-mo-rj-c0xffffff/photo.jpg');
background-size:cover;
}
body {
background-image:url('https://www.petdrugsonline.co.uk/images/page-headers/cats-master-header');
background-size:cover;
transition: all 0.33s ease;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="btn">My button</button>

Hi you can add more styles as below,
$('body').css({'background-image':'url("../img/background-experience.jpg")','transition':'all 0.33s ease','background-size':'cover'});

First of all you need to add css3 transition property for the image you want to show transition when hover. Then you must add css on hover for setting background size cover.
For more information about transition css3 property w3shools

Related

JavaScript media query vs CSS media query

I've noticed that the JavaScript media query seems to take effect after the CSS equivalent ones.
I've created two examples demonstrating what I'm talking about:
First example
HTML:
<div class="foo">
bar
</div>
CSS:
.foo {
background-color: orange;
}
#media(max-width: 300px) {
.foo {
background-color: blue;
transform: translateY(100px);
transition: all 300ms ease-out;
}
}
jsbin link is: here
Here transition happens, when screen width becomes 300px or less from something bigger.
But when creating responsive design such transition can be annoying. I'm trying to get rid of them. The following Javascript and CSS solves the problem, but I'm not sure that is it reliable or not.
2nd example
HTML
<div class="foo">
bar
</div>
<button>toggle translateY to 200px</button>
CSS
.transition {
transition: all 300ms ease-out;
}
.foo {
background-color: orange;
}
#media(max-width: 300px) {
.foo {
background-color: blue;
transform: translateY(100px);
}
}
.translateY {
transform: translateY(200px);
}
JavaScript:
const w = window.matchMedia("(max-width: 300px)");
const div = document.querySelector(".foo");
const button = document.querySelector('button');
function fun(e) {
if (e.matches) {
div.classList.add('transition');
} else {
div.classList.remove('transition');
}
}
// for initial screen width change detection
fun(w);
w.addEventListener('change', fun);
button.onclick = function() {
div.classList.toggle('translateY');
}
jsbin link is here
Here it seems the following thing happens in order when screen width becomes 300px or less from something bigger:
CSS transform: translateY(100px) is rendered in a flash.
transition class is added to div by JavaScript.
By clicking the button, it makes sure that the transition class is working.
This example doesn't cause any unwanted transition as screen size becomes 300px or less from something bigger.
So it seems that any CSS media query is rendered before JavaScript equivalent media queries. I think it's a good thing. But I'm not sure, is it the standard well supported behavior? Is it safe to build logic based on this behavior?
This is part of the CSS specificity
Inline styles added to an element (e.g., style="font-weight: bold;") always overwrite any styles in external stylesheets, and thus can be thought of as having the highest specificity.
The javascript code you posted will add inline styles (through the style property of the element) and thus has the highest specificity. (it has nothing to do with the js media query, it just has to do with how you apply the style in the JS to the element)
Update after the comments/update in question
Again it depends on when you load the CSS and the JS. If you first include the CSS file, since it is a render blocking resource, it will be applied first.
I am not sure though, why don't you apply all the rules through CSS media queries ?
const div = document.querySelector(".foo");
const button = document.querySelector('button');
button.onclick = function() {
div.classList.toggle('translateY');
}
.foo {
background-color: orange;
}
#media(max-width: 300px) {
.foo {
background-color: blue;
transform: translateY(100px);
transition: all 300ms ease-out;
}
}
.translateY {
transform: translateY(200px);
}
<div class="foo">
bar
</div>
<button>toggle translateY to 200px</button>

How can I stop this jQuery from bugging out?

So I'm trying to create a box that has two layers: The front layer and the back layer. They're going to be stacked on top of each other so the back layer is hidden by default.
When you hover over the top of the box (front layer technically), then the front layer is supposed to slide up revealing the back layer. I tried to do this by using .slideUp() and .slideDown() but it kept bugging out revealing both layers at the same time. So then I switched to just .slideUp() and .fadeIn() but that didn't seem to help too much.
As you can see, it sometimes shows both divs when it's not supposed to and it also slides multiple times randomly. How could I make this more efficient?
Here is a JsFiddle
UPDATE:
Questions seeking debugging help ("why isn't this code working?") must
include the desired behavior, a specific problem or error and the
shortest code necessary to reproduce it in the question itself.
Questions without a clear problem statement are not useful to other
readers.
That is the reason people are voting to close this answer... What does this question not have, from that list?
Desired behavior? - Check
Specific problem? - Check
Shortest code necessary? - Check
Clear problem? - check
You don't really need to use slideUp and slideDown, you can achieve the slide effect by using the transform and transition CSS3 properties.
Updated JS fiddle: https://jsfiddle.net/9uw2q24h/3/
Javascript:
$('.outer').hover(function() {
$(this).children('.front').addClass('front-up');
}, function() {
$(this).children('.front').removeClass('front-up');
});
CSS:
.outer {
position: relative;
.front,
.back {
text-align: center;
width: 100%;
}
.back {
display: block;
}
.front {
position: absolute;
transition: 0.5s ease;
}
.front-up {
transform: translateY(-100%);
}
}
If you have to support older browsers, make sure to add the vendor prefixes to the transition and tranform rules (-webkit-, -moz-, etc.).
You can do this like:
var running = false;
$('.outer').hover(function() {
if (!running) {
running = true;
$(this).children('.front').slideUp(function() {
$(this).next('.back').slideDown(function() {
running = false;
});
});
}
}, function() {
if (!running) {
running = true;
$(this).children('.back').slideUp(function() {
$(this).prev('.front').slideDown(function() {
running = false;
});
});
}
});
Explanation: as soon as the animation starts you save the status in a variable in order to avoid conflicts (otherwise it will be called again). Additionally with the slideDown and slideUp combined you have a much smoother animation. You had a not very nice flickering with your combination of fadeOut and slideDown
Fiddle: https://jsfiddle.net/dL7ckq6b/
With a slight tweak to your CSS, specifically making your elements' position property absolute, will cause your back element to be behind your front element from the start, now you only have to show/hide your front element.
Javascript:
$('.outer').hover(function() {
$('.front').slideUp();
console.log("IN");
}, function() {
$('.front').slideDown();
console.log("OUT");
});
I did also update the CSS to more clearly show the effect happening.
CSS:
.outer {
.front,
.back {
text-align: center;
position: absolute;
padding: 20px 10px;
border: 2px solid yellow;
}
.front {
z-index: 10;
background-color: red;
}
.back {
z-index: 0;
background-color: blue;
}
}
Here is the JSFiddle: https://jsfiddle.net/z8e7eb4b/

Change color with css over time back and forth

I was wondering if someone could help me change the color of a div from black to white after two seconds, then from white to black after two seconds, back again and so on as long as the div exists. Putting it other way, the div is only shown whenever a user clicks and drags a surface (just like the desktop selection area) and my objective is to change the color of the borders as described above while the user is still making his selection on the surface just as resizing the div.
If your browser requirements allow you to use css3 you don't need any javascript at all.
HTML:
<div class="blinkdiv">
</div>
CSS:
#-webkit-keyframes blackWhite {
0% { background-color: white; }
50% { background-color: white; }
51% { background-color: black; }
100% { background-color: black; }
}
.blinkdiv {
height: 100px;
background-color: black;
-webkit-animation-name: blackWhite;
-webkit-animation-iteration-count: infinite;
-webkit-animation-duration: 2s;
}
Here's an example: http://jsfiddle.net/tommcquarrie/w3Qy9/1/
This will transition the background color from black to white after every 2 seconds, and repeat..
body {
-webkit-animation:name 2s infinite;
}
#-webkit-keyframes name {
0% {background-color:black;}
100% {background-color:white;}
}
jsFiddle demo.. haven't tested it in many browsers.. works in Chrome.
There are a couple of ways to do this. You could either use a setTimeout that always spawns another setTimeout (until the div disappears), or you could use a setInterval and toggle the color (with a clearInterval to stop the transition if the element should be removed). I feel like the latter approach is a little more straightforward, so I'll use that one:
var toggleIntervalId = setInterval( function() {
var $div = $('#toggleMe');
if( $div.length ) {
$div.attr( 'background-color', $div.attr('background-color')=='black'
? 'white' : 'black' );
} else {
clearInterval( toggleIntervalId );
}, 2000 );
Depending on your requirements and usage of CSS3 (or lack thereof), you may want to do this with Javascript/jQuery, and in particular with jQuery, you will likely want to look into jQueryUI.
I suggest you take a look at this StackOverflow question.
However, as for some instant gratification, here's a cross-browser Fiddle modified from the above question that will probably suffice, or at least give you a good starting point (needless, I still suggest you research this a bit further and look into the links provided as well...)
The Fiddle's code:
JQuery:
function changeColor(element, curNumber){
curNumber++;
if(curNumber > 2){
curNumber = 1;
}
console.log(curNumber);
element.addClass('color' + curNumber, 500);
element.attr('class', 'color' + curNumber);
setTimeout(function(){changeColor(element, curNumber)}, 1000);
}
changeColor($('#testElement'), 0);
CSS:
.color1{
background: white;
color: black;
}
.color2{
background: black;
color: white;
}
HTML:
<div id="testElement">This will change colors</div>

get previous siblings, accordion effect

I'm trying to get an accordion effect on a DIV when hovering.
The right side of the accordion is working already, but the left one isn't.
I put my code in jsFiddle
Can someone please help me with the left side? I've been trying it for hours but it won't work :(
Javascript:
$(document).ready(function () {
$('.middle').hover(function () {
$(this).siblings().stop().animate({
opacity: 1
}, 200);
},
function () {
$(this).siblings().stop().animate({
opacity: 0
}, 200);
});
});
The reason the right is fading, and the left isn't is because you are applying a CSS transition to the right side spans.
You can easily address this by applying the same transition to <span> tags:
.squares span {
transition-property:opacity;
transition-duration:1s;
transition-delay:0.1s;
}
In fact, you could condense your code and make it easier to adjust overall by combining repeated styles across the multiple spans into single definitions.
For example:
.squares span {
opacity: 0;
float: left;
width: 139px;
height: 138px;
transition-property:opacity;
transition-duration:1s;
transition-delay:0.7s;
}
span.middle {
background:#0f0;
opacity: 1;
}
span.left1,
span.right1 {
background:#00F;
transition-delay:0.1s;
}
span.left2,
span.right2 {
background:#0FF;
transition-delay:0.3s;
}
span.left3,
span.right3 {
background:#0F0;
transition-delay:0.5s;
}
span.left4,
span.right4 {
background:#FF0;
transition-delay:0.7s;
}
See the working example here: http://jsfiddle.net/uBBZ2/14/
In your css you set the transition-property and transition-duration settings on the right side blocks, but not the left side ones. If you comment them out, both transitions happen quickly and at the same time. If you add those settings mirrored to the left side, they both happen more slowly.

Using CSS to target a style other than itself

It might only be possible with JavaScript, but I was wondering if it was possible to link one style to another with events like :focus or :hover in CSS alone.
For example, could the class "hitArea" change the "changeArea" background attribute when in focus?
.changeArea { background: yellow; }
.hitArea div:focus { changeArea:changeBG; }
.changeArea changeBG { background: blue; }
I know there is communication between styles when doing CSS animations, like in this working example:
.reveal {
position:absolute;
top:190px;
left:0px;
margin-left:0px;
-webkit-animation-name:reveal;
-webkit-animation-duration:0.1s;
-webkit-animation-fill-mode:backwards;
-webkit-animation-delay:0.2s;
animation-name:reveal;
animation-duration:0.1s;
animation-fill-mode:backwards;
animation-delay:0.2s;
}
#-webkit-keyframes reveal {
0% { left:-900px; -webkit-animation-timing-function:linear; }
99% { left:-900px; -webkit-animation-timing-function:linear; }
100% { left:0px; }
}
So what is the syntax, or is it even possible, for me to communicate between other styles?
If your HTML looks like this:
<div class="hitarea">
<div class="changeArea"></div>
</div>
Then you can target changeArea when hitArea is focused like this:
.hitarea:focus .changeArea {
background-color: red;
}
This will only work when "changeArea" is some child of hitarea.
Read more on CSS Selectors and what you can do with them here: https://developer.mozilla.org/en-US/docs/CSS/Getting_Started/Selectors
I don't believe it is possible. You can take a look at http://sass-lang.com/ which allows you to do things like that.
If .changeArea is a child of .hitArea, yes!
.hitArea:focus .changeArea{ /* Styles to apply when .hitarea is hovered */ }
If that's not what you want, I recommend setting it up so that when .hitArea is focused, javascript applies a class to .changeArea that has the style you want to apply.

Categories