Again, I am working with code from my predecessor and am at a loss for this one. It appears to be a sampled navigation script. It is receiving an error in IE stating Object doesn't support this property or method. Here is what I have narrowed the error down to.
The function:
/**
* hoverIntent r5 // 2007.03.27 // jQuery 1.1.2+
* <http://cherne.net/brian/resources/jquery.hoverIntent.html>
*
* #param f onMouseOver function || An object with configuration options
* #param g onMouseOut function || Nothing (use configuration options object)
* #author Brian Cherne <brian#cherne.net>
*/
(function($){$.fn.hoverIntent=function(f,g){var cfg={sensitivity:7,interval:100,timeout:0};
cfg=$.extend(cfg,g?{over:f,out:g}:f);
var cX,cY,pX,pY;
var track=function(ev){cX=ev.pageX;
cY=ev.pageY;
};
var compare=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);
if((Math.abs(pX-cX)+Math.abs(pY-cY))<cfg.sensitivity){$(ob).unbind("mousemove",track);
ob.hoverIntent_s=1;
return cfg.over.apply(ob,[ev]);
}else{pX=cX;
pY=cY;
ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);
},cfg.interval);
}};
var delay=function(ev,ob){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);
ob.hoverIntent_s=0;
return cfg.out.apply(ob,[ev]);
};
var handleHover=function(e){var p=(e.type=="mouseover"?e.fromElement:e.toElement)||e.relatedTarget;
while(p&&p!=this){try{p=p.parentNode;
}catch(e){p=this;
}}if(p==this){return false;
}var ev=jQuery.extend({},e);
var ob=this;
if(ob.hoverIntent_t){ob.hoverIntent_t=clearTimeout(ob.hoverIntent_t);
}if(e.type=="mouseover"){pX=ev.pageX;
pY=ev.pageY;
$(ob).bind("mousemove",track);
if(ob.hoverIntent_s!=1){ob.hoverIntent_t=setTimeout(function(){compare(ev,ob);
},cfg.interval);
}}else{$(ob).unbind("mousemove",track);
if(ob.hoverIntent_s==1){ob.hoverIntent_t=setTimeout(function(){delay(ev,ob);
},cfg.timeout);
}}};
return this.mouseover(handleHover).mouseout(handleHover);
};
})(jQuery);
The document.ready line triggering the error:
var config = {
sensitivity: 1, // number = sensitivity threshold (must be 1 or higher)
interval: 50, // number = milliseconds for onMouseOver polling interval
over: megaHoverOver, // function = onMouseOver callback (REQUIRED)
timeout: 200, // number = milliseconds delay before onMouseOut
out: megaHoverOut // function = onMouseOut callback (REQUIRED)
};
$("ul#topnav li .sub").css({'opacity':'0'});
$("ul#topnav li").hoverIntent(config);
I am at a loss as to how to resolve this and finally get this section fixed.
The two functions that are defined within document.ready.
function megaHoverOver(){
$(this).find(".sub").stop().fadeTo('fast', 1).show();
//Calculate width of all ul's
(function($) {
jQuery.fn.calcSubWidth = function() {
rowWidth = 0;
//Calculate row
$(this).find("ul").each(function() {
rowWidth += $(this).width();
});
};
})(jQuery);
if ( $(this).find(".row").length > 0 ) { //If row exists...
var biggestRow = 0;
//Calculate each row
$(this).find(".row").each(function() {
$(this).calcSubWidth();
//Find biggest row
if(rowWidth > biggestRow) {
biggestRow = rowWidth;
}
});
//Set width
$(this).find(".sub").css({'width' :biggestRow});
$(this).find(".row:last").css({'margin':'0'});
} else { //If row does not exist...
$(this).calcSubWidth();
//Set Width
$(this).find(".sub").css({'width' : rowWidth});
}
}
function megaHoverOut(){
$(this).find(".sub").stop().fadeTo('fast', 0, function() {
$(this).hide();
});
}
I'm able to run that code without errors (see http://jsfiddle.net/veHEY/). It looks like the issue might be in the megaHoverOver and megaHoverOut functions that you're passing in through the configuration object. Do you have the code for those functions?
Previously:
The problem is almost certainly
opacity, which is not supported in
IE. Check out this nice quirksmode
article on cross-browser opacity
issues.
Correction: As #patrick rightly points out, and backs up with a source code reference to boot, jQuery is smart enough to automatically deal with IE's own special brands of opacity handling. Whatever the OP's problem is, this is not the answer.
Related
i made a function that change the opacity of an element, but you know it is not working, Following is my code:
function _opacity(ele, opacity,addOpac , delay ){
ele = document.getElementById(ele);
var CurrentOpacity = ele.style.opacity,
ChangeInOpacity = setInterval(function(){
if (CurrentOpacity > opacity ) { decrease();};
if (CurrentOpacity < opacity) { increase();};
if (CurrentOpacity == opacity) { stopInc();};
}, delay),
increase = function(){
ele.style.opacity = CurrentOpacity;
CurrentOpacity = CurrentOpacity+addOpac;
},
decrease =function(){
ele.style.opacity = CurrentOpacity;
CurrentOpacity = CurrentOpacity-addOpac;
},
stopInc = function(){
clearInterval(ChangeInOpacity);
};
}
one of the foremost feature of this function is that is doesn't uses any loop.
this ideology of using setInterval works perfectly in changing the width and height of element. But here this function is not functioning.
What i know is that it is not adding any style attribute to the element which is passed to the above function
what is the mistake here because of which this is not working?
thanks in advance.
There are a few problems there:
To get the current opacity of the element, you need to use the getComputedStyle function (or currentStyle property on oldIE), not .style.opacity. The latter only has a value if it's been assigned explicitly, rather than implicitly through style sheets.
The value will be a string, so you need to convert it to a number.
It's unlikely that you'll exactly match the target opaccity, so you need to just stop when you cross the target.
You don't put ; at the end of if statements, so remove those.
You assign the opacity, but then increment it, and then later the incremented value is what you check to see if you're done, so even if it weren't for #3, you'd stop early.
In JavaScript, the overwhelming convention is to start local variable names with a lower-case letter. I changed the name of your timer handle to timer.
Your best bet is to figure out what direction you're going, then stop when you pass the target:
// Polyfill getComputedStyle for old IE
if (!window.getComputedStyle) {
window.getComputedStyle = function(element) {
return element.currentStyle;
}
}
// Your _opacity function
function _opacity(ele, opacity, addOpac, delay) {
var direction;
ele = document.getElementById(ele);
// Determine direction
direction = +getComputedStyle(ele).opacity < opacity ? 1 : -1;
var timer = setInterval(function() {
// Get the *computed* opacity
var current = +getComputedStyle(ele).opacity;
if (direction > 0) {
if (current < opacity) {
increase(current);
} else {
stopInc();
}
}
else {
if (current > opacity) {
decrease(current);
} else {
stopInc();
}
}
}, delay),
increase = function(current) {
// Increase, but don't go past target
ele.style.opacity = Math.min(current + addOpac, opacity);
},
decrease = function(current) {
// Decrease, but don't go past target
ele.style.opacity = Math.max(current - addOpac, opacity);
},
stopInc = function() {
clearInterval(timer);
};
};
// Run
_opacity("target", 0.3, 0.05, 50);
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
<div id="target">this is the element</div>
you can do this:
ele.style.opacity = "0.2";// some desired value but string if for all browsers.
for more info see this post:Setting opacity of html elements in different browsers
A documented restriction with document and sheet add-ons is that Apps Script cannot tell what a user does outside of the add-on. This tantalizing tip is given:
It is possible to poll for changes in a file's contents from a
sidebar's client-side code, although you'll always have a slight
delay. That technique can also alert your script to changes in the
user's selected cells (in Sheets) and cursor or selection (in Docs).
Sadly, this isn't shown in any of the demo code. How can I do it?
The polling is done from the html code in your add-on's User Interface, calling across to server-side Apps Script functions using google.script.run.
Using jQuery simplifies this, and we can even start with the answers from jQuery, simple polling example.
function doPoll(){
$.post('ajax/test.html', function(data) {
alert(data); // process results here
setTimeout(doPoll,5000);
});
}
The basic idea can work for Google Apps Script, if we replace the ajax calls with the GAS equivalents.
Here's the skeleton of the poll function that you would use in your html file:
/**
* On document load, assign click handlers to button(s), add
* elements that should start hidden (avoids "flashing"), and
* start polling for document updates.
*/
$(function() {
// assign click handler(s)
// Add elements that should start hidden
// Start polling for updates
poll();
});
/**
* Poll a server-side function 'serverFunction' at the given interval
* and update DOM elements with results.
*
* #param {Number} interval (optional) Time in ms between polls.
* Default is 2s (2000ms)
*/
function poll(interval){
interval = interval || 2000;
setTimeout(function(){
google.script.run
.withSuccessHandler(
function(results) {
$('#some-element').updateWith(results);
//Setup the next poll recursively
poll(interval);
})
.withFailureHandler(
function(msg, element) {
showError(msg, $('#button-bar'));
element.disabled = false;
})
.serverFunction();
}, interval);
};
Add-on Example, Document Poller
This is a demonstration of the jQuery polling technique calling server-side Google Apps Script functions to detect user behavior in a Google Document. It does nothing useful, but it showcases a few things that would typically require knowledge of the user's activity and state of the document, for instance context-sensitve control over a button.
The same principle could apply to a spreadsheet, or a stand-alone GAS Web Application.
Like the UI App example in this question, this technique could be used to get around execution time limits, for operations with a User Interface at least.
The code builds upon the example add-on from Google's 5-minute quickstart. Follow the instructions from that guide, using the code below instead of that in the quickstart.
Code.gs
/**
* Creates a menu entry in the Google Docs UI when the document is opened.
*
* #param {object} e The event parameter for a simple onOpen trigger. To
* determine which authorization mode (ScriptApp.AuthMode) the trigger is
* running in, inspect e.authMode.
*/
function onOpen(e) {
DocumentApp.getUi().createAddonMenu()
.addItem('Start', 'showSidebar')
.addToUi();
}
/**
* Runs when the add-on is installed.
*
* #param {object} e The event parameter for a simple onInstall trigger. To
* determine which authorization mode (ScriptApp.AuthMode) the trigger is
* running in, inspect e.authMode. (In practice, onInstall triggers always
* run in AuthMode.FULL, but onOpen triggers may be AuthMode.LIMITED or
* AuthMode.NONE.)
*/
function onInstall(e) {
onOpen(e);
}
/**
* Opens a sidebar in the document containing the add-on's user interface.
*/
function showSidebar() {
var ui = HtmlService.createHtmlOutputFromFile('Sidebar')
.setTitle('Document Poller');
DocumentApp.getUi().showSidebar(ui);
}
/**
* Check if there is a current text selection.
*
* #return {boolean} 'true' if any document text is selected
*/
function checkSelection() {
return {isSelection : !!(DocumentApp.getActiveDocument().getSelection()),
cursorWord : getCursorWord()};
}
/**
* Gets the text the user has selected. If there is no selection,
* this function displays an error message.
*
* #return {Array.<string>} The selected text.
*/
function getSelectedText() {
var selection = DocumentApp.getActiveDocument().getSelection();
if (selection) {
var text = [];
var elements = selection.getSelectedElements();
for (var i = 0; i < elements.length; i++) {
if (elements[i].isPartial()) {
var element = elements[i].getElement().asText();
var startIndex = elements[i].getStartOffset();
var endIndex = elements[i].getEndOffsetInclusive();
text.push(element.getText().substring(startIndex, endIndex + 1));
} else {
var element = elements[i].getElement();
// Only translate elements that can be edited as text; skip images and
// other non-text elements.
if (element.editAsText) {
var elementText = element.asText().getText();
// This check is necessary to exclude images, which return a blank
// text element.
if (elementText != '') {
text.push(elementText);
}
}
}
}
if (text.length == 0) {
throw 'Please select some text.';
}
return text;
} else {
throw 'Please select some text.';
}
}
/**
* Returns the word at the current cursor location in the document.
*
* #return {string} The word at cursor location.
*/
function getCursorWord() {
var cursor = DocumentApp.getActiveDocument().getCursor();
var word = "<selection>";
if (cursor) {
var offset = cursor.getSurroundingTextOffset();
var text = cursor.getSurroundingText().getText();
word = getWordAt(text,offset);
if (word == "") word = "<whitespace>";
}
return word;
}
/**
* Returns the word at the index 'pos' in 'str'.
* From https://stackoverflow.com/questions/5173316/finding-the-word-at-a-position-in-javascript/5174867#5174867
*/
function getWordAt(str, pos) {
// Perform type conversions.
str = String(str);
pos = Number(pos) >>> 0;
// Search for the word's beginning and end.
var left = str.slice(0, pos + 1).search(/\S+$/),
right = str.slice(pos).search(/\s/);
// The last word in the string is a special case.
if (right < 0) {
return str.slice(left);
}
// Return the word, using the located bounds to extract it from the string.
return str.slice(left, right + pos);
}
Sidebar.html
<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css">
<!-- The CSS package above applies Google styling to buttons and other elements. -->
<div class="sidebar branding-below">
<form>
<div class="block" id="button-bar">
<button class="blue" id="get-selection" disabled="disable">Get selection</button>
</div>
</form>
</div>
<div class="sidebar bottom">
<img alt="Add-on logo" class="logo" height="27"
id="logo"
src="https://www.gravatar.com/avatar/adad1d8ad010a76a83574b1fff4caa46?s=128&d=identicon&r=PG">
<span class="gray branding-text">by Mogsdad, D.Bingham</span>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js">
</script>
<script>
/**
* On document load, assign click handlers to button(s), add
* elements that should start hidden (avoids "flashing"), and
* start polling for document selections.
*/
$(function() {
// assign click handler(s)
$('#get-selection').click(getSelection);
// Add elements that should start hidden
var newdiv1 = $( "<div class='block' id='cursor-word'/>" ).hide(),
newdiv2 = $( "<div class='block' id='selected-text'/>" ).hide();
$('#button-bar').after( newdiv1, newdiv2 );
$('#cursor-word').html('<H2>Word at cursor:</H2><p id="cursor-word-content"></p>');
$('#selected-text').html('<H2>Selected text:</H2><p id="selected-text-content"></p>');
// Start polling for updates
poll();
});
/**
* Poll the server-side 'checkSelection' function at the given
* interval for document selection, and enable or disable the
* '#get-selection' button.
*
* #param {Number} interval (optional) Time in ms between polls.
* Default is 2s (2000ms)
*/
function poll(interval){
interval = interval || 2000;
setTimeout(function(){
google.script.run
.withSuccessHandler(
function(cursor) {
if (cursor.isSelection) {
// Text has been selected: enable button, hide cursor word.
$('#get-selection').attr('disabled', false);
$('#cursor-word').hide();
// $('#selected-text').show(); // Not so fast - wait until button is clicked.
}
else {
$('#get-selection').attr('disabled', true);
$('#cursor-word').show();
$('#selected-text').hide();
}
$('#cursor-word-content').text(cursor.cursorWord);
//Setup the next poll recursively
poll(interval);
})
.withFailureHandler(
function(msg, element) {
showError(msg, $('#button-bar'));
element.disabled = false;
})
.checkSelection();
}, interval);
};
/**
* Runs a server-side function to retrieve the currently
* selected text.
*/
function getSelection() {
this.disabled = true;
$('#error').remove();
google.script.run
.withSuccessHandler(
function(selectedText, element) {
// Show selected text
$('#selected-text-content').text(selectedText);
$('#selected-text').show();
element.disabled = false;
})
.withFailureHandler(
function(msg, element) {
showError(msg, $('#button-bar'));
element.disabled = false;
})
.withUserObject(this)
.getSelectedText();
}
/**
* Inserts a div that contains an error message after a given element.
*
* #param msg The error message to display.
* #param element The element after which to display the error.
*/
function showError(msg, element) {
var div = $('<div id="error" class="error">' + msg + '</div>');
$(element).after(div);
}
</script>
Polling Interval
The setTimeout() function accepts a time interval expressed in milliseconds, but I found through experimentation that a two-second response was the best that could be expected. Therefore, the skeleton poll() has a 2000ms interval as its default. If your situation can tolerate a longer delay between poll cycles, then provide a larger value with the onLoad call to poll(), e.g. poll(10000) for a 10-second poll cycle.
Sheets
For a sheet example see How do I make a Sidebar display values from cells?
In our page,we often use the javascript based animation to make the element move/resize,most of them use the setTimeout or setInterval to change the position or size of the element:
For example:
function open() {
var w=parseInt(foo.style.width);
if(w>=200) clearTimeout(t);
else{
foo.style.width = +1+'px';
t=setTimeout(open,20); // call doMove in 20msec
}
}
function init() {
foo = document.getElementById('dv'); // get the "foo" object
foo.style.width = '0px'; // set its initial position to 0px
open(); // start animating
}
The above code want to show the div#foo slowly,but as you see,I set the maxwidth of the div to 200px to stop the animation.
But how about if the real size of the content div should more than 200?
That's to say I can not get the final width of the element.
What is the general solution?
Here is the live exmple:
Use the modified code as shown below. It will continue expanding until the element has reached its full width.
function open() { //See comment at OP
var w = foo.offsetWidht; // offsetWidht NOT style.width
var realWidth = foo.scrollWidth;
if(w < 200 || w < realWidth) {
foo.style.width = +1+'px';
setTimeout(open, 20); // call doMove in 20msec
}
}
Also, you don't need clearTimeout, since no timeout has been set when the function is called again.
Use one of the various methods of computing styles. Google "JavaScript compute width" and there will be lots of results. Try the property offsetWidth first. I can't quite remember its compatibility table but it definitely works in Chrome, Safari, and IE8/9.
I want to be able to do a cross fade transition on large images whose width is set to 100% of the screen. I have a working example of what I want to accomplish. However, when I test it out on various browsers and various computers I don't get a buttery-smooth transition everywhere.
See demo on jsFiddle: http://jsfiddle.net/vrD2C/
See on Amazon S3: http://imagefader.s3.amazonaws.com/index.htm
I want to know how to improve the performance. Here's the function that actually does the image swap:
function swapImage(oldImg, newImg) {
newImg.css({
"display": "block",
"z-index": 2,
"opacity": 0
})
.removeClass("shadow")
.animate({ "opacity": 1 }, 500, function () {
if (oldImg) {
oldImg.hide();
}
newImg.addClass("shadow").css("z-index", 1);
});
}
Is using jQuery animate() to change the opacity a bad way to go?
You might want to look into CSS3 Transitions, as the browser might be able to optimize that better than Javascript directly setting the attributes in a loop. This seems to be a pretty good start for it:
http://robertnyman.com/2010/04/27/using-css3-transitions-to-create-rich-effects/
I'm not sure if this will help optimize your performance as I am currently using IE9 on an amped up machine and even if I put the browser into IE7 or 8 document mode, the JavaScript doesn't falter with your current code. However, you might consider making the following optimizations to the code.
Unclutter the contents of the main photo stage by placing all your photos in a hidden container you could give an id of "queue" or something similar, making the DOM do the work of storing and ordering the images you are not currently displaying for you. This will also leave the browser only working with two visible images at any given time, giving it less to consider as far as stacking context, positioning, and so on.
Rewrite the code to use an event trigger and bind the fade-in handling to the event, calling the first image in the queue's event once the current transition is complete. I find this method is more well-behaved for cycling animation than some timeout-managed scripts. An example of how to do this follows:
// Bind a custom event to each image called "transition"
$("#queue img").bind("transition", function() {
$(this)
// Hide the image
.hide()
// Move it to the visible stage
.appendTo("#photos")
// Delay the upcoming animation by the desired value
.delay(2500)
// Slowly fade the image in
.fadeIn("slow", function() {
// Animation callback
$(this)
// Add a shadow class to this image
.addClass("shadow")
// Select the replaced image
.siblings("img")
// Remove its shadow class
.removeClass("shadow")
// Move it to the back of the image queue container
.appendTo("#queue");
// Trigger the transition event on the next image in the queue
$("#queue img:first").trigger("transition");
});
}).first().addClass("shadow").trigger("transition"); // Fire the initial event
Try this working demo in your problem browsers and let me know if the performance is still poor.
I had the same problem too. I just preloaded my images and the transitions became smooth again.
The point is that IE is not W3C compliant, but +1 with ctcherry as using css is the most efficient way for smooth transitions.
Then there are the javascript coded solutions, either using js straight (but need some efforts are needed to comply with W3C Vs browsers), or using libs like JQuery or Mootools.
Here is a good javascript coded example (See demo online) compliant to your needs :
var Fondu = function(classe_img){
this.classe_img = classe_img;
this.courant = 0;
this.coeff = 100;
this.collection = this.getImages();
this.collection[0].style.zIndex = 100;
this.total = this.collection.length - 1;
this.encours = false;
}
Fondu.prototype.getImages = function(){
var tmp = [];
if(document.getElementsByClassName){
tmp = document.getElementsByClassName(this.classe_img);
}
else{
var i=0;
while(document.getElementsByTagName('*')[i]){
if(document.getElementsByTagName('*')[i].className.indexOf(this.classe_img) > -1){
tmp.push(document.getElementsByTagName('*')[i]);
}
i++;
}
}
var j=tmp.length;
while(j--){
if(tmp[j].filters){
tmp[j].style.width = tmp[j].style.width || tmp[j].offsetWidth+'px';
tmp[j].style.filter = 'alpha(opacity=100)';
tmp[j].opaque = tmp[j].filters[0];
this.coeff = 1;
}
else{
tmp[j].opaque = tmp[j].style;
}
}
return tmp;
}
Fondu.prototype.change = function(sens){
if(this.encours){
return false;
}
var prevObj = this.collection[this.courant];
this.encours = true;
if(sens){
this.courant++;
if(this.courant>this.total){
this.courant = 0;
}
}
else{
this.courant--;
if(this.courant<0){
this.courant = this.total;
}
}
var nextObj = this.collection[this.courant];
nextObj.style.zIndex = 50;
var tmpOp = 100;
var that = this;
var timer = setInterval(function(){
if(tmpOp<0){
clearInterval(timer);
timer = null;
prevObj.opaque.opacity = 0;
nextObj.style.zIndex = 100;
prevObj.style.zIndex = 0;
prevObj.opaque.opacity = 100 / that.coeff;
that.encours = false;
}
else{
prevObj.opaque.opacity = tmpOp / that.coeff;
tmpOp -= 5;
}
}, 25);
}
I want that when mouse is over an image, an event should be triggered ONCE, and it should be triggered again only after mouse is out of that image and back again, and also at least 2 seconds passed.
My current function is called continuously (refreshcash) if I leave the mouse over my image
<img src="images/reficon.png" onmouseover="refreshcash()" onmouseout="normalimg()" id="cashrefresh"/>
function refreshcash() {
$("#showname").load('./includes/do_name.inc.php');
$("#cashrefresh").attr("src","images/reficonani.gif");
}
function normalimg() {
$("#cashrefresh").attr("src","images/reficon.png");
}
code update
This code seems to have a bug,but the algorithm is kinda logical
<script type="text/javascript">
var canhover = 1;
var timeok = 1;
function redotimeok() {
timeok = 1;
}
//
function onmenter()
{
if (canhover == 1 && timeok == 1)
{
enter();
canhover = 0;
}
}
//
function onmleave()
{
leave();
canhover = 1;
setTimeout(redotimeok(), 2000);
leave();
}
//
$('#cashrefresh').hover(onmenter(),onmleave());
function enter(){
$("#showname").load('./includes/do_name.inc.php');
$("#cashrefresh").attr("src","images/reficonani.gif");
}
function leave(){
$("#cashrefresh").attr("src","images/reficon.png");
}
</script>
Try the hover:
$('#cashrefresh').hover(function(){
$("#showname").load('./includes/do_name.inc.php');
$("#cashrefresh").attr("src","images/reficonani.gif");
}, function(){
$("#cashrefresh").attr("src","images/reficon.png");
});
And your image should look like:
<img src="images/reficon.png" id="cashrefresh"/>
Update:
Modify your code like this:
var e = null;
var l = null;
$('#cashrefresh').hover(function(){
e = setTimeout(enter, 2000)
}, function(){
l = setTimeout(leave, 2000)
});
function enter(){
$("#showname").load('./includes/do_name.inc.php');
$("#cashrefresh").attr("src","images/reficonani.gif");
clearTimeout(e);
}
function leave(){
$("#cashrefresh").attr("src","images/reficon.png");
clearTimeout(l);
}
Do you have the images cached in some way? If you replace them by their src attribute without specifying width/height elsewhere (best would be CSS) or having them readily available then the hovered box (img element) will collapse into a smaller (or no) box until the image has been loaded far enough for the browser to know the correct dimensions of the image to resize the box (which may affect other elements being adjusted to the image). The exact effect depends on the browser but you may lose the hover state causing the call of your mouseout function.
I assume that both images are the same size, so if you didn't already, you could try adding the dimensions to your CSS for #cashrefresh and see if that fixes the problem.
For the delay I would recommend using the jQuery timers plugin (or a similar one) which eases handling of timers compared to doing it on your own. You would probably want to give your timers names and try to stop older ones before you add the next one.