Mouseover and Mouseout do not work when onload process is proceeded - javascript

I have a mouseover event and a mouseout event that shows and hide images...
It works fine as long as the image is fully cached/loaded.
If I go over the image and leave the specific div (where mouseover and mouseout should trigger) fast during the load process, the mouseout event do not trigger and the image is always displayed until than (only if I reenter and leave with the cached image it works correctly). I guess that jquery is stuck in the onload process of the image and do not recognize the mouseout event. Is there any fix?
$(document).on('mouseover',".divclass", { ....
loadImage(urllink);
function loadImage(src) {
var image = new Image();
image.onload = function() {
if ('naturalHeight' in this) {
if (this.naturalHeight + this.naturalWidth === 0) {
this.onerror();
return;
}
} else if (this.width + this.height == 0) {
this.onerror();
return;
}
// At this point, there's no error. Picture is available:
$('#picture').attr('src', urllink);
$(".image-content").stop().fadeIn(200);
};
image.onerror = function() {
//display noimg.png
$('#picture').attr('src', ".../noimg.png");
$(".image-content").stop().fadeIn(200);
};
image.src = src;
}
...
});
$(document).on('mouseout',".divclass", function (e) {
$('.image-content').css("display", "none");
});
Exact the same bug happens when using mouseenter/mouseleave.

just in case someone has the same problem ...
I could not eraze the bug because jquery seems to skip the mouseout/mouseleave event when .onload for the image is going on. Furthermore a fast mouse movement increases the error rate.
I just did a small workaround:
$(document).on('mousemove', function (e) {
if ($(e.target).attr("class") !== "classname") {
$('.image-content').stop();
$('.image-content').css("display", "none");
e.stopPropagation();
} else { return; }
});
that do the trick ...

Related

jQuery change button image not working

Just learning jQuery and am using it to change the background image on a button triggered by a mouseover event. All of the console output fires at the correct times, but my image never changes. No errors are thrown. What am I doing wrong?
In the <head> element, I have this preloading script:
function preloader() {
if (document.images) {
console.log("preloading images");
contact_green = new Image();
contact_green.src = "http://www.xxxx.com/images/contact_green.png";
}
}
function addLoadEvent(func) {
var oldonload = window.onload;
if (typeof window.onload != 'function') {
window.onload = func;
} else {
window.onload = function() {
if (oldonload) {
oldonload();
}
func();
}
}
}
addLoadEvent(preloader);
That seems to work fine, in the sense that I get the output "preloading images". Not sure that it has the correct scope, however.
Then, in the <body> element, I have this button defined:
<td>
<button id='contact' class='CXIII' onclick="btnContact()">
<img id="logo" src="images/contact_blue.png">
</button>
</td>
Finally, I have a script that is supposed to change the image on this button upon a mouseover event:
<script>
function showHover(img) {
console.log("show hover");
if (img) img.src = contact_green;;
}
$("#contact").hover(
function () {
console.log("mouse in");
showHover(this);
},
function () {
console.log("mouse out");
}
);
</script>
I get the console output, but the image doesn't change. There are no errors thrown, either.
You are setting an object, not the source of the image
img.src = contact_green;;
needs to be
img.src = contact_green.src;
And you are not setting the image, but the button.
showHover(this);
needs to be
showHover($(this).find("img")[0]);
and since you are using jQuery
$(window).load(preloader);

Run function, disable scroll, but enable on callback

