admin管理员组

文章数量:1404927

Good day there

I have a site where I have lots of 'tooltips'. These tooltips are created when hovered on a certain part of text. The tooltip is a div block which appears on top all the other content on site, and is removed when the cursor is moved away from the text. Now, this tooltip is spawned only when the text has <a rel> with 'tooltip' class. The tooltip fetches data from MySQL database with XMLHttpRequest and with the rel tag. This all works very well but I have a one little problem. Tooltip.php, which is the main script for fetching data from MySQL (8,809 lines), sometimes takes a while to respond. For example if I just quickly move my cursor through the site and the cursor accidently hovered for 0.05 secs a text with <a rel> text, it will generate a tooltip even if my cursor is not any longer on the text. I want some sort of check to check is the cursor still on the same <a rel> text, before creating the actual tooltip.

HTML:

<a href="#" rel="1" onmouseover="createTooltip(event);" onmousemove="moveTooltip(event);" onmouseout="removeTooltip();" class="tooltip">A tooltip</a>

Javascript:

   function createTooltip(event)
   {
      var target = event.target || event.srcElement;
      var str = target.rel || target.parentNode.rel; 
      if (str === "" || !str)
      {  
         return;
      }

      if (window.XMLHttpRequest)
      {
         xmlhttp = new XMLHttpRequest();
      }
      else // for older IE clients
      {
         xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
      }

      xmlhttp.onreadystatechange = function()
      {
         if (xmlhttp.readyState==4 && xmlhttp.status==200)
         {
            var link = document.getElementsByClassName('tooltip');
            var oldTooltip = document.getElementsByClassName('object-tooltip'); // removing possible old tooltips...
            for (var k = 0; k < oldTooltip.length; k++)
            {
               if (oldTooltip[k])
               {
                  oldTooltip[k].remove();
               }
            }

            for (var i = 0; i < link.length; i++)
            {
               if (str == link[i].rel)
               {
                  var tooltip = document.createElement("div");
                  tooltip.setAttribute('class', 'object-tooltip');
                  tooltip.style.border = "solid 1px black";
                  tooltip.style.color = "white"; //"#99CC00";
                  tooltip.style.position = "fixed";
                  tooltip.style.width = "300px";
                  tooltip.style.left = event.clientX + 'px';
                  tooltip.style.top = event.clientY + 'px';
                  tooltip.style.padding = "5px 10px 5px 10px";
                  tooltip.style.margin = "-25px 0 0 60px";
                  tooltip.style.backgroundColor = "#0E0E0F";
                  tooltip.style.opacity = "0.9";
                  tooltip.style.display = "inline-block";
                  tooltip.style.zIndex = "100000";
                  tooltip.style.textDecoration = "none";
                  tooltip.style.textAlign = "left";
                  tooltip.innerHTML = xmlhttp.responseText;

                  link[i].parentNode.insertBefore(tooltip, link[i].nextSibling);
               }  
            }
         }
      };
      xmlhttp.open("GET", "./armory/tooltip.php?s="+str, true);
      xmlhttp.send();
   }

   function moveTooltip(event)
   {
      var tooltip = document.getElementsByClassName('object-tooltip');
      for (var i = 0; i < tooltip.length; i++)
      {
         tooltip[i].style.left = event.clientX + 'px';
         tooltip[i].style.top = event.clientY + 'px';
      }
   }

   function removeTooltip()
   {
      var tooltip = document.getElementsByClassName('object-tooltip'); // you can have only one tooltip active at time
      for (var i = 0; i < tooltip.length; i++)
      {
         tooltip[i].remove();
      }
   }

I will not share tooltip.php for the sake of your time. It only gets the rel attribute and searches MySQL database with the attribute and prints data back. Is it possible to check is the cursor still on the same text, before creating the tooltip?

The best regards

Good day there

I have a site where I have lots of 'tooltips'. These tooltips are created when hovered on a certain part of text. The tooltip is a div block which appears on top all the other content on site, and is removed when the cursor is moved away from the text. Now, this tooltip is spawned only when the text has <a rel> with 'tooltip' class. The tooltip fetches data from MySQL database with XMLHttpRequest and with the rel tag. This all works very well but I have a one little problem. Tooltip.php, which is the main script for fetching data from MySQL (8,809 lines), sometimes takes a while to respond. For example if I just quickly move my cursor through the site and the cursor accidently hovered for 0.05 secs a text with <a rel> text, it will generate a tooltip even if my cursor is not any longer on the text. I want some sort of check to check is the cursor still on the same <a rel> text, before creating the actual tooltip.

