How to customize SpryCollapsiblePanel.js to mouseout

  • honeyham
  • Novice
  • Novice
  • honeyham
  • Posts: 16

Post 3+ Months Ago

Hello,

I am pulling out hair trying to figure out how to make my collapsible panel / drop down menu mouseover and mouseout properly. The following code was created by adobe and I have altered only line 207 of code. 207 to 209 originally read:

Spry.Widget.CollapsiblePanel.addEventListener(tab, "click", function(e) { return self.onTabClick(); }, false);
Spry.Widget.CollapsiblePanel.addEventListener(tab, "mouseover", function(e) { return self.onTabMouseOver(); }, false);
Spry.Widget.CollapsiblePanel.addEventListener(tab, "mouseout", function(e) { return self.onTabMouseOut(); }, false);

And I have changed "click" to "mouseover".

This seems to have done part of the job correctly. When mouse hovers over the menu, the sub menu animates down perfectly. HOWEVER, the only way to have it animate closed is to mouse out directly over the main menu item. If I mouse out over the sub menu, it remains open.

I need to have the sub menu remain open when the mouse hovers over either the main menu item, or the sub menu items. But animate close when mouse out of sub menu.

Any ideas how I can do this? I am very new at programming, especially with javascript. Below is the full script:

Code: [ Select ]
var Spry;
if (!Spry) Spry = {};
if (!Spry.Widget) Spry.Widget = {};
 
Spry.Widget.CollapsiblePanel = function(element, opts)
{
    this.init(element);
 
    Spry.Widget.CollapsiblePanel.setOptions(this, opts);
 
    this.attachBehaviors();
};
 
Spry.Widget.CollapsiblePanel.prototype.init = function(element)
{
    this.element = this.getElement(element);
    this.focusElement = null;
    this.hoverClass = "CollapsiblePanelTabHover";
    this.openClass = "CollapsiblePanelOpen";
    this.closedClass = "CollapsiblePanelClosed";
    this.focusedClass = "CollapsiblePanelFocused";
    this.enableAnimation = true;
    this.enableKeyboardNavigation = true;
    this.animator = null;
    this.hasFocus = false;
    this.contentIsOpen = true;
};
 
Spry.Widget.CollapsiblePanel.prototype.getElement = function(ele)
{
    if (ele && typeof ele == "string")
        return document.getElementById(ele);
    return ele;
};
 
Spry.Widget.CollapsiblePanel.prototype.addClassName = function(ele, className)
{
    if (!ele || !className || (ele.className && ele.className.search(new RegExp("\b" + className + "\b")) != -1))
        return;
    ele.className += (ele.className ? " " : "") + className;
};
 
Spry.Widget.CollapsiblePanel.prototype.removeClassName = function(ele, className)
{
    if (!ele || !className || (ele.className && ele.className.search(new RegExp("\b" + className + "\b")) == -1))
        return;
    ele.className = ele.className.replace(new RegExp("\s*\b" + className + "\b", "g"), "");
};
 
Spry.Widget.CollapsiblePanel.prototype.hasClassName = function(ele, className)
{
    if (!ele || !className || !ele.className || ele.className.search(new RegExp("\b" + className + "\b")) == -1)
        return false;
    return true;
};
 
Spry.Widget.CollapsiblePanel.prototype.setDisplay = function(ele, display)
{
    if( ele )
        ele.style.display = display;
};
 
Spry.Widget.CollapsiblePanel.setOptions = function(obj, optionsObj, ignoreUndefinedProps)
{
    if (!optionsObj)
        return;
    for (var optionName in optionsObj)
    {
        if (ignoreUndefinedProps && optionsObj[optionName] == undefined)
            continue;
        obj[optionName] = optionsObj[optionName];
    }
};
 
Spry.Widget.CollapsiblePanel.prototype.onTabMouseOver = function()
{
    this.addClassName(this.getTab(), this.hoverClass);
};
 
Spry.Widget.CollapsiblePanel.prototype.onTabMouseOut = function()
{
    this.removeClassName(this.getTab(), this.hoverClass);
};
 
