Question

I am trying to dynamically update a tooltip made with Prototip and Prototype. The way I am trying to do this is probably not the best way (so if you know a better way that would be helpful), but the only way i could think to do it would be to hold the javascript in a div element and update the javascript inside the div element in order to update the tooltip. However, this seems to be a memory leak since each time the javascript is updated, a new Tip object is created and stored in the memory. If there isn't a better way of doing this, how can I clear the memory?

I made this simple script to test the memory leak, now I need to figure out how to make it so that the memory leak is patched in this example.

for (i=0; i<1000; i++) {
    $('testdiv').update("<script type='text/javascript'> new Tip('chips_tip', 'Your Chips', {style: 'creamy',stem: 'topLeft',hook: { mouse: true, tip: 'topLeft' },offset: { x: 10, y: 16 },delay: 0.04,width: 85}); <\/script>");
}

Here is what the javascript for the tooltip is normally:

new Tip('element', "Description", {
    style: 'creamy',
    stem: 'topLeft',
    hook: { mouse: true, tip: 'topLeft' },
    offset: { x: 10, y: 16 },
    delay: 0.04,
    width: 85
});
Was it helpful?

Solution

It seems that the new Tip construct can take an element instead of the tooltip text as a parameter. You might want to try to use that. I haven't done this so you'll have to try it by yourself. First, create the tooltip layout (div tag containing tooltip text) and style it as usual. Set the style attribute of this div to "display:none". Then try to create the tip like this:

new Tip('source', $('tooltip_container'));

You can then change the tooltip's text using:

$('tooltip_container').update('new tooltip text');

It's not enough to assign the tooltip construct to a variable in the global space, since it seems to me that prototip inserts it's own tooltip html stuff into the dom. My guess is that every time you call "new Tip" you are adding extra html into the dom. These object's then reference dom nodes, so they are never garbage collected. Should be easy for you to check that out using your test code and firebug to inspect the dom.

The final option you have is to look at the prototip source code to see if it has some sort of a setTooltipText function. Then you might be able to do something like this:

var tooltip = new Tip('element', 'text');
// snip
tooltip.setText('some new text');

If that doesn't help, just email the author of prototip. I am sure he will be glad to help.

OTHER TIPS

As you have noticed, simply instantiating a new Tip will mean a new Tip object is created and stored in memory.

To get around this, you need to assign the Tip to a unique variable in the global scope. i.e. instantiate the variable "tooltip", and then use "tooltip = new Tip" in your routine (this will allow for only 1 tooltip to be in use at a time, which I would assume is what you want as only one can be displayed). Garbage collection should take care of the rest.

By instantiating the "Tip" object you actually perform constructor call, e.g. simple function call, which handle and update the visual element accordingly, but once this object is not referenced by any variable it supposed to be collected by garbage collector. In case you want to be sure in that you can do the next:

var tip = new Tip( whatever);
// before next update do delete tip;

It looks like this is actually a memory leak in Prototype. According to this, the leak is fixed in 1.6.1

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top