On my web page, I have a list of images. Currently, when the user hovers their mouse over any image for 3 seconds, a showUpdateImageDialog() method executes which causes a jQuery dialog to pop up. If the user moves their mouse away from the image at any point during the 3 seconds, the timer is reset and the jQuery dialog never displays:
HTML:
<ul class="imageGroup">
<li class="imageLi">
<img class="image" src="fizz/buzz/blah.jpg"/>
</li>
<li class="imageLi">
<img class="image" src="fizz/buzz/example.jpg"/>
</li>
...
</ul>
<div id="edit-image-description-frame" title="Update Image Description">
<div id="thumbnail-dialog-image-container">
<!-- How do I get the 'src' attribute to be the correct image file? -->
<img src="???"/>
</div>
</div>
JS:
$(".imageLi").live({
mouseenter:
function()
{
window.myTimeout = setTimeout(showUpdateImageDialog,3000);
},
mouseleave:
function()
{
clearTimeout(window.myTimeout);
}
});
function showUpdateImageDialog()
{
$('#edit-image-description-frame').dialog({
modal:true,
minHeight:500,
minWidhth:500
});
}
Unfortunately, this code behaves the same regardless of which image in the list the user is hovering over. I need a way for the jQuery dialog to display the specific image that the user is hovering over:
How can I pass the image's source to jQuery so that I can have the dialog present this image back to the user? This may seem strange, but the dialog will allow the user to edit metadata about the image and update that metadata. Because of other constraints, I need to use the image's src attribute to look up the metadata. Thanks in advance!
$(".imageLi").live({
mouseenter: function()
{
var src = $(this).children('img')[0].src;
window.myTimeout = setTimeout(function ()
{
showUpdateImageDialog(src);
},3000);
},
mouseleave: function()
{
clearTimeout(window.myTimeout);
}
});
function showUpdateImageDialog(src)
{
$('#thumbnail-dialog-image-container').children('img')[0].src = src;
$('#edit-image-description-frame').dialog({
modal:true,
minHeight:500,
minWidth:500
});
}
Pass it as a parameter to your function
$(".imageLi").live({
mouseenter:
function()
{
var element = $(this).find('img');
window.myTimeout = setTimeout(function(){showUpdateImageDialog(element);},3000);
},
mouseleave:
function()
{
clearTimeout(window.myTimeout);
}
});
function showUpdateImageDialog(image)
{
// do what you want with image variable
// it refers to the img element inside the li that was hovered
$('#edit-image-description-frame').dialog({
modal:true,
minHeight:500,
minWidhth:500
});
}
Related
I'm trying to assign two actions to a button in jQuery. The button is supposed to:
open a hidden div, and...
scroll down to get said div into view.
While both actions are working on the button, they currently require 2 clicks. On the first click the div appears, but to scroll it into view I need to click the button a second time.
Any suggestions how I am going wrong?
jQuery
$(document).ready(function () {
"use strict";
$('.footer a').click(function (event) {
event.preventDefault();
$('.impr-text').hide(); // hide previous popup div
var id = $(this).data("id"); // get the div id which to show
$('#' + id).fadeIn(function () { // show cuurent click link's popup
$(this).css({
'display': 'block'
});
});
$.scrollTo( '#impressum-footer', 800, {easing:'elasout'} );
});
});
HTML
<div id="impressum-footer">
<div class="footer">
<div class="inner-wrap-imp">
<ul class="impressum-links">
<li>Impressum</li>
<li>|</li>
<li>Datenschutz</li>
<li class="impressum-button" ></li>
</ul>
</div>
</div>
<div id="impr-text" class="impr-text">
<div class="inner-wrap"> ...
You need to put the scrollTo in the fadeIn completion callback handler. That way callTo is performed on completion of the fadeIn rather than, essentially, at the same time. Currently you seem to also be placing a callback function where another parameter is to go (either duration or options object depending on which method signature you are using). Not sure why you have the css change there at all.
Try something like this:
$(document).ready(function () {
"use strict";
$('.footer a').click(function (event) {
event.preventDefault();
$('.impr-text').hide(); // hide previous popup div
var id = $(this).data("id"); // get the div id which to show
$('#' + id).fadeIn({
duration: 100, // or whatever duration you want to use
complete: function() {
$.scrollTo( '#impressum-footer', 800, {easing:'elasout'} );
}
});
});
});
if you want to assign 2 different actions on one button, set it 2 different classes (or IDs), lets say
<div class="action1 action2">
After, in jQuery you will be able to do:
$('.action1').on('click', function (e) { console.log('#1'); ... });
$('.action2').on('click', function (e) { console.log('#2'); ... });
JsFiddle: http://jsfiddle.net/g2wdd2cb/
I have now managed to get it going. The approach as explained by #euvl was the one...
I changed my code (the scrolling part) after I realized it wasn't working. The final (working) code now looks like this:
jQuery:
$(document).ready(function () {
"use strict";
$('.footer-action-1 a').click(function (event) {
event.preventDefault();
$('.impr-text').hide(); // hide previous popup div
var id = $(this).data("id"); // get the div id which to show
$('#' + id).fadeIn(function () { // show cuurent click link's popup
$(this).css({
'display': 'block'
});
});
});
});
$(document).on('click','.footer-action-2 a', function(event) {
event.preventDefault();
var target = "#" + this.getAttribute('data-target');
$('html, body').animate({
scrollTop: $(target).offset().top
}, 2000);
});
HTML:
<div id="impressum-footer">
<div class="footer footer-action-1 footer-action-2">
<div class="inner-wrap-imp">
<ul class="impressum-links">
<li>Impressum</li>
<li>|</li>
<li>Datenschutz</li>
<li class="impressum-button" ></li>
</ul>
</div>
</div>
<div id="impr-text" class="impr-text">
<div class="inner-wrap">
The only problem now is that it scrolls a little too far. The moment I add an offset it stops working.
I'm trying to make a navigation using jQuery. I'm very new to jQuery so I'm getting a bit stuck here.
Basically what I'm trying to do is have testbutton2 appear and hide when I mouse over/off testbutton1. I was able to get this to work with mouseenter/leave.
The part I'm trying to add is to keep testbutton2 visible when I have the mouse over testbutton2 and to keep testbutton2 visible if I cursor back onto testbutton1 - so only fade in or out once.
You'll see from my code exactly what I encountered and probably have a chuckle.
CSS
#testbutton1 {
float:left;
height:100px;
width:100px;
background:#69C;
}
#testbutton2 {
float:left;
height:100px;
width:100px;
background:#0C6;
display:none;
}
HTML
<div id="testbutton1"></div>
<div id="testbutton2"></div>
jQuery
$("#testbutton1").on({
mouseenter: function() {
$("#testbutton2").fadeIn();
},
mouseleave: function() {
$("#testbutton2").fadeOut();
},
});
$("#testbutton2").on({
mouseenter: function() {
$("#testbutton2").fadeIn();
},
mouseleave: function() {
$("#testbutton2").fadeOut();
},
});
JSFiddle
DEMO
Or you can do it in pure css.
Wrap both buttons in a larger div and show the second button only while the mouse hovers over the larger div:
<div id="buttons">
<div id="testbutton1"></div>
<div id="testbutton2"></div>
</div>
#buttons:hover div {
display:block;
}
http://jsfiddle.net/r267b/1/
You can do something like
$("#testbutton1").on({
mouseenter: function () {
$("#testbutton2").fadeIn();
},
mouseleave: function () {
var $target = $("#testbutton2");
//delay the fade out to see whether the mouse is moved to the second button
var timer = setTimeout(function () {
$target.stop(true, true).fadeOut();
}, 200);
$target.data('hoverTimer', timer);
}
});
$("#testbutton2").on({
mouseenter: function () {
//if mouse is moved inside then clear the timer so that it will not get hidden
clearTimeout($(this).data('hoverTimer'));
$(this).stop(true, true).fadeIn();
},
mouseleave: function () {
$(this).stop(true, true).fadeOut();
}
});
Demo: Fiddle
This is solved with timers, as Arun P Johny said...
But as far as I saw, what you want to do is a menu.
Have you thought about using jQuery UI menu widget?
http://jqueryui.com/menu/
I suggest to use status variables that stores if you are hovering over button1 or over button2.
var isOver1 = false;
var isOver2 = false;
Then, add conditions to mouseleave and mouseenter in order to set hide or to alter the status variables, e.g.:
mouseleave: function() {
isOver1 = false;
window.setTimeout( function() {
if (!isOver2) {
isOver2 = false;
$("#testbutton2").fadeOut();
}
}, 50);
The timeout is necessary because if you leave testbutton1, you are not entering testbutton2 at exact the same time. So waiting a bit allows to fire the testbutton2 enter event.
Here is the full demo:
http://jsfiddle.net/KTULJ/2/
Leaving button1 to button2 keeps button2, leaving back to button1 still keeps button2, leaving any button towards the space around hides button2.
With this approach, you don't need to stop an animation as it doesn't start one if it is not necessary.
I'm having a tricky time with this code.
First, I have a series of images, each within an anchor.
a > img
a > img
a > img
The functionality I want is, when you roll your mouse over the image it dynamically adds 2 share buttons to the anchor:
a > .fb + .twitter + img
When you roll off they get removed.
The problem is, I also have a lightbox which binds to the a. That means when you click one of the share divs, it shows the share box properly, but it also triggers the lightbox.
I have tried everything to stop this... preventDefault(), stopPropagation() and return false. None of them stop the div click from bubbling to the anchor and triggering the lightbox.
First is my code for the rollovers. App.postImages is just a cached collection of jQuery image anchors. I use .add() to also add embedded video containers.
rolloverShares: {
divs: $('<div class="image-rollover rollover-facebook">Facebook</div><div class="image-rollover rollover-twitter">Twitter</div>'),
init: function() {
var _this = this;
App.postImages.add('.embed-container', '#content-wrapper').hover(
function() {
_this.divs.prependTo($(this)).show();
},
function() {
$('div', this).remove();
}
);
$(document).on('click', '.rollover-facebook', function() {
Social.facebook.popup();
return false;
});
$(document).on('click', '.rollover-twitter', function() {
Social.twitter.popup();
return false;
});
}
},
Here is my lightbox code. Nothing fancy. If it matters, the .on() in the block below makes it so you can click anywhere on the lightbox to close it, not just the image.
lightbox: function() {
if (isDesktop) {
App.postImages.nivoLightbox({
effect: 'fade',
theme: 'default',
keyboardNav: false,
clickOverlayToClose: true,
errorMessage: 'The requested image cannot be loaded. Please try again later.'
});
$(document).on('click', '.nivo-lightbox-image img', function() {
$(this).closest('.nivo-lightbox-overlay').find('.nivo-lightbox-close').click();
});
} else {
App.postImages.click(function(e) {
e.preventDefault();
});
}
},
Also I suppose i should put what's in App.postImages. It's just this:
$('a img', '#content-wrapper').not('.share-button img').parent().addClass('post-image')
I've tried to create a jQuery effect using fancy box to contain my content and within that is a large image with thumbnails below. What I was trying to make happen was when the thumbnails are clicked then the large image updates (see RACE Twelve image as an example). This works fine but the problem is when I go to another fancy box on my website (SEE RACE ONE box) then that image has been updated to be whatever thumbnail was clicked last.
I thought this might be event bubbling but preventing default hasn't helped.
I'm very new to jQuery and know that this is something stupid that I'm doing.
Any advice would be greatly appreciated? Thank you :)
Live version of page: http://www.goodwood.co.uk/members-meeting/the-races.aspx
jsfiddle for jQuery: http://jsfiddle.net/greenhulk01/JXqzL/
(function ($) {
$(document).ready(function () {
$('.races-thumbnail').live("click", function (e) {
$('.races-main-image').hide();
$('.races-image-wrap').css('background-image', "url('http://www.goodwood.co.uk/siteelements/images/structural/loaders/ajax-loader.gif')");
var i = $('<img />').attr('src', this.href).load(function () {
$('.races-main-image').attr('src', i.attr('src'));
$('.races-image-wrap').css('background-image', 'none');
$('.races-main-image').fadeIn();
});
return false;
e.preventDefault();
});
$(".races-image-wrap img").toggle(function () { //fired the first time
$(".races-pop-info").show();
$(this).animate({
width: "259px",
height: "349px"
});
}, function () { // fired the second time
$(".races-pop-info").hide();
$('.races-main-image').animate({
width: "720px",
height: "970px"
});
});
$('#fancybox-overlay, #fancybox-close').live("click", function () {
$(".races-pop-info").show();
$(".races-main-image").animate({
width: "259px",
height: "349px"
});
});
});
})(jQuery);
$('.races-main-image') will select all elements with that class, even the ones which aren't currently visible.
You can select the closest '.races-main-image' to the clicked element as per the code below (when placed inside the click event handler)
$('.races-main-image', $(e.target).closest('.races-fancy-box'))
So your new code should look like:
$('.races-thumbnail').live("click", function (e) {
var racesmainimage = $('.races-main-image', $(e.target).closest('.races-fancy-box'));
var racesimagewrap = $('.races-image-wrap', $(e.target).closest('.races-fancy-box'));
racesmainimage.hide();
racesimagewrap.css('background-image', "url('http://www.goodwood.co.uk/siteelements/images/structural/loaders/ajax-loader.gif')");
var i = $('<img />').attr('src', this.href).load(function () {
racesmainimage.attr('src', i.attr('src'));
racesimagewrap.css('background-image', 'none');
racesmainimage.fadeIn();
});
return false;
});
I've also removed your 'e.preventDefault();' return false; includes that, and was preventing e.preventDefault() from being executed in any case.
I am writing a really quick js module that opens up and image and fades out a container to show the image. The markup for the image is this below:
<div style="margin-bottom:1px;" class="rsNavItem rsThumb front">
<div class="rsTmb portfolio">
<img src="http://www.mysterium.ch/revelation/pictures/revelation_highres_06.jpg"/>
</div>
</div>
Now what happens is the click basically fades out a div and then shows the container.
loadSlide: function () {
console.log('clicked');
//$('.rsThumb').each(function () {
var containerT = $('.rsnav-container'),
containerB = containerT.find('.rsThumb');
$('.rsThumb').click(function (e) {
console.log('clicked again');
e.preventDefault();
var sliderObject = $('.collection #gallery-t-group').data('royalSlider');
var s = this;
// Lets make sure the body is activated
$('body').addClass('rsSlider-active');
$('.loader').show().transition({
opacity: 1
}, 100, 'easeInOutQuart');
// $('.socialbar-vertical-static').removeClass('activestate');
$('.body').transition({
opacity: 0
}, 100, 'easeInOutQuart');
// After slider loads
setTimeout(function () {
$('.body').transition({
opacity: 1
}, 500, function() {
$('.loader').transition({
opacity: 0
}, 500).hide();
});
theSliderActivated();
theSocialActivated();
sliderObject.updateSliderSize(true);
$('div#container').css('margin',0);
}, 1000);
});
//});
}
The script is also loaded in at the top like so:
init: function() {
var app = this;
this.fakingIt();
this.loadSlide();
this.unloadSlide();
this.mobileNav();
this.loadThumbs();
this.royalSlider();
this.thumbsSwitch();
this.functionResize();
this.theSocialActivated();
this.slideEventChange();
console.log('======> new.global.js');
}
For some reason it will not register the event at all and even with a console log after the click nothing registers at all.
Am I doing something really wrong here?
Make sure you are definitely calling init() from within a document ready event handler. This will ensure the rsThumb div is available when binding to its click event.
$(function(){
init();
});