Spry.Widget.CollapsiblePanel.prototype.open = function()
{
    this.contentIsOpen = true;
    if (this.enableAnimation)
    {
        if (this.animator)
            this.animator.stop();
        this.animator = new Spry.Widget.CollapsiblePanel.PanelAnimator(this, true);
        this.animator.start();
    }
    else
        this.setDisplay(this.getContent(), "block");
 
    this.removeClassName(this.element, this.closedClass);
    this.addClassName(this.element, this.openClass);
};
 
Spry.Widget.CollapsiblePanel.prototype.close = function()
{
    this.contentIsOpen = false;
    if (this.enableAnimation)
    {
        if (this.animator)
            this.animator.stop();
        this.animator = new Spry.Widget.CollapsiblePanel.PanelAnimator(this, false);
        this.animator.start();
    }
    else
        this.setDisplay(this.getContent(), "none");
 
    this.removeClassName(this.element, this.openClass);
    this.addClassName(this.element, this.closedClass);
};
 
Spry.Widget.CollapsiblePanel.prototype.onTabClick = function()
{
    if (this.isOpen())
        this.close();
    else
        this.open();
    this.focus();
};
 
Spry.Widget.CollapsiblePanel.prototype.onFocus = function(e)
{
    this.hasFocus = true;
    this.addClassName(this.element, this.focusedClass);
};
 
Spry.Widget.CollapsiblePanel.prototype.onBlur = function(e)
{
    this.hasFocus = false;
    this.removeClassName(this.element, this.focusedClass);
};
 
Spry.Widget.CollapsiblePanel.ENTER_KEY = 13;
Spry.Widget.CollapsiblePanel.SPACE_KEY = 32;
 
Spry.Widget.CollapsiblePanel.prototype.onKeyDown = function(e)
{
    var key = e.keyCode;
    if (!this.hasFocus || (key != Spry.Widget.CollapsiblePanel.ENTER_KEY && key != Spry.Widget.CollapsiblePanel.SPACE_KEY))
        return true;
   
    if (this.isOpen())
        this.close();
    else
        this.open();
 
    if (e.stopPropagation)
        e.stopPropagation();
    if (e.preventDefault)
        e.preventDefault();
 
    return false;
};
 
Spry.Widget.CollapsiblePanel.prototype.attachPanelHandlers = function()
{
    var tab = this.getTab();
    if (!tab)
        return;
 
    var self = this;
    Spry.Widget.CollapsiblePanel.addEventListener(tab, "mouseover", function(e) { return self.onTabClick(); }, false);
    Spry.Widget.CollapsiblePanel.addEventListener(tab, "mouseover", function(e) { return self.onTabMouseOver(); }, false);
    Spry.Widget.CollapsiblePanel.addEventListener(tab, "mouseout", function(e) { return self.onTabMouseOut(); }, false);
 
    if (this.enableKeyboardNavigation)
    {
        // XXX: IE doesn't allow the setting of tabindex dynamically. This means we can't
        // rely on adding the tabindex attribute if it is missing to enable keyboard navigation
        // by default.
 
        // Find the first element within the tab container that has a tabindex or the first
        // anchor tag.
       
        var tabIndexEle = null;
        var tabAnchorEle = null;
 
        this.preorderTraversal(tab, function(node) {
            if (node.nodeType == 1 /* NODE.ELEMENT_NODE */)
            {
                var tabIndexAttr = tab.attributes.getNamedItem("tabindex");
                if (tabIndexAttr)
                {
                    tabIndexEle = node;
                    return true;
                }
                if (!tabAnchorEle && node.nodeName.toLowerCase() == "a")
                    tabAnchorEle = node;
            }
            return false;
        });
 
        if (tabIndexEle)
            this.focusElement = tabIndexEle;
        else if (tabAnchorEle)
            this.focusElement = tabAnchorEle;
 
        if (this.focusElement)
        {
            Spry.Widget.CollapsiblePanel.addEventListener(this.focusElement, "focus", function(e) { return self.onFocus(e); }, false);
            Spry.Widget.CollapsiblePanel.addEventListener(this.focusElement, "blur", function(e) { return self.onBlur(e); }, false);
            Spry.Widget.CollapsiblePanel.addEventListener(this.focusElement, "keydown", function(e) { return self.onKeyDown(e); }, false);
        }
    }
};
 
