I am trying to use JS/JQuery to make tiles that will fade out then fade in with different data (In this case it is pictures) when you over on it and then reverse it when you mouse off of it. Now my code works fine in Chrome but when I test it in FireFox it keeps executing the fade in/out commands. I looked up similar situations where people use the $(this).stop().fadeOut(function() code but since I am doing multiple fades and loading information it won't do the animation correctly. Does anyone know a solution to this?
<script>
$(document).ready(function()
{
var hov = false;
$(".previewBox").mouseenter(function()
{
if(hov === false)
{
hov = true;
$(this).fadeOut(function()
{
$(this).load(function()
{
$(this).fadeIn();
});
$(this).attr("src", "Images/Portfolio/Art_Bike_Flip.png");
});
};
});
$(".previewBox").mouseleave(function()
{
if(hov === true)
{
hov = false;
$(this).fadeOut(function()
{
$(this).load(function()
{
$(this).fadeIn();
});
$(this).attr("src", "Images/Portfolio/Art_Bike_Preview.png");
});
};
});
});
</script>`enter code here`
There are several problems here. First .load is not a reliable way to detect image loading. Some browsers, when the image is cached, wont fire a load event, so the script will fail. You need to use a plugin like waitForImages or imageLoaded.
https://github.com/alexanderdickson/waitForImages I recommend this one.
Also .stop() will work fine for your needs, if it seems to cancel fades in some instances, try .stop(true, true), it should animate just fine, even with loading data and multiple fades. You may need to tune it so that the stop command only is placed on the last fade to occur.
also you are making a ton of jQuery objects when you only need one. Limiting it to one object will make your script substantially more efficient.
var previewBox = $('.previewBox');
Then you can use that one everywhere:
previewBox.mouseenter(function()
{
if(hov === false)
{
hov = true;
previewBox.stop().fadeOut(function(){
previewBox.imagesLoaded(function...
In your case with the multiple instances using a class, you need to isolate your events from one another. You can do this with .each
$('.previewBox').each(function(){
var previewBox = $(this);
previewBox.mouseenter(function(){ ....
By wrapping all your current logic in a .each you will avoid interaction of events between elements. In this way the events mouseenter mouseleave and the attached logic will bind isolated to each instance of an element with that class, instead of binding to all elements of that class.
Related
I am trying to make a image preview containing of about 5-6 images which will appear one after another when user hovers over it (not like a carousel with prev and next buttons). Here is the fiddle consisting of what I gathered so far.. i don't know if this approach is right or not.. but I am stuck as the alert callback is not working. Could someone please tell me what is wrong?
$(function()
{
var imageCount = $('#product_grid_list').find('figure')[0].getElementsByTagName('img');
for (var i = 0, n = imageCount.length; i < n; i++) {
imageCount[i].on('click', function(e)
{
alert('Everything is going fine!');
}
);
}
}
);
The root cause of click event callback can't be triggered is that you're trying to register a event handler on a "DOM" (in this case: imageCount[i]) element in jQuery way. Try to register the event handler like this if you want to use pure javascript solution:
imageCount[i].addEventListener('click', function(e){
alert('Everything is going fine!');
});
Here is a jsfiddle demo.
Note: I didn't consider the cross browser issue in this case.
BTW, try to cache the length of imageCount node list, it will improve the performance.
You are using js AND jQuery at same time. It's wrong. If you use jQuery, than click event will be like this:
$(document).('click', '#product_grid_list figure img', function(){
alert('Everything is going fine!');
});
You are using a mix of jQuery and standalone javascript. You might as well go all the way to jQuery, with something like:
$('#product_grid_list figure:first img').click(function(e) {
alert('Everything is going fine, hopefully!');
});
You did not send the corresponding HTML, so we cannot test whether the above is correct.
it's just a simple click event in jQuery, no need to use js: http://jsfiddle.net/wP3QQ/11/
$('#product_grid_list').find('figure img').click(function(e){
alert('Everything is going fine!');
e.preventDefault();
});
You want the hover effect, so click event should not be used over here. It should be mouseover.
Working Fiddle
Code Snippet:
$(document).on('mouseover','#product_grid_list figure img',function(e){
alert("now it is working");
});
You are attempting to call on(), a jQuery method, on an HTMLElement (a DOM element). You can't do that, jQuery methods can only be called on jQuery collections. It's easy to get a jQuery collection for the elements you desire:
Use .find() to match the images
There's no need for a for() loop, jQuery's .on() will handle looping for you.
You may also want to prevent the default behaviour of your anchors
$(function () {
var imageCount = $('#product_grid_list').find('figure img');
imageCount.on('click', function (e) {
e.preventDefault()
alert('Everything is going fine!');
})
});
JSFiddle
I have a slideshow that i replace an unordered list within the slide show, the images change but any effects are not inherited. this is the script that introduces a new DOM:
jQuery("#kwick1").click(function () {
jQuery('#photography').load('/design.html #photography');
});
jQuery("#kwick2").click(function () {
jQuery('#photography').load('/design.html #design');
});
how do i get the jQuery slideshow to inherit this new list of images??
i both these functions and the slide show function in the same file.
I have a
jQuery(document).ready(function() {
that loads the slideshow script.
You have to let us know what slideshow plugin you are using. Regardless, you probably just need to destroy your old slideshow instance and restart it. Something like:
//start slideshow on
var slideshow = $('#slideshow').cycle();
slideshow.start();
$('#button').click( function() {
//depending on plugin api maybe stop, add and start again
slideshow.stop();
slideshow.addImages();
slideshow.start();
//or perhaps just destroy old slideshow and restart
slideshpw = $('#slideshow').cycle();
});
To attach events to newly added elements you should use live() or delegate();
jQuery('.yourselector').live('click', function(){
//do something on click
});
Instead of attaching events to each of elements, you should learn how to use event delegation. That way you can attach single event listener on some container ( or even document ) and catch the events as they bubble up.
Additionally it will make your code look much cleaner and easier to understand.
http://lab.distilldesign.com/event-delegation/
http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-javascript-event-delegation-in-4-minutes/
http://www.sitepoint.com/javascript-event-delegation-is-easier-than-you-think/
P.S. , if you put your code at the bottom of the HTML ( before </body> ) then, when it triggers , it will already be an "onDomReady" event.
Is there a way to check if jQuery fired the page load events yet, or do you have to roll your own? I need to alter the behavior of links, but I don't want to wait until the page finishes loading because the user could conceivably click on a link on, say, the top half of the page before the page finishes loading. Right now I'm doing it like this:
var pageLoaded = false;
$(function() {
pageLoaded = true;
});
function changeLinks() {
$("a[data-set-already!='true']").each(function() {
$(this).attr("data-set-already", "true").click(...);
});
// Is there something along the lines of jQuery.pageWasLoaded that I can
// use instead?
if (!pageLoaded) {
window.setTimeout(changeLinks, 100);
}
}
changeLinks(); // Added per #jondavidjohn's question
Since you are using the document ready shorthand, I'm guessing you mean when the dom is loaded. For this:
$.isReady
You could use setInterval and clear the interval on domready:
var changeLinksInterval = setInterval(function () {
$("a[data-set-already!='true']").each(function() {
$(this).attr("data-set-already", "true").click(...);
});
}, 100);
$(function () {
clearInterval(changeLinksInterval);
});
By the way, in your code example, you shouldn't need .each() - you should be able to call .attr() and .click() directly and let jQuery do the looping. Unless there is more to your .each() code that you didn't post.
$("a[data-set-already!='true']").attr("data-set-already", "true").click(...);
you could use .live() to initiate a click event that needs additional work when binding.
$("a[data-set-already!='true']").live(function(){
// since this event will only fire once per anchor tag, you
// can safely bind click events within it without worrying
// about getting duplicate bound click events.
var $this = $(this);
$this
.data("dataSetAlready",true)
.click(myClickHandler);
});
this is also a useful technique for late-initializing plugins on elements that may not exist at domReady.
I have to display two images for single mouseover. So when I mouseover to the image, first, the image is displayed then with a time delay of 5000, the image is needed to display for that same hover. Now on mouseout display the original image.
I am not so familiar with JavaScript and jQuery.
Can someone please give me some idea about how to do this.
What i did is,
$('.image1').mouseover(function() {
setInterval($(this).removeClass(.image1).addClass('image-over1'),5000);
$(this).removeClass(.image1).addClass('image-over2');
});
$('.image1').mouseout(function() {
$(this).removeClass('image-over1');
$(this).removeClass('image-over2').addClass(item);
});
$('.image1').click(function(){
document.location='index.php?page='index.php';
})
The .hover() function lets you specify both mouseover/mouseout at the same time, and you need to make a function for the setInterval:
$('.image1').hover(function(evt) {
// mouse over function.
// DOM Element that got the mouseover.
var target = evt.target;
if (target.timer) {
clearTimeout(target.timer);
target.timer = null;
}
target.timer = setInterval(function() {
// $(this) will not work here, since 'this' has changed.
// depending on your css you shouldn't need to remove the '.image1'
// class, just make sure .image-over1 and .image-over2 are
// stronger selectors, or occur after .image1
$('.image1').addClass('image-over2');
// at this point your element will be (just guessing <img>, could be
// anything really:
// <img class="image1 image-over1 image-over2" .../>
// it's absolutely fine for the image to have all those classes as
// long as your css is correct.
}, 5000);
$('.image1').addClass('image-over1');
}, function(evt) {
// mouse out function.
// DOM Element that got the mouseout.
var target = evt.target;
if (target.timer) {
clearTimeout(target.timer);
target.timer = null;
}
$('.image1').removeClass('image-over1');
$('.image1').removeClass('image-over2');
});
$('.image1').click(function(){ document.location='index.php?page='index.php'; })
First of all, I think there's a problem in your approach; if you remove the "image1" class from the element on a mouseover, then that element won't be matched by the $(".image1") selector for the mouseout. Is there a reason you need to remove it? If you do (i.e. if there is something defined on the class in the CSS that you need to disable), is there some other selector you could match on?
As to the time delay, if you're using a jQuery version greater than 1.4, you can use the .delay() function:
$('.image1').mouseover(function() {
$(this).addClass('image-over1').delay(5000).addClass('image-over2');
});
Perhaps you to create an animated GIF of these images??? Then use a code similar to here: http://www.netmechanic.com/news/vol3/design_no10.htm
Even if the images are generated on fly, it is possible to programtically generate animated gif in PHP - see http://php.net/manual/en/function.imagegif.php
I have a timed event I want to behave differently accordingly to what HTML element the mouse pointer is on.
Is there a way, assuming I have the HTML element, to know if the mouse pointer is currently on top of it.
I am well aware of the onmouseover/onmouseout events and how to use them.
I am using JQuery.
I am obviously looking for some kind of flag, as I need to check a state and not handle an event.
again, I know how to implement this with events.
I'm not aware of any built-in way to ping an element for the status of mouse hovering.
However, you can create one by updating a flag at mouseenter and mouseleave -- which is where Brian Driscoll's suggestion of .hover comes in:
jQuery.fn.tracking = function () {
this.data('hovering', false);
this.hover(function () {
$(this).data('hovering', true);
}, function () {
$(this).data('hovering', false);
});
return this;
};
jQuery.fn.hovering = function () {
return this.data('hovering');
}
You'll need to initialize tracking for each element you care about:
$('#elem1,#elem2').tracking();
But then you can get the status of any of them:
if ($('#elem1').hovering()) {
// ...
} else if ($('#elem2').hovering()) {
// ...
}
Demo: http://jsbin.com/amaxu3/edit
Have you looked into jQuery.hover()? http://api.jquery.com/hover/
You need to give name to html andme and on mouseover you need to check document.getelementsbyName. Then check what your are getting as output. Now you can take decision is it html control or asp.net.
When you use collObjects = object.getElementsByName("htmlcontrol") then compare id of both.
1 morething why you needed to check this in javascript. there may be some other solution for that. Just share with us.
You might have some luck with document.elementFromPoint, although I believe there are some inconsistencies in older browser implementations (http://www.quirksmode.org/dom/w3c_cssom.html#documentview).
$('#elem').mousemove(function(e){
if (this == document.elementFromPoint(e.clientX, e.clientY)) {
// Do stuff
}
});
Or outside of a handler
if ($('#elem').get(0) == document.elementFromPoint(x, y)) {
// Do stuff
}
Aside from that, the only other option that comes to mind is using event handlers to keep track of which element the mouse is over.