I want to make a infinite scroll page, but I have a problem.
My loadElements works with $.get, like this:
loadElements: function() {
// fades out page
$.get(//..).done(function() {// fades in page});
}
And scrolling:
$(window).scroll(function() {
Functions.loadElements();
});
What I want is to run Functions.loadElements(); once on scroll, wait for the // fades in page, then reenable scrolling again. I tried bind/unbind, but with no success. How can I achieve this?
EDIT:
I tried using bind and unbind like this:
$(window).scroll(function() {
Functions.loadElements();
$(window).unbind('scroll');
}
and in loadElements:
loadElements: function() {
// fades out page
$.get(//..).done(function() {// fades in page; $(window).bind('scroll'); });
}
But it didn't work.
I can't give you a solution exactly. but try something like this. You can maintain a status with a globle variable.
var isLoading = false;
$(window).scroll(function(e) {
if( !isLoading )
{
Functions.loadElements();
isLoading = true;
}
e.preventDefault();
}
loadElements: function() {
// fades out page
$.get(//..).done(function() {// fades in page; isLoading = false; });
}
Maybe instead of rebinding the scroll function that contains the logic, try binding a function that "disables" scrolling and then remove this function once your content is ready to scroll again. You could use jquery namespace events for this
Try with
$(window).scroll(function() {
Functions.loadElements();
$(window).bind('scroll.StopScroll', function (e) {
e.preventDefault(); e.stopImmediatePropagation();
});
}
And then in the .done unbind it
$(window).unbind('scroll.StopScroll');
I'd do it with the get promise
var waiting;
$(window).scroll(function(e) {
if(waiting){
e.preventDefault();
return;
}
Functions.loadElements().then(function(){
waiting = false;
});
waiting = true;
});
and return the get promise from loadElements
loadElements: function() {
// fades out page
return $.get(...).done(function() {...});
}

Height check on resize causing lag

I'm using the below jquery to check and reset the height of my div on resize. However, there is a terrible freeze/lag when using the below code. The structure is just three absolutely positioned divs. One at the top, one at the bottom, and one in the middle. Any idea why this might be happening?
$(window).resize(function () {
if ($("#master_bodywrapper_div").height() < 500) {
$("#master_bodywrapper_div").height(500);
}
else {
$("#master_bodywrapper_div").height("auto");
}
});
This is because, on some browsers, the resize event can fire dozens of times per second. You should have a resizing function that is called only after the window is done being resized, like so:
(function($) {
var resizeTimer = false;
function doResize() {
if ($("#master_bodywrapper_div").height() < 500) {
$("#master_bodywrapper_div").height(500);
}
else {
$("#master_bodywrapper_div").height("auto");
}
resizeTimer = false;
}
$(window).on("resize", function() {
if (resizeTimer) {
clearTimeout(resizeTimer);
}
resizeTimer = setTimeout(doResize, 300);
});
})(jQuery);
Hope this helps!
Well, it is querying the DOM twice every time resize is triggered and this function called, which might be the source (DOM querying can be expensive). Note that resize is triggered a lot even if you simply grab the edge and move your mouse (with a moderate speed) 200px to one side. Try moving the $("#master_bodywrapper_div") query to above the resize callback, cached in a var, and then use that var reference in your callback function.
var div = $("#master_bodywrapper_div");
$(window).resize(function () {
if (div.height() < 500) {
div.height(500);
}
else {
div.height("auto");
}
});

Why jQuery doing unwanted multiple actions of single command?

When i resize browser the it gives multiple alerts. I used "return false" not working.
If I used unbind()/unbind('resize') then it works but it creates an other problem- the resize() function stops working from second time browser/window resize.
My code-
<script src="jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(e) {
alert($(".myclass").parent().width());
$(window).bind('resize',function() {
alert($(".myclass").parent().width());
});
});
</script>
<section class="myclass"></section>
This is not an issue with jQuery, but on the browser's implementation of resize.
Depending which browser you use it may trigger intermediate resizes, or a resize when your mouse is released only.
Because the resize triggers everytime the browser changes.
If you are resizing 100 pixels it can trigger up to 100 times.
Something like this should work and trigger only once you stopped resizing the window:
var resizing = false, stopedResizing = true;
$(window).bind('resize',function() {
if(!resizing){
console.log("started resizing. Width = " + $(".myclass").parent().width());
resizing = true;
}
stopedResizing = false;
setTimeout(function(){
if(!stopedResizing){
stopedResizing = true;
setTimeout(function(){
if(stopedResizing && resizing){
resizing = false;
console.log('Stoped resizing. Width = ' + $(".myclass").parent().width());
}
}, 500);
}
}, 500);
});
You could do something like:
$(document).ready(function(e) {
alert($(".myclass").parent().width());
var lastTime = 0;
$(window).bind('resize',function() {
var currentTime = new Date().time();
if(currentTime > lastTime + 5000)
alert($(".myclass").parent().width());
lastTime = currentTime;
});
});
...so that it will only fire on resizes at least 5 seconds apart. Normally though, you'd want to act when resizing stops, not when it starts.
This code fires ones on mouseover of the window after the a resize event as occurred.
$(document).ready(function() {
var windowResized = false;
function callFunction() {
console.log("I am called once after window resize");
}
$(window).mouseover(function() {
if (windowResized == true) {
callFunction();
windowResized = false;
}
})
$(window).resize(function() {
windowResized = true;
});
})

JavaScript image at onload event

I am trying to load a new image every time the previously loaded image has finished loading.
The function create_photo_list works correctly. It creates an array of the photos that need to be loaded. If none need to be loaded then the array is empty. The problem is, when there are no more items to load the it keeps calling the load_next_photo function.
The reason I call the registerEventHandler every time in the function is because if I don't, the function is not called when the next photo loads.
function registerEventHandler(node, event, handler) {
if (typeof node.addEventListener == "function")
node.addEventListener(event, handler, false);
else
node.attachEvent("on" + event, handler);
}
// Remove an HTML element event handler such as onclick
// ex: unregisterEventHandler($("textfield"), "keypress", showEvent);
function unregisterEventHandler(node, event, handler) {
if (typeof node.removeEventListener == "function")
node.removeEventListener(event, handler, false);
else
node.detachEvent("on" + event, handler);
}
function load_next_photo() {
var loading_list = create_photo_list();
alert(loading_list.length);
if (loading_list.length > 0) {
img[loading_list[0]]['loaded'] = 1;
registerEventHandler($("load_img"), "onload", load_next_photo());
$("load_img").src = img[loading_list[0]]['img'];
}
else {
alert("nothing");
unregisterEventHandler($("load_img"), "onload", load_next_photo())
}
unregisterEventHandler($("load_img"), "onload", load_next_photo())
}
Can't get my head around what you currently have, but such code works just fine:
var _images = ["image1.jpg", "image2.jpg", "image3.jpg"];
var _index = 0;
window.onload = function() {
LoadImage();
};
function LoadImage() {
//stop condition:
if (_index >= _images.length)
return false;
var url = _images[_index];
var img = new Image();
img.src = url;
img.onload = function() {
_index++;
LoadImage();
};
document.getElementById("Container").appendChild(img);
}
This will add the images to the container (element with ID Container) one by one, live test case: http://jsfiddle.net/yahavbr/vkQQ7/
This is plain JS, feel free to ask about any part for elaboration. :)

Categories

Resources