Spry.Widget.CollapsiblePanel.addEventListener = function(element, eventType, handler, capture)
{
    try
    {
        if (element.addEventListener)
            element.addEventListener(eventType, handler, capture);
        else if (element.attachEvent)
            element.attachEvent("on" + eventType, handler);
    }
    catch (e) {}
};
 
Spry.Widget.CollapsiblePanel.prototype.preorderTraversal = function(root, func)
{
    var stopTraversal = false;
    if (root)
    {
        stopTraversal = func(root);
        if (root.hasChildNodes())
        {
            var child = root.firstChild;
            while (!stopTraversal && child)
            {
                stopTraversal = this.preorderTraversal(child, func);
                try { child = child.nextSibling; } catch (e) { child = null; }
            }
        }
    }
    return stopTraversal;
};
 
Spry.Widget.CollapsiblePanel.prototype.attachBehaviors = function()
{
    var panel = this.element;
    var tab = this.getTab();
    var content = this.getContent();
 
    if (this.contentIsOpen || this.hasClassName(panel, this.openClass))
    {
        this.removeClassName(panel, this.closedClass);
        this.setDisplay(content, "block");
        this.contentIsOpen = true;
    }
    else
    {
        this.removeClassName(panel, this.openClass);
        this.addClassName(panel, this.closedClass);
        this.setDisplay(content, "none");
        this.contentIsOpen = false;
    }
 
    this.attachPanelHandlers();
};
 
Spry.Widget.CollapsiblePanel.prototype.getTab = function()
{
    return this.getElementChildren(this.element)[0];
};
 
Spry.Widget.CollapsiblePanel.prototype.getContent = function()
{
    return this.getElementChildren(this.element)[1];
};
 
Spry.Widget.CollapsiblePanel.prototype.isOpen = function()
{
    return this.contentIsOpen;
};
 
Spry.Widget.CollapsiblePanel.prototype.getElementChildren = function(element)
{
    var children = [];
    var child = element.firstChild;
    while (child)
    {
        if (child.nodeType == 1 /* Node.ELEMENT_NODE */)
            children.push(child);
        child = child.nextSibling;
    }
    return children;
};
 
Spry.Widget.CollapsiblePanel.prototype.focus = function()
{
    if (this.focusElement && this.focusElement.focus)
        this.focusElement.focus();
};
 
/////////////////////////////////////////////////////
 
Spry.Widget.CollapsiblePanel.PanelAnimator = function(panel, doOpen, opts)
{
    this.timer = null;
    this.interval = 0;
    this.stepCount = 0;
 
    this.fps = 0;
    this.steps = 10;
    this.duration = 200;
    this.onComplete = null;
 
    this.panel = panel;
    this.content = panel.getContent();
    this.panelData = [];
    this.doOpen = doOpen;
 
    Spry.Widget.CollapsiblePanel.setOptions(this, opts);
 
 
    // If caller specified speed in terms of frames per second,
    // convert them into steps.
 
    if (this.fps > 0)
    {
        this.interval = Math.floor(1000 / this.fps);
        this.steps = parseInt((this.duration + (this.interval - 1)) / this.interval);
    }
    else if (this.steps > 0)
        this.interval = this.duration / this.steps;
 
    var c = this.content;
 
    var curHeight = c.offsetHeight ? c.offsetHeight : 0;
   
    if (doOpen && c.style.display == "none")
        this.fromHeight = 0;
    else
        this.fromHeight = curHeight;
 
    if (!doOpen)
        this.toHeight = 0;
    else
    {
        if (c.style.display == "none")
        {
            // The content area is not displayed so in order to calculate the extent
            // of the content inside it, we have to set its display to block.
 
            c.style.visibility = "hidden";
            c.style.display = "block";
        }
 
        // Unfortunately in Mozilla/Firefox, fetching the offsetHeight seems to cause
        // the browser to synchronously re-layout and re-display content on the page,
        // so we see a brief flash of content that is *after* the panel being positioned
        // where it should when the panel is fully expanded. To get around this, we
        // temporarily position the content area of the panel absolutely off-screen.
        // This has the effect of taking the content out-of-flow, so nothing shifts around.
 
        // var oldPos = c.style.position;
        // var oldLeft = c.style.left;
        // c.style.position = "absolute";
        // c.style.left = "-2000em";
 
        // Clear the height property so we can calculate
        // the full height of the content we are going to show.
        c.style.height = "";
        this.toHeight = c.offsetHeight;
 
        // Now restore the position and offset to what it was!
        // c.style.position = oldPos;
        // c.style.left = oldLeft;
    }
 
    this.increment = (this.toHeight - this.fromHeight) / this.steps;
    this.overflow = c.style.overflow;
 
    c.style.height = this.fromHeight + "px";
    c.style.visibility = "visible";
    c.style.overflow = "hidden";
    c.style.display = "block";
};
 
