SitePoint Sponsor

User Tag List

Results 1 to 3 of 3
  1. #1
    SitePoint Member
    Join Date
    Mar 2006
    Posts
    9
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Elastic ToolTip?

    Hey Guys and Girls

    I have the following javascript code for a tool tip that moves with the mouse. However I would like it if it had an almost elastic quality to its movement so it doesn't just rigidly move with the exact mouse positions,. Sort of though it catches up with the cursor once it stops.

    Code:
    addLoadListener(initTooltips);
    
    function initTooltips()
    {
      var tips = getElementsByAttribute("class", "hastooltip");
    
      for (var i = 0; i < tips.length; i++)
      {
        attachEventListener(tips[i], "mouseover", showTip, false);
        attachEventListener(tips[i], "mouseout", hideTip, false);
      }
    
      return true;
    }
    
    function showTip(event)
    {
      if (typeof event == "undefined")
      {
        event = window.event;
      }
    
      var target = getEventTarget(event);
    
      while (target.className == null || !/(^| )hastooltip( |$)/.test(target.className))
      {
        target = target.parentNode;
      }
    
      var tip = document.createElement("div");
      var content = target.getAttribute("title");
    
      target.tooltip = tip;
      target.setAttribute("title", "");
    
      if (target.getAttribute("id") != "")
      {
        tip.setAttribute("id", target.getAttribute("id") + "tooltip");
      }
    
      tip.className = "tooltip";
      tip.appendChild(document.createTextNode(content));
    
      var scrollingPosition = getScrollingPosition();
      var cursorPosition = [0, 0];
    
      if (typeof event.pageX != "undefined" && typeof event.x != "undefined")
      {
        cursorPosition[0] = event.pageX;
        cursorPosition[1] = event.pageY;
      }
      else
      {
        cursorPosition[0] = event.clientX + scrollingPosition[0];
        cursorPosition[1] = event.clientY + scrollingPosition[1];
      }
    
      tip.style.position = "absolute";
      tip.style.left = cursorPosition[0] + 10 + "px";
      tip.style.top = cursorPosition[1] + 10 + "px";
      tip.style.visibility = "hidden";
    
      document.getElementsByTagName("body")[0].appendChild(tip);
    
      var viewportSize = getViewportSize();
    
      if (cursorPosition[0] - scrollingPosition[0] + 10 + tip.offsetWidth > viewportSize[0] - 25)
      {
        tip.style.left = scrollingPosition[0] + viewportSize[0] - 25 - tip.offsetWidth + "px";
      }
      else
      {
        tip.style.left = cursorPosition[0] + 10 + "px";
      }
    
      if (cursorPosition[1] - scrollingPosition[1] + 10 + tip.offsetHeight > viewportSize[1] - 25)
      {
        if (event.clientX > (viewportSize[0] - 25 - tip.offsetWidth))
        {
          tip.style.top = cursorPosition[1] - tip.offsetHeight - 10 + "px";
        }
        else
        {
          tip.style.top = scrollingPosition[1] + viewportSize[1] - 25 - tip.offsetHeight + "px";
        }
      }
      else
      {
        tip.style.top = cursorPosition[1] + 10 + "px";
      }
    
      tip.style.visibility = "visible";
    
      return true;
    }
    
    function hideTip(event)
    {
      if (typeof event == "undefined")
      {
        event = window.event;
      }
    
      var target = getEventTarget(event);
    
      while (target.className == null || !target.className.match(/(^| )hastooltip( |$)/))
      {
        target = target.parentNode;
      }
    
      if (target.tooltip != null)
      {
        target.setAttribute("title", target.tooltip.childNodes[0].nodeValue);
        target.tooltip.parentNode.removeChild(target.tooltip);
      }
    
      return false;
    }
    
    function addLoadListener(fn)
    {
      if (typeof window.addEventListener != 'undefined')
      {
        window.addEventListener('load', fn, false);
      }
      else if (typeof document.addEventListener != 'undefined')
      {
        document.addEventListener('load', fn, false);
      }
      else if (typeof window.attachEvent != 'undefined')
      {
        window.attachEvent('onload', fn);
      }
      else
      {
        var oldfn = window.onload;
        if (typeof window.onload != 'function')
        {
          window.onload = fn;
        }
        else
        {
          window.onload = function()
          {
            oldfn();
            fn();
          };
        }
      }
    }
    
    function attachEventListener(target, eventType, functionRef, capture)
    {
      if (typeof target.addEventListener != "undefined")
      {
        target.addEventListener(eventType, functionRef, capture);
      }
      else if (typeof target.attachEvent != "undefined")
      {
        target.attachEvent("on" + eventType, functionRef);
      }
      else
      {
        eventType = "on" + eventType;
    
        if (typeof target[eventType] == "function")
        {
          var oldListener = target[eventType];
    
          target[eventType] = function()
          {
            oldListener();
    
            return functionRef();
          }
        }
        else
        {
          target[eventType] = functionRef;
        }
      }
    
      return true;
    }
    
    function getEventTarget(event)
    {
      var targetElement = null;
    
      if (typeof event.target != "undefined")
      {
        targetElement = event.target;
      }
      else
      {
        targetElement = event.srcElement;
      }
    
      while (targetElement.nodeType == 3 && targetElement.parentNode != null)
      {
        targetElement = targetElement.parentNode;
      }
    
      return targetElement;
    }
    
    function getViewportSize()
    {
      var size = [0,0];
    
      if (typeof window.innerWidth != 'undefined')
      {
        size = [
            window.innerWidth,
            window.innerHeight
        ];
      }
      else if (typeof document.documentElement != 'undefined'
          && typeof document.documentElement.clientWidth != 'undefined'
          && document.documentElement.clientWidth != 0)
      {
        size = [
            document.documentElement.clientWidth,
            document.documentElement.clientHeight
        ];
      }
      else
      {
        size = [
            document.getElementsByTagName('body')[0].clientWidth,
            document.getElementsByTagName('body')[0].clientHeight
        ];
      }
    
      return size;
    }
    
    function getScrollingPosition()
    {
      //array for X and Y scroll position
      var position = [0, 0];
    
      //if the window.pageYOffset property is supported
      if(typeof window.pageYOffset != 'undefined')
      {
        //store position values
        position = [
            window.pageXOffset,
            window.pageYOffset
        ];
      }
    
      //if the documentElement.scrollTop property is supported
      //and the value is greater than zero
      if(typeof document.documentElement.scrollTop != 'undefined'
        && document.documentElement.scrollTop > 0)
      {
        //store position values
        position = [
            document.documentElement.scrollLeft,
            document.documentElement.scrollTop
        ];
      }
    
      //if the body.scrollTop property is supported
      else if(typeof document.body.scrollTop != 'undefined')
      {
        //store position values
        position = [
            document.body.scrollLeft,
            document.body.scrollTop
        ];
      }
    
      //return the array
      return position;
    }
    
    function getElementsByAttribute(attribute, attributeValue)
    {
      var elementArray = new Array();
      var matchedArray = new Array();
    
      if (document.all)
      {
        elementArray = document.all;
      }
      else
      {
        elementArray = document.getElementsByTagName("*");
      }
    
      for (var i = 0; i < elementArray.length; i++)
      {
        if (attribute == "class")
        {
          var pattern = new RegExp("(^| )" + attributeValue + "( |$)");
    
          if (elementArray[i].className.match(pattern))
          {
            matchedArray[matchedArray.length] = elementArray[i];
          }
        }
        else if (attribute == "for")
        {
          if (elementArray[i].getAttribute("htmlFor") || elementArray[i].getAttribute("for"))
          {
            if (elementArray[i].htmlFor == attributeValue)
            {
              matchedArray[matchedArray.length] = elementArray[i];
            }
          }
        }
        else if (elementArray[i].getAttribute(attribute) == attributeValue)
        {
          matchedArray[matchedArray.length] = elementArray[i];
        }
      }
    
      return matchedArray;
    }
    Any help with this would be really appreciated

    Thanks in advance

    Streamer

  2. #2
    SitePoint Enthusiast Tygatur's Avatar
    Join Date
    Apr 2006
    Location
    Germany
    Posts
    53
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Believe me, this would be rather anoying for a vistor of your site.

    But if you are determined to do it, I suggest the following solution:
    Use an array which stores the position of the mouse every time it is moved.
    Then use setTimeout(); with dynamic delay times to move the tooltip towards the mouse.
    to code or not to code ?
    that's too much of a question for a signature.

  3. #3
    SitePoint Member
    Join Date
    Mar 2006
    Posts
    9
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Smile

    Hey Thanks

    Any chance of an example?

    I am fairly new to javascript. So a lot of stuff like this goes right over my head

    Thanks again

    Streamer


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •