Jquery fadeTo on mouseover - javascript

I am using a plugin called anything slider and am trying to make the controls fade after 4 seconds (which is working) then change opacity back to 1 on mouseover (not working). Here is what I have so far...what am I doing wrong?
$(slider.$controls).mouseover(function()
slider.$controls.fadeTo(400, 1.0);
});
$(function () {
var fadeTime = 400,
fadeDelay = 4000,
timer, hideControls = function (slider) {
clearTimeout(timer);
setTimeout(function () {
slider.$controls.fadeTo(fadeTime, 0.3);
$('.tooltip').fadeOut(fadeTime);
}, fadeDelay);
};
});

you sould replace every slider.$controls.fadeTo with slider.controls.fadeTo
$(slider.controls).mouseover(function()
$(this).fadeTo(400, 1.0);
});

You have a syntax error on line 2. Where you have
slider.$controls.fadeTo...
you should have
$(this).fadeTo...
because once you've entered the anonymous function on line 1, the this object now refers to the DOM element upon which you're executing this code, which is the element represented by slider.controls.

First you use slider.controls to target the control element(s), then you use slider.$controls to target the same element(s). I think you need to decide which one it is.
Also, inside a callback function you can use this as a reference to the element that has had the event fired on it:
$(slider.controls).bind('mouseover', function () {
$(this)...
});
Otherwise if you want to fade-in-out all the controls at the same time then you just need to figure out if you need to use slider.$controls or slider.controls.
UPDATE
I see you have changed your question and now you are using slider.$controls both times. You should put your mouseover code inside the document.ready event handler so you know the DOM elements are available:
$(function () {
slider.$controls.mouseover(function()
slider.$controls.fadeTo(400, 1.0);
});
var fadeTime = 400,
fadeDelay = 4000,
timer, hideControls = function (slider) {
clearTimeout(timer);
setTimeout(function () {
slider.$controls.fadeTo(fadeTime, 0.3);
$('.tooltip').fadeOut(fadeTime);
}, fadeDelay);
};
Also I noticed that you wrapped slider.$controls in a jQuery object the first time, but not the second, make sure to do that if slider.$controls is not already a jQuery object (many times developers put a $ as the first character of a variable name to denote that it is a jQuery object).

Related

Long click on button creates many instant clicks

Basically I'm trying to make a button to be performed again many times as long as the mouse is down on that button.
I need this for buttons with sliders. Right now, I click on a button for example "Increase Slider" and the slider is increased by 1 step, but now I want to be able to increase the slider many steps if I long press on that button.
How do I do that?
Your do loop runs as many times as it can in 1000 ms, and the mouseleave and mouseup handlers never get a chance to run because their events are sitting in the message queue waiting for the mousedown handler to finish running through that loop.
The loop sets up a couple thousand timeouts, to be run at least 200 ms later. Those timeouts don't actually do anything given the code you posted, because window's click handler is being called, not your button's.
The mouseleave and mouseup handlers essentially do nothing, because start will be reset to a valid time before ever being checked.
So how do we fix it?
There are two delays we want: the 1000 ms delay between the initial click and the first time the slider increases, and the 200 ms delay between slider increases. If the user cancels during the first 1000 ms, we'll count that as a single click. If the user cancels after the repetition starts, we shouldn't count that as a click. (We'll define "canceling" as releasing the mouse button or moving the cursor off the button. This means pressing the mouse button over the UI button and moving the cursor off will count as a click, but the code will be simpler.)
We can set up the delays by setting up a timeout that, after 1000 ms, sets up an interval that, every 200 ms, increases the slider. We won't be using the click event for the slider increase because of the last line of the spec:
If the user cancels after the repetition starts, we shouldn't count that as a click.
So we'll give the slider-increase code its own function, increaseSlider() (which is good practice anyway):
function startLongClick (e) {
window.setTimeout(() => {
increaseSlider();
window.setInterval(() => {
increaseSlider();
}, 200);
}, 1000);
}
$('#button').on('mousedown', startLongClick);
We put the first call to increaseSlider() in the timeout so the slider first increases 1000 ms after the initial click, not 1200. We use arrow functions in the timeout and interval because arrow functions don't redefine this, so we'd be able to refer to the triggering <button> if necessary.
I can't stop it!
As the code is now, a single click on the button will start the whole long-click process, with no way of stopping it. Stopping the process means stopping the timeout and interval, which we can do with window.clearTimeout() or window.clearInterval() (they're the same function; don't tell anybody). We'll need to hang on to the IDs setTimeout() and setInterval() give us, and clear them in the mouseup and mouseleave handlers:
let intervalId;
let timeoutId;
function startLongClick (e) {
timeoutId = window.setTimeout(() => {
increaseSlider();
intervalId = window.setInterval(() => {
increaseSlider();
}, 200);
}, 1000);
}
function cancelLongClick () {
window.clearInterval(intervalId);
window.clearTimeout(timeoutId);
}
$('#button').on('mousedown', startLongClick);
$('#button').on('mouseup', cancelLongClick);
$('#button').on('mouseleave', cancelLongClick);
What about the short click?
Now the button's doing what we want it to do, with one exception: a short click doesn't do anything, because we're not using the click handler and the timeout is being cleared before increaseSlider() is ever called. A short click should be registered if a canceling event is fired after the mousedown event but before the timeout fires. Since timeoutId is undefined before the mousedown event and we don't need it once the timeout fires, we can assign undefined to it in the timeout and use it to determine whether we should register a short click:
let intervalId;
let timeoutId;
function startLongClick (e) {
timeoutId = window.setTimeout(() => {
timeoutId = undefined;
increaseSlider();
intervalId = window.setInterval(() => {
increaseSlider();
}, 200);
}, 1000);
}
function cancelLongClick () {
window.clearInterval(intervalId);
if (timeoutId) {
increaseSlider();
window.clearTimeout(timeoutId);
timeoutId = undefined;
}
}
$('#button').on('mousedown', startLongClick);
$('#button').on('mouseup', cancelLongClick);
$('#button').on('mouseleave', cancelLongClick);
We set timeoutId to undefined in the short-click code as well. Otherwise, after short-clicking, an increase would trigger every time you mouse out of the button.
More buttons!
The code works now, but requires two global variables and is hard-coded for a specific button. Let's turn it into a general-purpose jQuery plugin*:
(($) => {
$.fn.repeatingClick = function (callback, delay = 500, interval = 200) {
return this.each(function () {
let intervalId;
let timeoutId;
function startLongClick (e) {
timeoutId = window.setTimeout(() => {
timeoutId = undefined;
callback.call($(this), e);
intervalId = window.setInterval(() => {
callback.call(this, e);
}, interval);
}, delay);
}
function cancelLongClick (e) {
window.clearInterval(intervalId);
if (timeoutId) {
callback.call(this, e);
window.clearTimeout(timeoutId);
timeoutId = undefined;
}
}
$(this).on('mousedown', startLongClick);
$(this).on('mouseup', cancelLongClick);
$(this).on('mouseleave', cancelLongClick);
});
}
})(jQuery);
function modifySlider (e) {
let modifier = Number($(this).data('change'));
$('progress').attr('value', Number($('progress').attr('value')) + modifier);
}
$('button').repeatingClick(modifySlider);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="dec" data-change="-1">−</button>
<progress value="25" max="50"></progress>
<button id="inc" data-change="1">+</button>
What's changed?
Replaced calls to increaseSlider() with a callback parameter and callback.call($(this), e). This way, any function can be used as the callback, and since we used arrow functions in the timeout, we're able to use Function.call with this to access the triggering element in the callback.
Parameterized the delays in the timeout and interval into delay and interval, for more general use.
Stuck the whole thing in a new jQuery function, $.repeatingClick(). Since jQuery objects can represent collections as well as individual elements, we wrap the original code in a call to $.each() to access each element individually. We also return the jQuery object in the usual style.
The rest is specific to this application: two buttons to modify the value of a (<progress>) 'slider', using custom data- attributes for the actual amounts so we can give both the same code.
*I've never written a jQuery plugin before; most of the code surrounding the core logic came straight from jquery-longpress, a jQuery plugin that does almost what OP wants.
Try using intervals instead of manually calculating time. Check this out:
var value = 0
var addval;
var press = false;
$('#button').on('mousedown', function (e) {
press = true;
increaseValue();
return false;
});
$('#button').on('mouseleave', function (e) {
clearInterval(addval);
return false;
});
$('#button').on('mouseenter', function(e) {
if (press)
increaseValue();
});
$('#button').on('mouseup', function (e) {
press = false;
clearInterval(addval);
return false;
});
function increaseValue() {
addval = setInterval(function(){
value++;
$("#counter").text(value);
}, 100);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="button">Press me</button>
<div id="counter">0</div>
You can adjust the speed by changing interval time.

jQuery Timeout Function not working

I am working on a currently working on a dropdown menu using jQuery. I have run into an issue where the Timeout function is not working at all. The code for it is:
$(document).ready(function() {
$('.has-sub').hover(
function() {
$('ul', this).stop(true, true).slideDown(500);
},
function() {
$('ul', this).stop(true, true).slideUp(400);
},
function() {
setTimeout(function() {
$('.has-sub').addClass("tap");
}, 2000);
},
function() {
$(this).removeClass("tap");
clearTimeout();
}
);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
What I trying to do is to create a hover delay for parent of the Dropdown. You would need to hover over the parent for 2 seconds for the Dropdown menu to appear. I also want to pair that with a Slidedown and Slideup effect.
The Slidedown and Slideup functions correctly but the Timeout does not work.
You can't just call clearTimeout() (which is not part of JQuery, by the way), you must provide it with an identifier for the timer you want to cancel.
Also, setTimeout() and clearTimeout() are not part of JQuery or JavaScript for that matter. They are methods of the window object, which is supplied by the browser. They are not part of the language (JavaScript) or the library (JQuery).
Additionally, the JQuery .hover() method takes 2 arguments and you are providing 4. I have combined them below, but not knowing exactly what you are trying to do, you may need to adjust that.
$(document).ready(function() {
// This will represent the unique ID of the timer
// It must be declared in a scope that is accessible
// to any code that will use it
var timerID = null;
$('.has-sub').hover(
function() {
// Clear any previously running timers, so
// we dont' wind up with multiples. If there aren't
// any, this code will do noting.
clearTimeout(timerID);
$('ul', this).stop(true, true).slideDown(500);
// Set the ID variable to the integer ID returned
// by setTimeout()
timerID = setTimeout(function() {
$('.has-sub').addClass("tap");
}, 2000);
},
function() {
$('ul', this).stop(true, true).slideUp(400);
$(this).removeClass("tap");
// Clear the particular timer based on its ID
clearTimeout(timerID);
}
);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>

Pause simple fader script on mouse-hover

I would like pause on hover when the mouse hovers over the fadelinks div for this script:
$(function(){
$('.fadelinks > :gt(0)').hide();
setInterval(function(){$('.fadelinks > :first-child').fadeOut().next().fadeIn().end().appendTo
('.fadelinks');}, 5000);
});
The html is along the lines of:
<div class="fadelinks">
<div>...</div>
<div>...</div>
</div>
I've tried a few things relating to interval to try and cram pause on hover functionality in there, but with my extremely limited jquery knowledge, everything I've tried breaks the script, leaving it stuck on the last slide or the first slide. Would just like this simple script to pause on mouse-hover and start up again on mouse-exit.
Here's a JSFiddle of the script in its natural state.
Try using .hover() , declaring variable to reference setInterval , using a function to call setInterval
$(function(){
// define `_interval` variable
var _interval;
// cache `.fadelinks` element
var elem = $(".fadelinks");
elem.find("> :gt(0)").hide();
elem.hover(function() {
// "pause" at `hover` of `.fadelinks`
clearInterval(_interval)
}, function() {
// "reset"
interval()
});
var interval = function() {
_interval = setInterval(function(){
elem.find("> :first-child")
.fadeOut().next().fadeIn().end()
.appendTo(elem);
}, 2000)
};
interval()
});
jsfiddle https://jsfiddle.net/ccmgdfog/4/
In your case, there wasn't the need for jQuery. Only with stopInterval you can control it. Altrough there is the jQuery $.stop() function, we wouldn't get the desired result.
I've changed a bit your code:
$(function(){
$('.fadelinks > :gt(0)').hide();
var interval = setInterval(intervalFunc, 2000);
$('.fadelinks').on('mouseenter',function(){
clearInterval(interval);
});
$('.fadelinks').on('mouseout',function(){
interval = setInterval(intervalFunc, 2000);
});
function intervalFunc(){
$('.fadelinks > :first-child').fadeOut().next().fadeIn().end().appendTo('.fadelinks');
}
});

Event listener DOMNodeInserted being run multiple times, why?

I'm trying to listen for a node with a certain class being added to the DOM dynamically. Once this Node has been added i want to then add an instance of of a plugin to this Node. The problem I'm having is DOMNodeInserted is running multiple times which is then running my plugin multiple on this one Node which is causing problems.
There is only ever one occurrence of this class on page.
Why is this and how can I stop this from happening?
$(document).ready(function(){
$('#editArea').live('DOMNodeInserted', '.class', function(e){
$('.class').plugin({
source: 'libs/ajax/somescript.php',
});
})
});
I ran into the same problem awhile back. What you need to do is debounce the function so it fires after the last DOMNodeInserted call.
Try this (adapted from John Hann's smartresize--comment/link left in):
(function ($, sr) {
// debouncing function from John Hann
// http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
var debounce = function (func, threshold, execAsap) {
var timeout;
return function debounced() {
var obj = this, args = arguments;
function delayed() {
if (!execAsap)
func.apply(obj, args);
timeout = null;
};
if (timeout) {clearTimeout(timeout);
} else if (execAsap) {func.apply(obj, args);}
timeout = setTimeout(delayed, threshold || 100);
};
}
jQuery.fn[sr] = function (fn) { return fn ? this.on('DOMNodeInserted', debounce(fn)) : this.trigger(sr); };
})(jQuery, 'debouncedDNI');
$(document).ready(function () {
$('#editArea').debouncedDNI(function () {
$('.class').plugin({
source: 'libs/ajax/somescript.php',
});
});
});
Probably because in your DOM whatever the element you're watching for has children elements. The event is fired once for the matching element (.class) and once for each descendant.
If your element you need to watch is something like a select with a bunch of option elements under it, a quick and dirty solution might be to watch for another "buddy" element you can put along with it in the DOM. For instance:
$(document).ready(function(){
$('#editArea').on('DOMNodeInserted', '#classbuddy', function(e){
$('.class').plugin({
source: 'libs/ajax/somescript.php',
});
})
});
Then in your markup you would just need to add something like an empty span element with id="classbuddy". Because that span would not have children elements, your code would fire only once and so .plugin() would be applied one time only.

setInterval is not working in YUI

I am trying to use SetInterval and clearInterval in YUI
The code is written so it will create element every second and on mouse hover of div it should stop creating element.
http://jsbin.com/awadek/5
Please let me know what is wrong with my code?
You should pass an anonymous function as a handler to "mouseover". Otherwise, Javascript will attempt to evaluate and call the return from clearInterval (in this case, an integer!). The following code will work:
YUI().use("console", "console-filters", "substitute", "node-event-simulate",
function(Y) {
console.log("YUI is ready");
var doSomething = function(e) {
Y.one("#seconds").append("<p>I am number four</p>");
};
IntervalId = setInterval(doSomething, 1000);
//Notice the anonymous function below:
Y.one("#clearInt").on('mouseover', function() { clearInterval( IntervalId ) });
});
Here is your JSBin, ftfy. Enjoy!

Categories

Resources