HTML:

<a href="#" rel="1" onmouseover="createTooltip(event);" onmousemove="moveTooltip(event);" onmouseout="removeTooltip();" class="tooltip">A tooltip</a>

Javascript:

   function createTooltip(event)
   {
      var target = event.target || event.srcElement;
      var str = target.rel || target.parentNode.rel; 
      if (str === "" || !str)
      {  
         return;
      }

      if (window.XMLHttpRequest)
      {
         xmlhttp = new XMLHttpRequest();
      }
      else // for older IE clients
      {
         xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
      }

      xmlhttp.onreadystatechange = function()
      {
         if (xmlhttp.readyState==4 && xmlhttp.status==200)
         {
            var link = document.getElementsByClassName('tooltip');
            var oldTooltip = document.getElementsByClassName('object-tooltip'); // removing possible old tooltips...
            for (var k = 0; k < oldTooltip.length; k++)
            {
               if (oldTooltip[k])
               {
                  oldTooltip[k].remove();
               }
            }

            for (var i = 0; i < link.length; i++)
            {
               if (str == link[i].rel)
               {
                  var tooltip = document.createElement("div");
                  tooltip.setAttribute('class', 'object-tooltip');
                  tooltip.style.border = "solid 1px black";
                  tooltip.style.color = "white"; //"#99CC00";
                  tooltip.style.position = "fixed";
                  tooltip.style.width = "300px";
                  tooltip.style.left = event.clientX + 'px';
                  tooltip.style.top = event.clientY + 'px';
                  tooltip.style.padding = "5px 10px 5px 10px";
                  tooltip.style.margin = "-25px 0 0 60px";
                  tooltip.style.backgroundColor = "#0E0E0F";
                  tooltip.style.opacity = "0.9";
                  tooltip.style.display = "inline-block";
                  tooltip.style.zIndex = "100000";
                  tooltip.style.textDecoration = "none";
                  tooltip.style.textAlign = "left";
                  tooltip.innerHTML = xmlhttp.responseText;

                  link[i].parentNode.insertBefore(tooltip, link[i].nextSibling);
               }  
            }
         }
      };
      xmlhttp.open("GET", "./armory/tooltip.php?s="+str, true);
      xmlhttp.send();
   }

   function moveTooltip(event)
   {
      var tooltip = document.getElementsByClassName('object-tooltip');
      for (var i = 0; i < tooltip.length; i++)
      {
         tooltip[i].style.left = event.clientX + 'px';
         tooltip[i].style.top = event.clientY + 'px';
      }
   }

   function removeTooltip()
   {
      var tooltip = document.getElementsByClassName('object-tooltip'); // you can have only one tooltip active at time
      for (var i = 0; i < tooltip.length; i++)
      {
         tooltip[i].remove();
      }
   }

I will not share tooltip.php for the sake of your time. It only gets the rel attribute and searches MySQL database with the attribute and prints data back. Is it possible to check is the cursor still on the same text, before creating the tooltip?

The best regards

Share Improve this question asked May 17, 2014 at 21:32 RobRob 1911 silver badge9 bronze badges 3
  • Rather wait a few (milli)seconds before starting the ajax request the check whether you need it, instead of cancelling it when you realize that you don't need it. – Bergi Commented May 17, 2014 at 21:52
  • I’m not sure if canceling the request is the best way to go about it – I’d maybe let it go through anyway and just not display the tooltip if the user moved the mouse away again – at least then the value is available immediately next time the user hovers the item. (Assuming you are at least storing the values for tooltips that where retrieved before already, and don’t do a request every time.) – C3roe Commented May 17, 2014 at 22:57
  • Good point. The data is stored, yes. But I rather personally would just abort the request. The tooltip.php has 8,809 lines and it has also douzens mysqli queries so in my opinion its better to abort it. But please share your opinions, I am open for suggestions :-) – Rob Commented May 17, 2014 at 23:16
Add a ment  | 

1 Answer 1

Reset to default 4

Welp, based on your current code, you need to add, for instance, a variable outside of the scope of your existing createTooltip function to bind the xhr request to, let's call it, xmlhttp to be aligned with your existing code

var xmlhttp; //not in a function

Now add an event listener for the mouseout function on the .tooltip class, then abort the xhr request.

document.querySelectorAll('.tooltip').addEventListener('mouseout', function(){
    xmlhttp.abort();
});

Now when the element with .tooltip triggers the mouseleave needless xmlhttprequests will be aborted.

本文标签: javascriptCancel XMLHttpRequestStack Overflow