Show the hovered element for a child element using jquery - javascript

I have three buttons for instance. On hover each I calculate the x and y axis of the mouse using jQuery and show a border to the hovered element. For individual elements, the hovering works fine. But for child elements, only the parent element shows border. The code used for the sample.
$(document).ready(function(){
$(document).mousemove(function(event){
$(".button").removeClass('active')
$('.button').each(function(){
var position = $(this).position();
var width = $(this).width()
var height = $(this).height()
var x1 = position.left
var y1 = position.top
var x2 = x1+width
var y2 = y1+height
if (event.pageX > x1 && event.pageX < x2 && event.pageY > y1 && event.pageY < y2){
$("span").text(event.pageX + ", " + event.pageY);
$(this).addClass('active')
}
});
});
});
.button{
width:150px;
height:35px;
display:block;
position:absolute;
pointer-events: none;
border:1px solid transparent;
}
.button.x{ top:10%; left;35%;}
.button.y{top:40%; left;35%;}
.button.z{top:20%; left;35%;}
.button.active{
border-color:blue;
pointer-events: auto;
border:1px solid;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="button x">
Hello
<div class="button y">
Hello
</div>
</div>
<div class="button z">
Hello
</div>
<span></span>

It's a common mistake, due in part to the naming of the jQuery methods involved (IMHO). You're using position ("Get the current coordinates...relative to the offset parent.") where you want to use offset ("Get the current coordinates...relative to the document."):
var position = $(this).offset();
Updated Example (easiest to see if you hit the Full Page link) (I've also added backgrounds to the nested elements and tweaked the border that gets added, to make it clearer when the mouse is over them):
$(document).ready(function(){
$(document).mousemove(function(event){
$(".button").removeClass('active')
$('.button').each(function(){
var position = $(this).offset();
var width = $(this).width()
var height = $(this).height()
var x1 = position.left
var y1 = position.top
var x2 = x1+width
var y2 = y1+height
if (event.pageX > x1 && event.pageX < x2 && event.pageY > y1 && event.pageY < y2){
$("span").text(event.pageX + ", " + event.pageY);
$(this).addClass('active')
}
});
});
});
.button{
width:150px;
height:35px;
display:block;
position:absolute;
pointer-events: none;
border:1px solid transparent;
}
.button.x{ top:10%; left;35%;}
.button.y{top:40%; left;35%;}
.button.z{top:20%; left;35%;}
.button.active{
pointer-events: auto;
border:2px solid red;
}
.button.x {
background-color: #00d;
}
.button.y {
background-color: #0d0;
}
<div class="button x">
Hello
<div class="button y">
Hello
</div>
</div>
<div class="button z">
Hello
</div>
<span></span>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
Or do it with CSS:
.button:hover {
border-color:blue;
pointer-events: auto;
border:1px solid;
}
(And remove pointer-events: none; from .button.)
Live Example (with the same visibility tweaks):
.button{
width:150px;
height:35px;
display:block;
position:absolute;
/*pointer-events: none;*/
border:1px solid transparent;
}
.button.x{ top:10%; left;35%;}
.button.y{top:40%; left;35%;}
.button.z{top:20%; left;35%;}
.button:hover {
pointer-events: auto;
border:2px solid red;
}
.button.x {
background-color: #00d;
}
.button.y {
background-color: #0d0;
}
<div class="button x">
Hello
<div class="button y">
Hello
</div>
</div>
<div class="button z">
Hello
</div>
<span></span>

Related

How to scroll to specific element

I try to create an effect that when a user is on the hero section(which uses 100vh) and scrolls down it immediately scrolls to a specific element and same when the user is at that specific element and scrolls up it takes him to the hero section
$(document).ready(function(){
$(window).scroll(function(){
var x = $("#scroll-to").offset();
var height1 = $("#scroll-to").outerHeight();
var y = document.documentElement.scrollTop;
var z = (x.top + height1) - y;
if(z < $(window).height()){
document.querySelector('#scroll-anchor').scrollIntoView({
behavior: 'smooth'
});
}
});
});
using HTML id and tag and using the id as href in the link
.blue{
background-color: blue;
min-width: 100px;
min-height:700px;
}
.red{
background-color: red;
min-width: 100px;
min-height:700px;
}
red
<div class="blue" id="blue"></div>
<div class="red" id="red"></div>

Show table in a tooltip with jQuery

I'm trying to show HTML code inside a tooltip (div, table,...), but it doesn't show up and it doesn't show any errors.
If I use the <span> tag with some text inside it, it works correctly. But I need to insert more HTML code inside it. How can I fix it?
Only works with <span> tag, and I don't know how to solve this problem, any help? Why is this happening?
$(document).ready(function() {
//Tooltips
$(".tip_trigger").hover(function(){
tip = $(this).find('.tip');
tip.show(); //Show tooltip
}, function() {
tip.hide(); //Hide tooltip
}).mousemove(function(e) {
var mousex = e.pageX + 20; //Get X coodrinates
var mousey = e.pageY + 20; //Get Y coordinates
var tipWidth = tip.width(); //Find width of tooltip
var tipHeight = tip.height(); //Find height of tooltip
//Distance of element from the right edge of viewport
var tipVisX = $(window).width() - (mousex + tipWidth);
//Distance of element from the bottom of viewport
var tipVisY = $(window).height() - (mousey + tipHeight);
if ( tipVisX < 20 ) { //If tooltip exceeds the X coordinate of viewport
mousex = e.pageX - tipWidth - 20;
} if ( tipVisY < 20 ) { //If tooltip exceeds the Y coordinate of viewport
mousey = e.pageY - tipHeight - 20;
}
tip.css({ top: mousey, left: mousex });
});
});
body {
margin: 0; padding: 0;
font: normal 12px Verdana, Geneva, sans-serif;
line-height: 1.8em;
color: #333;
}
* {
outline: none;
}
img {border: none;}
a {color: #d60000; text-decoration: none;}
/*--Tooltip Styles--*/
.tip {
display: inline-block;
color: #fff;
background:#1d1d1d;
display:none; /*--Hides by default--*/
padding:10px;
position:absolute; z-index:1000;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<p style="text-align:left;">My First
<a href="#" class="tip_trigger">Link
<span class="tip">
Some text. Works correctly!
</span>
</a>
</p>
<p style="text-align:left;">My Second
<a href="#" class="tip_trigger">Link
<div class="tip">
<table><tr><td>More text. Doesn't work!</td></tr></table>
</div>
</a>
</p>
Your issue is with the type of elements you put inside of other elements.
For example:
You can not put a <div> inside of an <a> or a <p>
See here: Putting <div> inside <p> is adding an extra <p>
I updated your example code with a working one.
$(document).ready(function() {
//Tooltips
$(".tip_trigger").hover(function(){
tip = $(this).siblings('.tip');
tip.show(); //Show tooltip
}, function() {
tip.hide(); //Hide tooltip
}).mousemove(function(e) {
var mousex = e.pageX + 20; //Get X coodrinates
var mousey = e.pageY + 20; //Get Y coordinates
var tipWidth = tip.width(); //Find width of tooltip
var tipHeight = tip.height(); //Find height of tooltip
//Distance of element from the right edge of viewport
var tipVisX = $(window).width() - (mousex + tipWidth);
//Distance of element from the bottom of viewport
var tipVisY = $(window).height() - (mousey + tipHeight);
if ( tipVisX < 20 ) { //If tooltip exceeds the X coordinate of viewport
mousex = e.pageX - tipWidth - 20;
} if ( tipVisY < 20 ) { //If tooltip exceeds the Y coordinate of viewport
mousey = e.pageY - tipHeight - 20;
}
tip.css({ top: mousey, left: mousex });
});
});
body {
margin: 0; padding: 0;
font: normal 12px Verdana, Geneva, sans-serif;
line-height: 1.8em;
color: #333;
}
* {
outline: none;
}
img {border: none;}
a {color: #d60000; text-decoration: none;}
/*--Tooltip Styles--*/
.tip {
display: none;
color: #fff;
background:#1d1d1d;
display:none; /*--Hides by default--*/
padding:10px;
position:absolute; z-index:1000;
-webkit-border-radius: 3px;
-moz-border-radius: 3px;
border-radius: 3px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<p style="text-align:left;">My First
<a href="#" class="tip_trigger">Link
</a>
<span class="tip">
Some text. Works correctly!
</span>
</p>
<div style="text-align:left;">My Second
Link
<div class="tip">
<table><tr><td>More text. Doesn't work!</td></tr></table>
</div>
</div>

clientx property with mousedown is not giving desired coordinate?

In the following code, I want the mouse position within the red button, for that, I have used clientX property with mousedown event.
but mousedown is not giving expected result instead it is giving clientX property in whole parent div?
In docs, it is mentioned that clientx will return mouse x position in local dom content and that should be the button!
link: http://devdocs.io/dom_events/mousedown
try clicking on the right most button, I already did console.log the value and the result are around -600 but it should be positive and within 60 range, why is the event not getting the correct value?
code: https://jsfiddle.net/nk2059sf/
var button1 = document.querySelector("#button1"),
button2 = document.querySelector("#button2"),
slider = document.querySelector(".slider"),
ae = 0,
be = 0,
sliderwidth = slider.clientWidth;
button1.addEventListener("mousedown", function(e){
var e = e||window.event;
ae = e.clientX;
console.log(ae);
});
button2.addEventListener("mousedown", function(e){
var e = e||window.event;
be = button2.clientWidth - e.clientX;
console.log(be);
});
html, body{
width: 100%;
height: 100%;
}
.slider{
max-width:700px;
height:50px;
background-color:#a0a0a0;
display:flex;
align-items:center;
box-sizing: border-box;
}
.slider div{
display: inline-block;
}
.button{
width:60px;
height:60px;
border-radius:30px;
background-color:red;
z-index: 100;
}
.button:hover{
cursor:pointer;
}
.range{
flex-grow:2;
height:50px;
background-color:blue;
margin: 0 -30px;
}
<body>
<div class="slider">
<div class="button" id="button1"></div>
<div class="range"></div>
<div class="button" id="button2"></div>
</div>
</body>

Zoom container with div using transform translate and scale

I would like to zoom a container with divs on click, using only css transform and scale. The problem is, that it works only on first click, on second, third... my divs are translating strange. For me very thing important is to scale background.
var scale =0.5;
var interval = 5;
var line_weight =1;
$('document').ready(function(){
$('#container').click(function(){
$('.test').each(function(i){
var position = $(this).position();
var positionL=position.left;
var positionT=position.top;
var positionTscale=positionT*scale;
var positionLscale=positionL*scale;
var translateX = -(positionL-positionLscale)*(1/scale);
var translateY = -(positionT-positionTscale) *(1/scale);
$(this).css( 'transform', 'scale('+ scale +')' + ' translate('+ translateX + 'px'+','+ translateY +'px )' );
});
$(".test").css('background', 'repeating-linear-gradient(0deg, #000, #000' + line_weight/scale+ ' #ffffff 0, #ffffff ' + scale*interval+ 'px');
$(".test").css('border-right', (line_weight) +'px solid');
});
$('#container').dblclick(function(){
$(".test").css('transform', 'scale(1.0)');
$(".test").css('background', 'repeating-linear-gradient(0deg, #000, #000' +line_weight+' , #ffffff 0, #ffffff ' + interval + 'px');
$(".test").css('border-right', line_weight+'px solid');
});
});
</script>
body{
width: 19200px;
height: 10750px;
}
.test{
height: 200px;
width: 160px;
display: inline-block;
border-right: 1px solid;
background: repeating-linear-gradient(0deg, #000, #000 1px, #ffffff 0, #ffffff 5px);
}
#container{
width: 340px;
height: 400px;
}
.column{
display: inline-block;
}
<script src="jquery-3.0.0.min.js"></script>
<body>
<div id="container">
<div>
<div class="test" >
<p class="click">test1</p>
</div>
<div class="test" >
<p class="click">test2</p>
</div>
</div>
<div>
<div class="test">
<p class="click">test3</p>
</div>
<div class="test">
<p class="click">test4</p>
</div>
</div>
</div>
</body>
Code on jsfiiddle
What you need is just change the value in transform: scale(value).
I added two buttons for the example for you to zoom in and zoom out:
<p class="zoom _bigger">
zoom++
</p>
<p class="zoom _smaller">
zoom--
</p>
And here is all js to solve your problem:
$('document').ready(function(){
// We set value as 2, because further we will zoom with a half
var zoomValue = 2;
$('.zoom').on('click', function(){
if ($(this).hasClass('_bigger')) {
zoomValue++;
} else if (zoomValue > 2) {
zoomValue--;
} else {
return false;
}
$('#container').css('transform', 'scale(' + zoomValue * 0.5 + ')');
});
});
I used a half value for zooming, and you can play with it and set what you wish.
You can check out my example on jsfiddle.

How to make this tooltip like this with pure javascript

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;
}
Clean 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.net/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 a div.info_container
add a clone of the triangle-div to div.info_container
add the original div.info to div.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>

Categories