如何使用纯javascript制作此工具提示

时间:2013-11-22 21:12:24

标签: javascript html css javascript-events tooltip

我需要使用JS没有JQuery插件来制作一个简单的工具提示,如下图所示。

点击“?”图像应打开此工具提示,然后再次单击同一图像以关闭它。 我认为对于具有良好JS知识的人来说这很简单,但无论如何我都做不到:(

这是我尝试的东西,我知道它不是太多,但我只是卡住了。
如何在图像上显示它,如何在图像上隐藏它;打开以及如何在角落中添加那个小三角形?

myfiddle

<img id="info" src="http://www.craiglotter.co.za/wp-content/uploads/2009/12/craig_question_mark_icon1.png"/>
<div id="ttip">bla bla</div>

document.getElementById('info').addEventListener('click', function(){
    // how to check if it's visible so I can close tooltip
    document.getElementById('ttip').style.display="block";    
});

#info{margin-left:100px;margin-top:50px;}
#ttip
{
    width: 280px;
z-index: 15001;
top: 0px;
left: 0px;
display: none;
    border-color: #666;
background-color: #fff;
color: #666;
    position: relative;
border: 1px solid #666;
padding: 15px 9px 5px 9px;
text-align: left;
word-wrap: break-word;
overflow: hidden;
}

enter image description here

2 个答案:

答案 0 :(得分:3)

清理css,基本上会这样做:

<script>
    function doTip(e){
          var elem = e.toElement;
          if(elem.getAttribute('data-tip-on')  === 'false') {

            elem.setAttribute('data-tip-on', 'true');
            var rect = elem.getBoundingClientRect();          
            var tipId = Math.random().toString(36).substring(7);
            elem.setAttribute('data-tip-id', tipId);
            var tip = document.createElement("div");
            tip.setAttribute('id', tipId);
            tip.innerHTML = elem.getAttribute('data-tip');
            tip.style.top = rect.bottom+ 10 + 'px';
            tip.style.left = (rect.left-200) + 'px';
            tip.setAttribute('class','tip-box');
            document.body.appendChild(tip);

          } else {

            elem.setAttribute('data-tip-on', 'false');
            var tip = document.getElementById(elem.getAttribute('data-tip-id'));
            tip.parentNode.removeChild(tip);


          }
    }
    function enableTips(){
        var elems = document.getElementsByClassName('quick-tip');
        for(var i = 0; i < elems.length; i++) { 
            elems[0].addEventListener("click", doTip, false);

        }
    }
    window.onload = function(){
        enableTips();
    }
</script>
<style>
    .quick-tip {
        background: black;
        color: #fff;
        padding: 5px;
        cursor: pointer;
        height: 15px;
        width: 15px;
        text-align: center;
        font-weight: 900;
        margin-left: 350px;

    }
    .tip-box {
    /* change dimensions to be whatever the background image is */
        height: 50px;
        width: 200px;
        background: grey;
        border: 1px solid black; 
        position: absolute;
    }
</style>


<div class="quick-tip" data-tip="THIS IS THE TIP! change elements 'data-tip' to change." data-tip-on="false">?</div>

<script>enableTips(); //might be required for jsfiddle, especially with reloads.</script>

编辑:修复格式和错误。 jsfiddle:http://jsfiddle.net/u93a3/

答案 1 :(得分:2)

概念证明:

HTML中的以下标记:使用类tooltip创建div,使用所有文本添加图像和带有info类的div(如果需要,可以是多个段落,必要时会显示scollbars):

<div class='tooltip'>
  <img src='craig_question_mark_icon1.png' alt='Help'/>
  <div class='info'>
    Some text to fill the box with.
  </div>
</div>

CSS中div.info设置为display:none

当加载页面时,正在运行一个纯javascript,它在canvas-element上绘制一个三角形的图像,然后创建一个div元素,其中三角形被设置为背景。然后,对于每个div.tooltip

  1. 向图片添加click-eventhandler
  2. div.info替换为div.info_container
  3. 将triangle-div的克隆添加到div.info_container
  4. 将原始div.info添加到div.info_container
  5. 您可以使用此fiddle进行测试。它在FF25,Chrome31,IE10,Opera 12和18上成功测试。

    <!doctype html>
    <html>
      <head>
        <script>
          "use strict";
          function click(event) {
            var elem = this.parentNode.querySelector('div.info_container');
            if (elem) elem.style.display = elem.style.display === 'block' ? 'none' : 'block';
          }
          function toolify() {
            var idx,
                len,
                elem,
                info,
                text,
                elements = document.querySelectorAll('div.tooltip'),
                canvas,
                imgurl,
                pointer,
                tipHeight = 20,
                tipWidth = 20,
                width = 200,
                height = 100,
                ctx;
    
            // Create a canvas element where the triangle will be drawn
            canvas = document.createElement('canvas');
            canvas.width = tipHeight;
            canvas.height = tipWidth;
            ctx = canvas.getContext('2d');
    
            ctx.strokeStyle = '#000';   // Border color
            ctx.fillStyle = '#fff';     // background color
            ctx.lineWidth = 1;
    
            ctx.translate(-0.5,-0.5);   // Move half pixel to make sharp lines
            ctx.beginPath();
            ctx.moveTo(1,canvas.height);              // lower left corner
            ctx.lineTo(canvas.width, 1);              // upper right corner
            ctx.lineTo(canvas.width,canvas.height);   // lower right corner
            ctx.fill();                               // fill the background
            ctx.stroke();                             // stroke it with border
            //fix bottom row
            ctx.fillRect(0,canvas.height-0.5,canvas.width-1,canvas.height+2);
    
            // Create a div element where the triangel will be set as background
            pointer = document.createElement('div');
            pointer.style.width = canvas.width + 'px';
            pointer.style.height = canvas.height + 'px';
            pointer.innerHTML = '&nbsp;' // non breaking space
            pointer.style.backgroundImage = 'url(' + canvas.toDataURL() + ')';
            pointer.style.position = 'absolute';
            pointer.style.top = '2px';
            pointer.style.right = '1px';
            pointer.style.zIndex = '1'; // place it over the other elements
    
            for (idx=0, len=elements.length; idx < len; ++idx) {
              elem = elements[idx];
              elem.querySelector('img').addEventListener('click',click);
              text = elem.querySelector('div.info');
              // Create a new div element, and place the text and pointer in it
              info = document.createElement('div');
              text.parentNode.replaceChild(info,text);
              info.className = 'info_container';
              info.appendChild(pointer.cloneNode());
              info.appendChild(text);
              //info.addEventListener('click',click);
            }
          }
          window.addEventListener('load',toolify);
        </script>
        <style>
          div.tooltip
          {
            position:relative;
            display:inline-block;
            width:300px;
            text-align:right;
          }
          div.tooltip > div.info
          {
            display:none;
          }
          div.tooltip div.info_container
          {
            position:absolute;
            right:20px;
            width:200px;
            height:100px;
            display:none;
          }
          div.tooltip div.info
          {
            text-align:left;
            position:absolute;
            left:1px;
            right:1px;
            top:20px;
            bottom:1px;
            color:#000;
            padding:5px;
            overflow:auto;
            border:1px solid #000;
          }
        </style>
      </head>
      <body>
        <div class='tooltip'>
          <img src='craig_question_mark_icon1.png' alt='Help'/>
          <div class='info'>
            Some text to fill the box with.
          </div>
        </div>
        <div class='tooltip'>
          <img src='craig_question_mark_icon1.png' alt='Help'/>
          <div class='info'>
            Some text to fill the box with.
            Some text to fill the box with.
            Some text to fill the box with.
            Some text to fill the box with.
          </div>
        </div>
      </body>
    </html>