Spry.Widget.CollapsiblePanel.PanelAnimator.prototype.start = function()
{
    var self = this;
    this.timer = setTimeout(function() { self.stepAnimation(); }, this.interval);
};
 
Spry.Widget.CollapsiblePanel.PanelAnimator.prototype.stop = function()
{
    if (this.timer)
    {
        clearTimeout(this.timer);
 
        // If we're killing the timer, restore the overflow
        // properties on the panels we were animating!
 
        if (this.stepCount < this.steps)
            this.content.style.overflow = this.overflow;
    }
 
    this.timer = null;
};
 
Spry.Widget.CollapsiblePanel.PanelAnimator.prototype.stepAnimation = function()
{
    ++this.stepCount;
 
    this.animate();
 
    if (this.stepCount < this.steps)
        this.start();
    else if (this.onComplete)
        this.onComplete();
};
 
Spry.Widget.CollapsiblePanel.PanelAnimator.prototype.animate = function()
{
    if (this.stepCount >= this.steps)
    {
        if (!this.doOpen)
            this.content.style.display = "none";
        this.content.style.overflow = this.overflow;
        this.content.style.height = this.toHeight + "px";
    }
    else
    {
        this.fromHeight += this.increment;
        this.content.style.height = this.fromHeight + "px";
    }
};
 
  1. var Spry;
  2. if (!Spry) Spry = {};
  3. if (!Spry.Widget) Spry.Widget = {};
  4.  
  5. Spry.Widget.CollapsiblePanel = function(element, opts)
  6. {
  7.     this.init(element);
  8.  
  9.     Spry.Widget.CollapsiblePanel.setOptions(this, opts);
  10.  
  11.     this.attachBehaviors();
  12. };
  13.  
  14. Spry.Widget.CollapsiblePanel.prototype.init = function(element)
  15. {
  16.     this.element = this.getElement(element);
  17.     this.focusElement = null;
  18.     this.hoverClass = "CollapsiblePanelTabHover";
  19.     this.openClass = "CollapsiblePanelOpen";
  20.     this.closedClass = "CollapsiblePanelClosed";
  21.     this.focusedClass = "CollapsiblePanelFocused";
  22.     this.enableAnimation = true;
  23.     this.enableKeyboardNavigation = true;
  24.     this.animator = null;
  25.     this.hasFocus = false;
  26.     this.contentIsOpen = true;
  27. };
  28.  
  29. Spry.Widget.CollapsiblePanel.prototype.getElement = function(ele)
  30. {
  31.     if (ele && typeof ele == "string")
  32.         return document.getElementById(ele);
  33.     return ele;
  34. };
  35.  
  36. Spry.Widget.CollapsiblePanel.prototype.addClassName = function(ele, className)
  37. {
  38.     if (!ele || !className || (ele.className && ele.className.search(new RegExp("\b" + className + "\b")) != -1))
  39.         return;
  40.     ele.className += (ele.className ? " " : "") + className;
  41. };
  42.  
  43. Spry.Widget.CollapsiblePanel.prototype.removeClassName = function(ele, className)
  44. {
  45.     if (!ele || !className || (ele.className && ele.className.search(new RegExp("\b" + className + "\b")) == -1))
  46.         return;
  47.     ele.className = ele.className.replace(new RegExp("\s*\b" + className + "\b", "g"), "");
  48. };
  49.  
  50. Spry.Widget.CollapsiblePanel.prototype.hasClassName = function(ele, className)
  51. {
  52.     if (!ele || !className || !ele.className || ele.className.search(new RegExp("\b" + className + "\b")) == -1)
  53.         return false;
  54.     return true;
  55. };
  56.  
  57. Spry.Widget.CollapsiblePanel.prototype.setDisplay = function(ele, display)
  58. {
  59.     if( ele )
  60.         ele.style.display = display;
  61. };
  62.  
  63. Spry.Widget.CollapsiblePanel.setOptions = function(obj, optionsObj, ignoreUndefinedProps)
  64. {
  65.     if (!optionsObj)
  66.         return;
  67.     for (var optionName in optionsObj)
  68.     {
  69.         if (ignoreUndefinedProps && optionsObj[optionName] == undefined)
  70.             continue;
  71.         obj[optionName] = optionsObj[optionName];
  72.     }
  73. };
  74.  
  75. Spry.Widget.CollapsiblePanel.prototype.onTabMouseOver = function()
  76. {
  77.     this.addClassName(this.getTab(), this.hoverClass);
  78. };
  79.  
  80. Spry.Widget.CollapsiblePanel.prototype.onTabMouseOut = function()
  81. {
  82.     this.removeClassName(this.getTab(), this.hoverClass);
  83. };
  84.  
  85. Spry.Widget.CollapsiblePanel.prototype.open = function()
  86. {
  87.     this.contentIsOpen = true;
  88.     if (this.enableAnimation)
  89.     {
  90.         if (this.animator)
  91.             this.animator.stop();
  92.         this.animator = new Spry.Widget.CollapsiblePanel.PanelAnimator(this, true);
  93.         this.animator.start();
  94.     }
  95.     else
  96.         this.setDisplay(this.getContent(), "block");
  97.  
  98.     this.removeClassName(this.element, this.closedClass);
  99.     this.addClassName(this.element, this.openClass);
  100. };
  101.  
  102. Spry.Widget.CollapsiblePanel.prototype.close = function()
  103. {
  104.     this.contentIsOpen = false;
  105.     if (this.enableAnimation)
  106.     {
  107.         if (this.animator)
  108.             this.animator.stop();
  109.         this.animator = new Spry.Widget.CollapsiblePanel.PanelAnimator(this, false);
  110.         this.animator.start();
  111.     }
  112.     else
  113.         this.setDisplay(this.getContent(), "none");
  114.  
  115.     this.removeClassName(this.element, this.openClass);
  116.     this.addClassName(this.element, this.closedClass);
  117. };
  118.  
  119. Spry.Widget.CollapsiblePanel.prototype.onTabClick = function()
  120. {
  121.     if (this.isOpen())
  122.         this.close();
  123.     else
  124.         this.open();
  125.     this.focus();
  126. };
  127.  
  128. Spry.Widget.CollapsiblePanel.prototype.onFocus = function(e)
  129. {
  130.     this.hasFocus = true;
  131.     this.addClassName(this.element, this.focusedClass);
  132. };
  133.  
  134. Spry.Widget.CollapsiblePanel.prototype.onBlur = function(e)
  135. {
  136.     this.hasFocus = false;
  137.     this.removeClassName(this.element, this.focusedClass);
  138. };
  139.  
  140. Spry.Widget.CollapsiblePanel.ENTER_KEY = 13;
  141. Spry.Widget.CollapsiblePanel.SPACE_KEY = 32;
  142.  
  143. Spry.Widget.CollapsiblePanel.prototype.onKeyDown = function(e)
  144. {
  145.     var key = e.keyCode;
  146.     if (!this.hasFocus || (key != Spry.Widget.CollapsiblePanel.ENTER_KEY && key != Spry.Widget.CollapsiblePanel.SPACE_KEY))
  147.         return true;
  148.    
  149.     if (this.isOpen())
  150.         this.close();
  151.     else
  152.         this.open();
  153.  
  154.     if (e.stopPropagation)
  155.         e.stopPropagation();
  156.     if (e.preventDefault)
  157.         e.preventDefault();
  158.  
  159.     return false;
  160. };
  161.  
  162. Spry.Widget.CollapsiblePanel.prototype.attachPanelHandlers = function()
  163. {
  164.     var tab = this.getTab();
  165.     if (!tab)
  166.         return;
  167.  
  168.     var self = this;
  169.     Spry.Widget.CollapsiblePanel.addEventListener(tab, "mouseover", function(e) { return self.onTabClick(); }, false);
  170.     Spry.Widget.CollapsiblePanel.addEventListener(tab, "mouseover", function(e) { return self.onTabMouseOver(); }, false);
  171.     Spry.Widget.CollapsiblePanel.addEventListener(tab, "mouseout", function(e) { return self.onTabMouseOut(); }, false);
  172.  
  173.     if (this.enableKeyboardNavigation)
  174.     {
  175.         // XXX: IE doesn't allow the setting of tabindex dynamically. This means we can't
  176.         // rely on adding the tabindex attribute if it is missing to enable keyboard navigation
  177.         // by default.
  178.  
  179.         // Find the first element within the tab container that has a tabindex or the first
  180.         // anchor tag.
  181.        
  182.         var tabIndexEle = null;
  183.         var tabAnchorEle = null;
  184.  
  185.         this.preorderTraversal(tab, function(node) {
  186.             if (node.nodeType == 1 /* NODE.ELEMENT_NODE */)
  187.             {
  188.                 var tabIndexAttr = tab.attributes.getNamedItem("tabindex");
  189.                 if (tabIndexAttr)
  190.                 {
  191.                     tabIndexEle = node;
  192.                     return true;
  193.                 }
  194.                 if (!tabAnchorEle && node.nodeName.toLowerCase() == "a")
  195.                     tabAnchorEle = node;
  196.             }
  197.             return false;
  198.         });
  199.  
  200.         if (tabIndexEle)
  201.             this.focusElement = tabIndexEle;
  202.         else if (tabAnchorEle)
  203.             this.focusElement = tabAnchorEle;
  204.  
  205.         if (this.focusElement)
  206.         {
  207.             Spry.Widget.CollapsiblePanel.addEventListener(this.focusElement, "focus", function(e) { return self.onFocus(e); }, false);
  208.             Spry.Widget.CollapsiblePanel.addEventListener(this.focusElement, "blur", function(e) { return self.onBlur(e); }, false);
  209.             Spry.Widget.CollapsiblePanel.addEventListener(this.focusElement, "keydown", function(e) { return self.onKeyDown(e); }, false);
  210.         }
  211.     }
  212. };
  213.  
  214. Spry.Widget.CollapsiblePanel.addEventListener = function(element, eventType, handler, capture)
  215. {
  216.     try
  217.     {
  218.         if (element.addEventListener)
  219.             element.addEventListener(eventType, handler, capture);
  220.         else if (element.attachEvent)
  221.             element.attachEvent("on" + eventType, handler);
  222.     }
  223.     catch (e) {}
  224. };
  225.  
  226. Spry.Widget.CollapsiblePanel.prototype.preorderTraversal = function(root, func)
  227. {
  228.     var stopTraversal = false;
  229.     if (root)
  230.     {
  231.         stopTraversal = func(root);
  232.         if (root.hasChildNodes())
  233.         {
  234.             var child = root.firstChild;
  235.             while (!stopTraversal && child)
  236.             {
  237.                 stopTraversal = this.preorderTraversal(child, func);
  238.                 try { child = child.nextSibling; } catch (e) { child = null; }
  239.             }
  240.         }
  241.     }
  242.     return stopTraversal;
  243. };
  244.  
  245. Spry.Widget.CollapsiblePanel.prototype.attachBehaviors = function()
  246. {
  247.     var panel = this.element;
  248.     var tab = this.getTab();
  249.     var content = this.getContent();
  250.  
  251.     if (this.contentIsOpen || this.hasClassName(panel, this.openClass))
  252.     {
  253.         this.removeClassName(panel, this.closedClass);
  254.         this.setDisplay(content, "block");
  255.         this.contentIsOpen = true;
  256.     }
  257.     else
  258.     {
  259.         this.removeClassName(panel, this.openClass);
  260.         this.addClassName(panel, this.closedClass);
  261.         this.setDisplay(content, "none");
  262.         this.contentIsOpen = false;
  263.     }
  264.  
  265.     this.attachPanelHandlers();
  266. };
  267.  
  268. Spry.Widget.CollapsiblePanel.prototype.getTab = function()
  269. {
  270.     return this.getElementChildren(this.element)[0];
  271. };
  272.  
  273. Spry.Widget.CollapsiblePanel.prototype.getContent = function()
  274. {
  275.     return this.getElementChildren(this.element)[1];
  276. };
  277.  
  278. Spry.Widget.CollapsiblePanel.prototype.isOpen = function()
  279. {
  280.     return this.contentIsOpen;
  281. };
  282.  
  283. Spry.Widget.CollapsiblePanel.prototype.getElementChildren = function(element)
  284. {
  285.     var children = [];
  286.     var child = element.firstChild;
  287.     while (child)
  288.     {
  289.         if (child.nodeType == 1 /* Node.ELEMENT_NODE */)
  290.             children.push(child);
  291.         child = child.nextSibling;
  292.     }
  293.     return children;
  294. };
  295.  
  296. Spry.Widget.CollapsiblePanel.prototype.focus = function()
  297. {
  298.     if (this.focusElement && this.focusElement.focus)
  299.         this.focusElement.focus();
  300. };
  301.  
  302. /////////////////////////////////////////////////////
  303.  
  304. Spry.Widget.CollapsiblePanel.PanelAnimator = function(panel, doOpen, opts)
  305. {
  306.     this.timer = null;
  307.     this.interval = 0;
  308.     this.stepCount = 0;
  309.  
  310.     this.fps = 0;
  311.     this.steps = 10;
  312.     this.duration = 200;
  313.     this.onComplete = null;
  314.  
  315.     this.panel = panel;
  316.     this.content = panel.getContent();
  317.     this.panelData = [];
  318.     this.doOpen = doOpen;
  319.  
  320.     Spry.Widget.CollapsiblePanel.setOptions(this, opts);
  321.  
  322.  
  323.     // If caller specified speed in terms of frames per second,
  324.     // convert them into steps.
  325.  
  326.     if (this.fps > 0)
  327.     {
  328.         this.interval = Math.floor(1000 / this.fps);
  329.         this.steps = parseInt((this.duration + (this.interval - 1)) / this.interval);
  330.     }
  331.     else if (this.steps > 0)
  332.         this.interval = this.duration / this.steps;
  333.  
  334.     var c = this.content;
  335.  
  336.     var curHeight = c.offsetHeight ? c.offsetHeight : 0;
  337.    
  338.     if (doOpen && c.style.display == "none")
  339.         this.fromHeight = 0;
  340.     else
  341.         this.fromHeight = curHeight;
  342.  
  343.     if (!doOpen)
  344.         this.toHeight = 0;
  345.     else
  346.     {
  347.         if (c.style.display == "none")
  348.         {
  349.             // The content area is not displayed so in order to calculate the extent
  350.             // of the content inside it, we have to set its display to block.
  351.  
  352.             c.style.visibility = "hidden";
  353.             c.style.display = "block";
  354.         }
  355.  
  356.         // Unfortunately in Mozilla/Firefox, fetching the offsetHeight seems to cause
  357.         // the browser to synchronously re-layout and re-display content on the page,
  358.         // so we see a brief flash of content that is *after* the panel being positioned
  359.         // where it should when the panel is fully expanded. To get around this, we
  360.         // temporarily position the content area of the panel absolutely off-screen.
  361.         // This has the effect of taking the content out-of-flow, so nothing shifts around.
  362.  
  363.         // var oldPos = c.style.position;
  364.         // var oldLeft = c.style.left;
  365.         // c.style.position = "absolute";
  366.         // c.style.left = "-2000em";
  367.  
  368.         // Clear the height property so we can calculate
  369.         // the full height of the content we are going to show.
  370.         c.style.height = "";
  371.         this.toHeight = c.offsetHeight;
  372.  
  373.         // Now restore the position and offset to what it was!
  374.         // c.style.position = oldPos;
  375.         // c.style.left = oldLeft;
  376.     }
  377.  
  378.     this.increment = (this.toHeight - this.fromHeight) / this.steps;
  379.     this.overflow = c.style.overflow;
  380.  
  381.     c.style.height = this.fromHeight + "px";
  382.     c.style.visibility = "visible";
  383.     c.style.overflow = "hidden";
  384.     c.style.display = "block";
  385. };
  386.  
  387. Spry.Widget.CollapsiblePanel.PanelAnimator.prototype.start = function()
  388. {
  389.     var self = this;
  390.     this.timer = setTimeout(function() { self.stepAnimation(); }, this.interval);
  391. };
  392.  
  393. Spry.Widget.CollapsiblePanel.PanelAnimator.prototype.stop = function()
  394. {
  395.     if (this.timer)
  396.     {
  397.         clearTimeout(this.timer);
  398.  
  399.         // If we're killing the timer, restore the overflow
  400.         // properties on the panels we were animating!
  401.  
  402.         if (this.stepCount < this.steps)
  403.             this.content.style.overflow = this.overflow;
  404.     }
  405.  
  406.     this.timer = null;
  407. };
  408.  
  409. Spry.Widget.CollapsiblePanel.PanelAnimator.prototype.stepAnimation = function()
  410. {
  411.     ++this.stepCount;
  412.  
  413.     this.animate();
  414.  
  415.     if (this.stepCount < this.steps)
  416.         this.start();
  417.     else if (this.onComplete)
  418.         this.onComplete();
  419. };
  420.  
  421. Spry.Widget.CollapsiblePanel.PanelAnimator.prototype.animate = function()
  422. {
  423.     if (this.stepCount >= this.steps)
  424.     {
  425.         if (!this.doOpen)
  426.             this.content.style.display = "none";
  427.         this.content.style.overflow = this.overflow;
  428.         this.content.style.height = this.toHeight + "px";
  429.     }
  430.     else
  431.     {
  432.         this.fromHeight += this.increment;
  433.         this.content.style.height = this.fromHeight + "px";
  434.     }
  435. };
  436.  
  • UPSGuy
  • Lurker ಠ_ಠ
  • Web Master
  • User avatar
  • Posts: 2733
  • Loc: Nashville, TN

Post 3+ Months Ago

What you're seeing is not necessarily an issue with the script. It's a behaviorism that you're noticing. Think about onMouseOut - let's say you're setting it to a div that pops up another div (like a menu would do). When you onMouseOut the first one, you need to account for the mouse entering the popup, which would imply that the user is about to select something, so it needs to stay open.
  • honeyham
  • Novice
  • Novice
  • honeyham
  • Posts: 16

Post 3+ Months Ago

So if I understand correctly, you're saying that there needs to be additional code to declare the second pop up stay open onmouseover and close onmouseout?

Post Information

  • Total Posts in this topic: 3 posts
  • Users browsing this forum: No registered users and 78 guests
  • You cannot post new topics in this forum
  • You cannot reply to topics in this forum
  • You cannot edit your posts in this forum
  • You cannot delete your posts in this forum
  • You cannot post attachments in this forum
 
 

© 1998-2014. Ozzu® is a registered trademark of Unmelted, LLC.