I need to use JS no JQuery plugins to make a simple tooltip like on the image below.
Click on ? image should open this tooltip and click again on the same image to close it. I think that it's simple for someone with good JS knowledge but I can't do it anyway :(
This is something that I have tried I know it's not too much but I am simply stuck.
How to display it like on the image, how to hide it when it's open and how to add that little triangle in the corner?
myfiddle
<img id="info" src=".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;
}
I need to use JS no JQuery plugins to make a simple tooltip like on the image below.
Click on ? image should open this tooltip and click again on the same image to close it. I think that it's simple for someone with good JS knowledge but I can't do it anyway :(
This is something that I have tried I know it's not too much but I am simply stuck.
How to display it like on the image, how to hide it when it's open and how to add that little triangle in the corner?
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;
}
Share
Improve this question
edited Jul 8, 2021 at 10:11
Brian Tompsett - 汤莱恩
5,89372 gold badges61 silver badges133 bronze badges
asked Nov 22, 2013 at 21:12
11101110
6,83956 gold badges186 silver badges346 bronze badges
4
- 1 You need to explain your base of knowledge, which parts of this you know how to do, what you've found when you searched and which part of this problem you specifically need help with. In other words, you need to show you've at least put some base level of effort into getting started here and then show us where you got stuck. – jfriend00 Commented Nov 22, 2013 at 21:18
- I have tried with JQuery plugins and thats not good as I need pure JavaScript. I have tried some stuff but didn't get with anything really. I know just to show div on click but not to show it like this with arrow point to image that was clicked. So I don't have anything that is similar to this :( – 1110 Commented Nov 22, 2013 at 21:20
- I am shamed. I updated question I know it;s not too much but can't make what I want. I work very little with js. – 1110 Commented Nov 22, 2013 at 21:40
- @1110 this should do the trick now: jsfiddle/u93a3/1 – Matthew Graves Commented Nov 22, 2013 at 22:25
2 Answers
Reset to default 3Clean up the css and this will basically do it:
<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>
Edit: fixed formatting and a bug. jsfiddle: http://jsfiddle/u93a3/
Proof of concept:
The following markup in HTML: Create a div with class tooltip
, add image and a div with class info
with all text (can be multiple paragraphs if needed, scollbars is shown if necessary):
<div class='tooltip'>
<img src='craig_question_mark_icon1.png' alt='Help'/>
<div class='info'>
Some text to fill the box with.
</div>
</div>
The div.info
is set to display:none
in CSS.
When the page is loaded a pure javascript is running that draws an image of a triangle on a canvas-element, and then creates a div-element where the triangle is set as a background. Then, for every div.tooltip
:
- add a click-eventhandler to the image
- replace the
div.info
with adiv.info_container
- add a clone of the triangle-div to
div.info_container
- add the original
div.info
todiv.info_container
You can test it with this fiddle. It is tested successfully on 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 = ' ' // 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>