Hi! I really try to find a topic related to my issue here, but I had no luck...
Some simple code: I have two divs, placed in the same position -
<div id="fader1" style="display:inline-block;position:absolute;background-image:url(images/fader1.png);opacity:1;width:296px;height:435px;margin:-215px 50px -20px"></div>
<div id="fader2" style="display:inline-block;position:absolute;background-image:url(images/fader2.png);opacity:0;width:296px;height:425px;margin:-215px 50px -20px"></div>
The idea is when the mouse passes over the div "fader1", the opacity changes to 0, and the opacity of fader2 changes to 1. And turn back like the beginning if I put the cursor out of the div.
I've tried to achieve this with mootools but I'm now in a dead-end.
Mootools Demos have the example of Fx.Morph like this:
$('myElement').set('opacity', 0.5).addEvents({
mouseenter: function(){
// This morphes the opacity and backgroundColor
this.morph({
'opacity': 0.6,
'background-color': '#E79D35'
});
},
mouseleave: function(){
// Morphes back to the original style
this.morph({
opacity: 0.5,
backgroundColor: color
});
}
});
As you can see, I can only manage ONE element (this.morph). I try to put other element like: "('fader1').morph" with no results... But I think that I'm doing it wrong.
I really appreciate any help you can give me to achieve this in mootools. Regards!
you should read the manual and not copy/paste from examples.
$('myElement').set('opacity', 0.5).addEvents({
mouseenter: function(){
// This morphes the opacity and backgroundColor
this.morph({
'opacity': 0.6,
'background-color': '#E79D35'
});
}
});
in the above function, the scope this refers to myElement. if you need to reference a different element, then simply do so.
(function(){
var other = $('myOtherElement').set('moprh', {
link: 'cancel'
}); // save a reference and set link to cancel existing morphing
$('myElement').set('opacity', 0.5).addEvents({
mouseenter: function(){
// This morphes the opacity and backgroundColor
other.morph({
'opacity': 0.6,
'background-color': '#E79D35'
});
},
mouseleave: function(){
// Morphes back to the original style
other.morph({
opacity: 0.5,
backgroundColor: color
});
}
});
}());
read up on what $ (documentid) returns (an element), saving an element into a variable and referencing it later - this is standard javascript.
Related
I'll preface this by saying my initial problem is difficult to reproduce.
Brief explanation of my problem following, question is at the bottom.
So I am using the Jquery multislider for a project.
Here is a link to it: Multislider
Now my issue is that the animation of the moving elements seems to lag... Sometimes.
It jumps instead of moving smoothly.
The way the element works is by applying the animate() method to the first item and applies an inline margin-left property to the first .item
With some research I have found that CSS animations often cause problems when margins are used for the animation(among some other properties like top/bottom/left/right, as well as height/width) and that using transform is preferable.
So far so good.
This is the snippet in the javascript that creates the animation:
function singleLeft(){
isItAnimating(function(){
reTargetSlides();
$imgFirst.animate(
{
marginLeft: -animateDistance /* This is the part that causes me problems */
}, {
duration: animateDuration,
easing: "swing",
complete: function(){
$imgFirst.detach().removeAttr('style').appendTo($msContent);
doneAnimating();
}
}
);
});
}
function singleRight(){
isItAnimating(function(){
reTargetSlides();
$imgLast.css('margin-left',-animateDistance).prependTo($msContent);
$imgLast.animate(
{
marginLeft: 0
}, {
duration: animateDuration,
easing: "swing",
complete: function(){
$imgLast.removeAttr("style");
doneAnimating();
}
}
);
});
}
Now if I understand it correctly, I have to replace the marginLeft: -animateDistance portion with a transformX property, is that correct?
But I am failing to make it work.
So my question is, how can I replace the marginLeft: -animateDistance portion with transform: translateX() and add the animateDistance variable between the parentheses?
I have tried something like transform: "translateX(-$(animateDistance))", but that just disables the animation entirely.
Am I missing something?
I'm open for other suggestions to solve the issue of the laggy animation as well, this just is the conclusion I came to.
You can use animate with $(this) and .css() if you use step()
let test = "100";
$('div h2').animate({ pxNumber: test }, {
step: function(pxNumber) {
$(this).css('transform','translateX(-' + pxNumber + 'px )');
},
duration:'slow',
easing: "swing",
complete: function(){
console.log('Animation done');
// doneAnimating();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div><h2>Move it</h2></div>
What I'm trying to achieve: when my mouse is moving then do this, but when it stops moving for like half a second then do that, but when it starts to move again then do that.
This is my temporary jQuery:
$(document).ready(function() {
$('.test').mouseenter(function(){
$(this).mousemove(function(){
$(this).css({
'background-color' : '#666',
'cursor' : 'none'
});
});
});
$('.test').mouseout(function(){
$(this).css({
'background-color' : '#777',
'cursor' : 'default'
});
});
});
And I have absolutely no idea how to do that, basically my code does this: when you enter an element with a mouse and your mouse is moving inside that element then apply this CSS and when your mouse leaves the element then apply this CSS, but when mouse is inside that element and it stops moving for some period of time then do this <- I can't figure the last bit out.
I understood that you want to detect the mouse movements over a particular element.
To achieve this, you need to use the mousemove event... There is no mousefroze event, sadly!
So you will use a setTimeout() and will constantly clear its callback while the mouse moves. Since that event fires multiple times on a single slight movement, you can set the delay quite tight. So it should be accurate.
The setTimeout callback will execute only when the mouse will stop moving. And that is the whole "trick".
About delays... I think that 100 ms is the lowest accurate value. Less than that will create flickering on "slow" user moves.
The mouseenter is not really usefull here, because it is overridden by the mousemove event right after (because when the mouse enters... it also moves!). But the mouseleave or mouseout is really usefull to restore the element's original state and clear the timeout too... Because the mouse won't be moving over your element does'nt mean it doesn't move at all. So you have to clear that when leaving.
$(document).ready(function() {
var test = $('#test');
var moveTimer;
test.on("mouseout",function(){
$(this).css({
'background-color' : 'white',
}).text("");
clearTimeout(moveTimer);
});
test.on("mousemove",function(){
console.log("I'm moving!");
clearTimeout(moveTimer);
moveTimer = setTimeout(function(){
console.log("I stopped moving!");
test.css({
'background-color' : 'red',
}).text("The mouse is not moving.");
},100)
$(this).css({
'background-color' : 'blue',
}).text("Movement detected...");
});
});
#test{
margin:50px;
border:2px solid black;
height:200px;
width:200px;
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="test"></div>
CodePen
Sounds like you're looking for timeouts. In a similar project, I used something like this:
var timer;
function active() {
// Apply active styles
}
function inactive() {
// Apply inactive styles
}
$('.test').mousemove(function(){
active(); // Apply active styles
clearTimeout(timer); // Reset the timer
timer = setTimeout(out, 500);
});
Once you move the mouse over the area, that launches a timer that resets every mouse move. If the timer is ever allowed to expire, the user's gone inactive and we run whatever code we like.
So I was just googling. This is the answer:
$(document).ready(function() {
var countdown;
$('.test').hover(function() {
setTimeout(function(){
$('.test').css({
'background-color' : '#666',
'cursor' : 'none'
});
cursor();
}, 2000);
}, function(e){
$('.test').css({
'background-color' : '#777',
'cursor' : 'default'
});
});
$('.test').mousemove(function() {
$('.test').css({
'background-color' : '#777',
'cursor' : 'default'
});
cursor();
});
function cursor() {
countdown = setTimeout(function() {
$('.test').css({
'background-color' : '#666',
'cursor' : 'none'
});
}, 2000);
}
});
});
This may deviate from your current code, but I think CSS is more appropriate here than JavaScript.
.test {
background-color:#666;
}
.test:hover {
background-color:#777;
cursor:none;
}
These lines of CSS should perform the exact same thing without the complication. Note that in your example, for every pixel the mouse moves, the css is set once more. And since you are not removing the event handler on mouse out, the event is actually ran multiple times.
This morphs just fine but I need it to pause first then morph.
var animate = (function(){
var div = document.getElement('div.es-transition');
if (div){
div.set('morph', {duration: 800, transition: 'quad:out'});
div.pauseFx(1000, 'morph');
div.addClass('hidden');
div.setStyles({'visibility': 'hidden', 'opacity': 0});
div.removeClass('hidden').fade('in');
}
});
window.addEvent('load', animate);
Banging head.
TIA
don't know about pauseFx? this is not standard mootools-core api. it has http://mootools.net/docs/core/Fx/Fx#Fx:pause - which needs to be applied to the instance.
in your case, it makes no sense anyway as you pause before you even run it. which means, use setTimeout or delay. pause is to stop and resume a morph/tween midway. please clarify what you are trying to achieve
also. .set('morph') does not work with .fade() - fade is based on tween options, not morph. the difference between tween and morph is single property vs multiple properties.
if I understand this correctly, you need to rewrite as:
var animate = (function(){
var div = document.getElement('div.es-transition');
if (div){
div.set('tween', {duration: 800, transition: 'quad:out'});
div.addClass('hidden');
div.setStyles({'visibility': 'hidden', 'opacity': 0});
(function(){
div.removeClass('hidden').fade(0, 1);
}).delay(1000);
}
});
window.addEvent('load', animate);
I am trying to do a mouseover event for one picture where when you mouseover a div comes up and animates on the picture. When I do my mouseover though, it brings up both divs for separate pictures when I only want one at a time. Here is my code. The first part is the mouseover. Second is mouseout.
$('.portfolio img').mouseover(function(){
$(this).css('cursor', 'pointer');
$(this).parent().find('img:first').stop().animate({opacity:1}, 800, function() {
$("div.folio").animate({ height: '+=25px', top: '-=24px' }, 100, function() {
$("div.folio span").animate({ opacity: 1 }, 500);
});
});
});
$('.img_grayscale').mouseout(function(){
$(this).stop().animate({opacity:0}, 800, function() {
$("div.folio span").animate({ opacity: 0 }, 500, function() {
$("div.folio").animate({ height: '-=25px', top: '+=24px' }, 100);
$("div.folio").css('top', '-9px');
});
});
});
<div class="portfolio">
<h2>The Portfolio</h2>
<p class="slideTwo">Check out some of our recent projects.</p>
<ul>
<li><img src="portfolioOne.jpg"></img><div class="folio"><span>thesite.com</span></div></li>
<li><img src="portfolioOne.jpg"></img><div class="folio"><span>mysite.com</span></div></li>
</ul>
</div>
Using jQuery's $("div.folio") will return all divs with a class of "folio". Since you are seeing this animation on both images, rather than just the one you've moused-over, I'm assuming they both have the same class on the div they want to animate. In order to only animate one, you'll need to be more specific when selecting it with jQuery. Including $(this) on the path to the div to animate usually works, but I can't tell you the exact code without the corresponding HTML.
You need to cancel the bubble up event by returning "false" from your event handler.
$('.portfolio img').mouseover(function(){
// Your logic here...
return false;
});
There are a couple of concerns that I have about this which may or may not be problematic depending on what else is going on that you haven't shown.
You're doing $(this).parent().find('img:first') inside of a jQuery onmouseover function where $(this) should already be representing the img that you care about. Did you find that was necessary for some reason?
You could be more specific in your selector. Try doing $(".portfolio>ul>li>img")
img_grayscale is only mentioned once in your markup in your question so I'm not sure how that class gets applied but I'm assuming it does.
You could just add the class portfolio (or some unique identifier) to your images directly and probably have an easier time figuring out exactly why it isn't working as you expect. Then your mouseover selector could just be $(".specialClass")
You should definitely try posting a jsfiddle.net; you could borrow any two images off the web for testing.
Managed to figure this one out. I had to basically transverse the DOM through the following code. I referenced the image and then I went to the parent then to the next element in the DOM which was my div of div.folio. Then I went to the child of that object to fade it in. I did the same thing in reverse basically on the mouseout.
$('.portfolio img').mouseover(function(){
$(this).css('cursor', 'pointer');
$(this).parent().find('img:first').stop().animate({opacity:1}, 800, function() {
$(this).parent().next().animate({ height: '+=25px' }, 100, function() {
$(this).children().animate({ opacity: 1 }, 100);
});
});
});
$('.img_grayscale').mouseout(function(){
$(this).stop().animate({opacity:0}, 800, function() {
$(this).parent().next().children().animate({ opacity: 0 }, 100, function() {
$(this).parent().animate({height: '-=25px' }, 100);
});
});
});
I am currently working on my portfolio website which uses a very simple navigation.
However what I want to do is have the drop shadow beneath the type become stronger (read: higher opacity/ darker) when the type is being hovered on.
Right now my code looks as follows and does not generate any errors but simply does not do anything either.
For a good understanding of what I mean please have a look at the website with a live example.
/* Work | Play | About | Contact */
/* Shadow Opacity */
$(document).ready(function() {
$('#workShadow', '#playShadow', '#aboutShadow', '#contactShadow').fadeTo( 0, 0.1);
});
/* Shadow Hover effect */
$(document).ready(function() {
$('a#work').hover(function() {
$('#workShadow').fadeTo( 200, 0.5);
}, function() {
$('#workShadow').fadeTo( 400, 0.1);
});
});
/* Type movement on hovering */
$(document).ready(function() {
$('a.shift').hover(function() { //mouse in
$(this).animate({ paddingTop: 85, paddingBottom: 2 }, 200);
}, function() { //mouse out
$(this).stop().animate({ paddingTop: 75, paddingBottom: 12 }, 400);
});
});
Basically I need the opacity of the shadow elements (4 individual ones) to start at 10% opacity and while the user hovers, the type moves down (this part is working) and simultaneously the shadow becomes stronger, increases to 60% opacity. Then revert back to 10% when on mouseOut.
This line is wrong - it is passing a bunch of arguments to the $() function.
$('#workShadow', '#playShadow', '#aboutShadow', '#contactShadow').fadeTo( 0, 0.1);
As the documentation notes, jQuery doesn't expect N arguments as a selector, but 1:
$('#workShadow, #playShadow, #aboutShadow, #contactShadow').fadeTo( 0, 0.1);
It is common (and good) practice to give a set of objects that should do something a common class or to select them in a smarter than just listing all their IDs. Based on your current HTML, this selector gets all the shadow <div>s in the menu, and is much shorter - you won't have to modify your code if you add a new menu element later on, for example:
$('div','#navigationFrame').fadeTo(0, 0.1);
I also see you have this:
<li id="work"><a id="work" ...>
This is really, really, wrong. IDs should be unique in the document. By having more than 1 ID in the document not only are you breaking best practices, ID selection on jQuery will go crazy and won't work as expected. Like the fadeTo selector, you can change the shadow changing code to a cleaner:
$('a','#navigationFrame').hover(function() {
$(this).next('div').fadeTo(200, 0.5);
}, function() {
$(this).next('div').fadeTo(400, 0.1);
});
I tested the website with these changes and it works fine.
What the selectors in my examples are doing is taking advantage of jQuery's context. By doing this:
$('a','#navigationFrame');
Or this:
$('div','#navigationFrame');
We are telling jQuery "only give me the <a> (or <div>) elements inside #navigationFrame.
It is equivalent to this:
$('#navigationFrame').find('a');
It is a good idea to take advantage of this. I see you have a tendency to manually list the elements you're trying to do stuff to do even if they are all similar in some way. Try to shake this habit and let jQuery's powerful selectors get what you want from the document.
I use this:
$(".thumbs img").addClass('unselected_img');
$('.thumbs img').click(function() {
$(this).addClass('selected_img');
if ($(this).is('selected_img')) {
$(this).removeClass('selected_img');
} else {
$('.thumbs img').removeClass('selected_img');
$(this).addClass('selected_img');
}
});
// hover the lists
$('.thumbs img').hover(
function() {
$(this).addClass('selected_img_h');
},
function() {
$(this).removeClass('selected_img_h');
});`
and style:
.selected_img
{
opacity: 1; filter: alpha(opacity = 100);
border:none;
}
.selected_img_h{
opacity: 1; filter: alpha(opacity = 100);
border:none;
}
.unselected_img
{
opacity: 0.6; filter: alpha(opacity = 60);
border:none;
}