how to display different div on button click with JS? - javascript

I am trying to make a section where there are 2 cards, each one with a button and a small descriptive text.
What I am trying to achieve is that when I click on the button 3 things happen:
1 The button changes content, that goes from a "+" to a "-", but that is what worries me the least.
2 that a div is displayed with information corresponding to that card and that occupies 100 vw
and
3 that if there is a div displayed and the other button on another card is clicked, the first div disappears and the second appears and occupies the 100vw
-----What am I using? I am using HTML5, CSS, Vanilla Js, Bootstrap (mainly for the css)-----
This is what I want to achieve:
This is what I have achieved:
var jsaccordion = {
init : function (target) {
var headers = document.querySelectorAll("#" + target + " .accordion-btn");
if (headers.length > 0) { for (var head of headers) {
head.addEventListener("click", jsaccordion.select);
}}
},
select : function () {
this.classList.toggle("open");
}
};
window.addEventListener('load', function(){
jsaccordion.init("accordion-container");
});
.accordion-text {
display: none;
color: #808080;
padding: 15px;
border: 1px solid #ffcc4b;
}
.accordion-btn.open + .accordion-text{
display: block;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class='row'>
<div id="accordion-container" class='col-6'>
<div class="my-3">
<h3 class=" text-center">First one</h3>
<button class='mx-auto d-block accordion-btn btn btn-white border-primary'>+</button>
<div class="accordion-text">
<p>
some specific and special information for the first div.</p>
</div>
</div>
</div>
<div id="accordion-container" class='col-6'>
<div class="my-3">
<h3 class='text-center'>second one</h3>
<button class='mx-auto d-block accordion-btn btn btn-white border-primary'>+</button>
<div class="accordion-text">
<p>some specific and special information for the second div.</p>
</div>
</div>
</div>
</div>
Please help me, I don't know how to do it

It is a lot easier to do this in jQuery, but here is how I would approach it using Vanilla JS.
The idea is that to center something that is based on neither elements, but moreso the browser window, is to use a shared container (outside of either element) to print to. This takes the guess work out of positioning as well.
On clicking the button, the information should be copied from the accordion, and printed to the target container. Also on that click, check if the other is active to remove the active class. Adding classes to the active container to change the button symbol + and -, using CSS pseudo-elements.
Keeping the arrows inside the accordion containers will also make it easier to position them according to the HTML element it is in.
Sidenote: You should only use an HTML ID once on the entire page, otherwise use a class for multiple instances. This is in reference to #accordion-container.
var sharedCont = document.getElementById('shared-container');
var allCont = document.querySelectorAll('#accordion-container');
var jsaccordion = {
init : function (target) {
var headers = document.querySelectorAll("#" + target + " .accordion-btn");
if (headers.length > 0) { for (var head of headers) {
head.addEventListener("click", jsaccordion.select);
}}
},
select : function () {
var targ1 = this.parentElement.closest('#accordion-container'), // find parent
targText = targ1.querySelector('.accordion-text').innerHTML; // grab text for shared container
if( targ1.classList.contains('active') ){
// when clicked, if active, reset them all
targ1.classList.remove('active');
sharedCont.innerHTML = '';
sharedCont.classList.remove('active');
} else {
// when clicked, reset them all, then activate
for (let i = 0; i < allCont.length; i++) {
var el = allCont[i];
el.classList.remove('active');
}
targ1.classList.add('active');
sharedCont.innerHTML = targText;
sharedCont.classList.add('active');
}
}
};
window.addEventListener('load', function(){
jsaccordion.init("accordion-container");
});
body {
max-width: 90%;
margin: 0 auto;
overflow: hidden;
}
#accordion-container {
position: relative;
}
#accordion-container button::before {
content: '+' !important;
}
#accordion-container.active button::before {
content: '-' !important;
}
#accordion-container.active::after {
content: '';
width: 0;
height: 0;
border-left: 15px solid transparent;
border-right: 15px solid transparent;
border-bottom: 15px solid orange;
position: absolute;
bottom: -2rem;
left: 50%;
transform: translateX(-50%);
color: orange;
z-index: 100;
font-size: 3rem;
line-height: 1;
}
#accordion-container .accordion-text {
display: none;
color: #808080;
padding: 15px;
border: 1px solid #ffcc4b;
}
/* .accordion-btn.open + .accordion-text{
display: block;
} */
#shared-container {
margin-top: 2rem;
display: block;
width: 100%;
padding: 2rem;
border: 1px solid orange;
display: none;
}
#shared-container.active {
display: block;
text-align: center;
}
#shared-container p {
margin: 0;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>Testing testing testing</h1>
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet"/>
<div class='row'>
<div id="accordion-container" class='col-6'>
<div class="my-3">
<h3 class=" text-center">First one</h3>
<button class='mx-auto d-block accordion-btn btn btn-white border-primary'></button>
<div class="accordion-text">
<p>Egestas erat imperdiet sed euismod nisi porta. Ipsum dolor sit amet consectetur adipiscing. Maecenas pharetra convallis posuere morbi leo urna molestie. Nullam vehicula ipsum a arcu. Gravida cum sociis natoque penatibus et magnis. Duis convallis convallis tellus id interdum velit laoreet. </p>
</div>
</div>
</div>
<div id="accordion-container" class='col-6'>
<div class="my-3">
<h3 class='text-center'>second one</h3>
<button class='mx-auto d-block accordion-btn btn btn-white border-primary'></button>
<div class="accordion-text">
<p>Tempus egestas sed sed risus pretium quam vulputate dignissim. Risus at ultrices mi tempus imperdiet. Mauris pellentesque pulvinar pellentesque habitant morbi tristique senectus et. Nisl vel pretium lectus quam id leo.</p>
</div>
</div>
</div>
</div>
<div id="shared-container"></div>
</body>
</html>

Its very simple you can assign id or class to those div, you want to hide or show then use javascript or jquery method to show and hide on the specific event click.

A small snippet of working example. It can be optimized and made dynamic.
Also as Owais suggested, we can simply use .show() and .hide() instead of .addClass() and .removeClass()
var firstDiv = $("#div-1-1");
var secondDiv = $("#div-1-2");
$(document).ready(function() {
//On Click of 1st Div, we're also toggling the 2nd DIV in case if it was open
// Can handle in a better way as well
// Same goes for the 2nd div
firstDiv.click(() => {
$(".dc-11").addClass("open");
$(".dc-12").removeClass("open");
});
secondDiv.click(() => {
$(".dc-12").addClass("open");
$(".dc-11").removeClass("open");
});
});
.outer-block {
width: 200px;
margin: auto;
}
.block {
display: flex;
}
.block>div {
flex: 1;
text-align: center;
border: 2px solid red;
height: 80px;
}
.open {
display: block !important;
}
.dc-11 {
background: red;
display: none;
}
.dc-12 {
background: orange;
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>
<div class='outer-block'>
<div class="block">
<div>
<p>First</p>
<button id="div-1-1">+</button>
</div>
<div>
<p>Second</p>
<button id="div-1-2">+</button>
</div>
</div>
<div id="div-1-1-content" class="dc-11">First Div Content will be displayed here</div>
<div id="div-1-2-content" class="dc-12">Second Div Content will be displayed here</div>
</div>
</div>

Related

Swiper.js not working correctly, not rendering slide amounts right

I am trying to achieve a design where each slide is 675px in width, and they overflow off of the right side of the page where each user can swipe.
But, when I hardcode the element to be 675px, swiper.js does not calculate the width correctly unless I pass slidesPerView={1}, and then I only see one slide per page and can swipe to see other ones, again, only one per page.
How it looks currently, on slidesPerView={1} OR slidesPerView={auto}
How I want it to look (imagine red boxes are filled)
Here is my code:
index.js
<section className="projects">
<div className="container--main-extended">
<div className="projects__inner">
<div className="projects__header">
<Heading subText="Projects">Examples of my work</Heading>
</div>
<div className="projects__projectList">
<Swiper
slidesPerView={'auto'}
spaceBetween={20}
onSlideChange={() => console.log("slide change")}
onSwiper={(swiper) => console.log(swiper)}
>
{projects.map((project) => (
<SwiperSlide>
<Project project={project} />
</SwiperSlide>
))}
</Swiper>
</div>
</div>
</div>
</section>
Project.jsx
import ProjectImage from "../atoms/ProjectImage";
const Project = ({ project }) => {
const techStack = [
"React",
"Next.js",
"TailwindCSS",
"Framer Motion",
"TailwindCSS",
];
return (
<a href="#" class="project__link">
<div className="project">
<div className="project__images">
<ProjectImage
type={project.imageStype}
background={project.background}
images={project.images}
/>
</div>
<div className="project__header">
<h2 className="heading--4 clr--text">{project.name}</h2>
</div>
<div className="project__techStack">
<ul>
{techStack.map((tech) => (
<li className="project__techStack--item copy--1 clr--text-dark">
{tech}
</li>
))}
</ul>
</div>
<div className="project__desc">
<p class="copy--1 clr--text">
Aliquam vitae magna quis est sodales pulvinar. Aenean gravida ac
dolor ac iaculis. Nullam euismod massa vitae viverra volutpat.
Quisque ut massa vel nisl tempor fringilla. Mauris purus arcu,
fermentum id laoreet eu, molestie tincidunt ipsum. Nulla facilisi.
Vestibulum odio ipsum.
</p>
</div>
</div>
</a>
);
};
export default Project;
projects.scss
.projects {
padding-bottom: rem(500);
&__projectList {
// display: flex;
// gap: rem(20);
}
}
.project {
display: block;
margin: 0 auto;
&__link {
display: block;
width: 675px;
height: rem(600);
background: red;
}
&:not(:last-child) {
margin-left: rem(20);
}
&__image {
margin-bottom: rem(30);
img {
width: 100%;
height: 100%;
object-fit: cover;
}
}
&__header {
margin-bottom: rem(8);
height: rem(70);
}
&__techStack {
margin-bottom: rem(24);
ul {
display: flex;
flex-wrap: wrap;
gap: rem(10);
}
}
&__images {
height: rem(800);
background: red;
}
}
.swiper-container {
margin-right: auto;
position: relative;
overflow: hidden;
list-style: none;
padding: 0;
z-index: 1;
}
finally, I am using swiper version 9.0.2

Vertical align text middle to image when text is less

I have a text-image component, and i need to vertical-align text middle to the floated image , if the text is less (condition one) (for larger screens). if the text is more then let it wrap around the floated image (condition two) (again for larger screens). How can i do this in CSS or do we need Javascript for this? Here is fiddle. Both my conditions one and two should work.
.clearfix { clear: both; }
.text-img { padding-left: 15px; padding-right: 15px; }
.text-img .info-box .info--body p { max-width: none; }
.text-img .info-box { text-align: justify; }
.text-img .stock-img { width: 100%; }
#media (min-width: 992px) {
.text-img.text-right .stock-img { width: 50%; float: left; }
.text-img.text-right .stock-img { padding-right: 15px; padding-bottom: 15px; }
.text-img.text-left .stock-img { width: 50%; float: right; }
.text-img.text-left .stock-img { padding-left: 15px; padding-bottom: 15px; }
}
<div class="clearfix text-img text-left">
<img src="https://cdn0.vox-cdn.com/thumbor/gvDQZLtlEM7U99rmTEdMoUtLRJU=/0x96:2039x1243/1600x900/cdn0.vox-cdn.com/uploads/chorus_image/image/50319283/ipad1_2040.0.0.jpg" alt="iPad" class="img-responsive stock-img" />
<div class="info-box">
<header class="info--header">
<h3 class="h3">The science of today is the technology of tomorrow.</h3>
</header>
<div class="info--body">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc semper urna nec lectus malesuada tincidunt. Aenean faucibus, nulla sed luctus tempus, purus libero vestibulum velit, et blandit odio nunc ac quam. Donec tellus tellus, venenatis ac diam nec, sodales viverra orci.</p>
</div>
</div>
</div>
I want the final output to be like this, which satisfys both my condition:
Well the answers given are right, this cannot be solved just by CSS alone, so i had to come up with jQuery solution. For those looking for solution for such scenarios, here is jQuery code that solved my problem:
$(document).ready(function() {
$(".text-img").each( function() {
var cH = parseInt( $( this ).height() );
var tH = parseInt( $( this ).find('.info-box').height() );
if( tH < cH ) {
var pt = ( cH - tH ) / 2;
$( this ).find('.info-box').css({
"padding-top" : pt + "px"
});
}
});
});
Use a flex box layout when you are in the smaller screens.
#media (min-width: 992px) {
.text-left {
display: flex;
align-items: center;
justify-content: center;
}
.text-left img {
max-width: 50%;
height: auto;
margin-right: 10px;
}
}
Preview
Output: http://jsbin.com/lulecudaji/edit?html,css,output
I would recommend you better/older than flex-box tick for centring elements.
For horizontal centring use simply text-align: center; on container div
For vertical centring uses propoerty of display inline-block elements which aligned in to the middle to center all display inline-block in the line.
Making it bigger i'll move other elements to the center
Making it 100% height causes the othere elements centers to the middle.
You simply need to create ghost (not visible) - red element to center content - blue and green elements.
For ghost element use for it before or after of conteiner div:
.continer:before {
content: '';
display: inline-block;
height: 100%;
vertical-align: middle;
}
And display inline-block your content:
.content{
display: inline-block;
}
Of course delete position:absolute etc.
Last tweak will be to get rid of that small spaces between elements (especially between red and others) use one of the tricks from here: https://css-tricks.com/fighting-the-space-between-inline-block-elements/
Probably you will need to set font size to zero.
More about ghost elements:
https://css-tricks.com/centering-in-the-unknown/

Display a Modal on button click using Jquery

I want to display my Modal on button click. Below is my code.
<input type="button" id="button1" value="Button" onclick="myFunction()"/>
<div id="openModal" class="modalDialog">
<div>
X
<h2>
Modal Box</h2>
<p>
Hello world</p>
</div>
</div>
This is my unfinished script.
<script type="text/javascript">
$(document).ready(function () {
});
</script>
show openModal div on button1 click.
$('#button1').on('click', function() {
$('#openModal').show();
});
No need of onclick="myFunction()" on button
Let's try...
Simple popup model created by using jquery, HTML, and CSS.
$(function() {
// Open Popup
$('[popup-open]').on('click', function() {
var popup_name = $(this).attr('popup-open');
$('[popup-name="' + popup_name + '"]').fadeIn(300);
});
// Close Popup
$('[popup-close]').on('click', function() {
var popup_name = $(this).attr('popup-close');
$('[popup-name="' + popup_name + '"]').fadeOut(300);
});
// Close Popup When Click Outside
$('.popup').on('click', function() {
var popup_name = $(this).find('[popup-close]').attr('popup-close');
$('[popup-name="' + popup_name + '"]').fadeOut(300);
}).children().click(function() {
return false;
});
});
body {
font-family:Arial, Helvetica, sans-serif;
}
p {
font-size: 16px;
line-height: 26px;
letter-spacing: 0.5px;
color: #484848;
}
/* Popup Open button */
.open-button{
color:#FFF;
background:#0066CC;
padding:10px;
text-decoration:none;
border:1px solid #0157ad;
border-radius:3px;
}
.open-button:hover{
background:#01478e;
}
.popup {
position:fixed;
top:0px;
left:0px;
background:rgba(0,0,0,0.75);
width:100%;
height:100%;
display:none;
}
/* Popup inner div */
.popup-content {
width: 500px;
margin: 0 auto;
box-sizing: border-box;
padding: 40px;
margin-top: 20px;
box-shadow: 0px 2px 6px rgba(0,0,0,1);
border-radius: 3px;
background: #fff;
position: relative;
}
/* Popup close button */
.close-button {
width: 25px;
height: 25px;
position: absolute;
top: -10px;
right: -10px;
border-radius: 20px;
background: rgba(0,0,0,0.8);
font-size: 20px;
text-align: center;
color: #fff;
text-decoration:none;
}
.close-button:hover {
background: rgba(0,0,0,1);
}
#media screen and (max-width: 720px) {
.popup-content {
width:90%;
}
}
<!DOCTYPE html>
<html>
<head>
<title> Popup </title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
</head>
<body>
<a class="open-button" popup-open="popup-1" href="javascript:void(0)"> Popup
Preview</a>
<div class="popup" popup-name="popup-1">
<div class="popup-content">
<h2>Model </h2>
<p>Model content will be here. Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Aliquam consequat diam ut tortor
dignissim, vel accumsan libero venenatis. Nunc pretium volutpat
convallis. Integer at metus eget neque hendrerit vestibulum.
Aenean vel mattis purus. Fusce condimentum auctor tellus eget
ullamcorper. Vestibulum sagittis pharetra tellus mollis vestibulum.
Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<a class="close-button" popup-close="popup-1" href="javascript:void(0)">x</a>
</div>
</div>
</body>
</html>
Change show() to modal.show();
$('#button1').on('click', function() {
$('#openModal').modal('show');
});
You probably have to set visibility:hidden; to the div, and set it to visible onclick

Menu Popping up and down HTML [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 years ago.
Improve this question
[I can't use JQuery, if you wanted to know.]
I'm trying to make my Menu come up and down. (Duh) I don't know how else to explain it, I want so if you put your cursor near the top of the screen, the menu will slide down from the top, (like an animation), and it will go back up when you move your cursor away from the top of the screen.
Code:
body {
background-color: #eeeeee;
}
Rounded {
padding: 17px 17px;
padding-top: 50px;
background: #dddddd;
border-radius: 25px;
}
Header {
font-style: arial;
font-size: 20px;
font-weight: 3px;
font-size-adjust: bottom;
color: #ededed;
}
Black {
color: 000000;
}
Backer {
}
Bod {
padding 15px 15px;
padding-left: 150px;
}
<html>
<head>
<title>Games-rade</title>
<link rel="stylesheet" href="CSS/Style.css">
<script src="Javascript/Java.js"></script>
</head>
<body>
<center>
<header>
<rounded><Black>---------------------------------- </Black>Main<text> | </text>About<text> | </text>Buy <Black>---------------------------------- </Black></rounded>
</header>
</center>
<br>
<br>
<br>
<Bod>
<h3> Hello. </h3>
</Bod>
</body>
</html>
Any Suggestions?
You can use CSS transitions on block elements to move your header in and out of view.
Below is a rough example using most of your code.
As an aside, you should really avoid using non-standard html elements (such as rounded) while learning; instead, add classes to standard elements. One last note, from looking at some of your CSS rules, I would recommend looking into the difference between display types, specifically block and inline, and what styles you can apply to each.
A good intro can be found here: http://learnlayout.com/display.html
body {
padding:0;
margin:0;
}
rounded {
padding: 17px;
background: #dddddd;
border-bottom-left-radius: 17px;
border-bottom-right-radius: 17px;
}
header{
font-size: 20px;
color: #ededed;
display:inline-block;
}
header rounded {
display:block;
transform:translateY(-100%);
transition:transform .5s ease;
}
header:hover rounded {
transform:none;
}
Black {
color: #000000;
}
Bod {
display:block;
padding 15px 15px;
padding-left: 150px;
}
<title>Games-rade</title>
<link rel="stylesheet" href="CSS/Style.css">
<script src="Javascript/Java.js"></script>
</head>
<body>
<center>
<header>
<rounded><Black>---------------------------------- </Black>Main<text> | </text>About<text> | </text>Buy <Black>---------------------------------- </Black></rounded>
</header>
</center>
<br>
<br>
<br>
<Bod>
<h3> Hello. </h3>
</Bod>
I did a simple example to you using jquery:
(function(){
var top_menu = $(".animation");
$(".menu").on("mouseenter", function(){
top_menu.slideDown();
});
$(".menu").on("mouseleave", function(){
top_menu.slideUp();
});
})();
Hope it helps.
I'm not too familiar with the language myself but Codecademy has a tutorial on making interactive webpages and I believe it covers just this. Plus, it's a good way to learn CSS/jQuery.
The course is at http://www.codecademy.com/en/skills/make-an-interactive-website/
I agree that you want to get away from non-standard tags. I would also suggest using CSS transitions. Assuming that you want your menu to be accessible once you've scrolled down the page I've used a fixed position container. Hopefully the simplicity of the code will help you understand what is happening.
<div class="menu-container">
<nav>Item 1 | Item 2 | Item 3</nav>
</div>
<div class="content">
<h1>Hello</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer nec odio. Praesent libero. Sed cursus ante dapibus diam. Sed nisi. Nulla quis sem at nibh elementum imperdiet. Duis sagittis ipsum. Praesent mauris. Fusce nec tellus sed augue semper porta. Mauris massa. Vestibulum lacinia arcu eget nulla. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. </p>
</div>
CSS
.menu-container {
width: 100%;
height: 30px;
position: fixed; /* Allows you to stick the container in place */
top: 0; /* Stick it to the top of the page */
left: 0; /* Make sure it's all the way to the left as well */
}
nav {
width: 100%;
height: 30px;
background-color: #ccc;
line-height: 30px; /* Easy way to vertically center single line text when you know the height of the container */
border-radius: 0 0 10px 10px;
text-align: center;
position: relative; /* Allows you to adjust placement of element */
top: -31px; /* Move up 30px from its normal position */
transition: all 1s; /* */
}
.menu-container:hover nav {
top: 0; /* When menu-container is hovered move nav to top 0 from -31px */
}
.content {
margin-top: 35px; /* Using this so that your content doesn't start behind the menu */
}

Chrome gives wrong element width

I'm making a tooltip class in Mootools that depends on getting the width of the tooltip element to centre it over the target.
It works nicely in all browsers except Chrome, which comes up with two wildly different numbers for the element width on each reload of the page. When I set a width of 100 and height 20 in the CSS, the Chrome web dev inspector shows the dimensions correctly. But when I refresh the page Chrome logs out a mad figure like 1904, and my element is positioned far away to the side.
I've tried using these different ways of getting the width, either hiding the tooltip with display:none or z-index:
getDimensions()
getSize()
getStyle('width')
element.offsetWidth
all with similar results. Can any kind person suggest a workaround, or tell me why Chrome is behaving in this way?
Thanks!
Fred
Here's my JS:
Tooltip = new Class({
Implements: Events,
Implements: Options,
options: {
target: '', // Single element or array of elements
tip: '' // Element to show
},
initialize: function(options) {
this.setOptions(options);
this.setValues();
this.attachEvents();
},
setValues: function() {
this.target = this.options.target;
this.tip = this.options.tip;
this.tip.setStyle('z-index', -1); // Hide tip element
if (this.target == null || this.tip == null) return; // We don't have required elements, so return
this.showing = false;
this.tipMousedOver = false;
this.tipDimensions = this.tip.getSize(); // Getting width
console.log(this.tip);
console.log(this.tipDimensions.x);
console.log(this.tip.offsetWidth);
this.tipFx = new Fx.Morph(this.tip, {
duration: 350,
transition: Fx.Transitions.Sine.easeIn,
link: 'cancel',
onComplete: function() {
if (this.showing) this.showing = false;
else this.showing = true;
}.bind(this)
});
},
attachEvents: function() {
this.tip.addEvent('mouseenter', function(e) {
this.tipMousedOver = true;
document.removeEvents('click');
}.bind(this));
this.tip.addEvent('mouseleave', function(e) {
document.addEvent('click', this.bodyClick.bind(this));
}.bind(this));
if (typeOf(this.target) == 'element') {
this.target.addEvent('click', this.toggleTip.bind(this));
} else {
this.target.each(function(item, index){
item.addEvent('click', this.toggleTip.bind(this));
}.bind(this));
}
},
toggleTip: function(e) {
e.stopPropagation();
if (!this.showing) {
// HIdden, so show
var posn = e.target.getPosition();
var vPosn = posn.y;
var hPosn = posn.x;
var targetWidth = e.target.getSize().x;
this.tip.setStyle('z-index', 1);
this.tip.setStyle('top', vPosn - (this.tipDimensions.y + 10));
this.tip.setStyle('left', (hPosn + targetWidth /2) - (this.tipDimensions.x / 2)); // Positions middle of tip over middle of target
console.log('targetWidth: ' + targetWidth + ' tipDimensions.x: ' + this.tipDimensions.x);
this.tipFx.start({'opacity': [0, 1]});
document.addEvent('click', this.bodyClick.bind(this));
} else {
// Visible, so hide
if (!this.tipMousedOver) {
this.tipFx.start({'opacity': 0});
this.tip.setStyle('z-index', 1);
document.removeEvent('click', this.bodyClick);
}
}
},
bodyClick: function(e) {
this.tipFx.start({'opacity': 0});
this.tip.setStyle('z-index', 1);
document.removeEvents('click', this.bodyClick);
}
});
window.addEvent('domready', function(){
new Tooltip({
target: $('comments-list').getElements('.shareLink'),
tip: $('shareTip')
});
});
HTML:
<!DOCTYPE html>
<html>
<head>
<script src="js/mootools-core-1.3.2-full-compat.js"></script>
<script src="js/mootools-more-1.3.2.1.js"></script>
<script src="comments_new_click.js"></script>
<link href="comments_new.css" type="text/css" rel="stylesheet">
</head>
<body>
<ul id="comments-list">
<!-- START COMMENT ITEM -->
<li id="CommentKey-f8b1-45f2-b4f6-68ba740ca9c3" class="commentItem">
<div class="commentTop clrd">
<span class="badges">
<img style="width: 32px; height: 32px;" src="" alt="" title="">
<img style="width: 32px; height: 32px;" src="" alt="" title="">
</span>
<a class="avatar" href="javascript:;" title="">
<img src="" alt="Photo of editor1">
</a>
<a class="username" href="javascript:;" title="">And Finally</a>
</div>
<div class="commentBody clrd">
<div class="commentOver">
<div class="submDateAndTime">26 April 2011</div>
</div>
<div class="commentSide">
<div class="likeDislike">
<a class="pluck-like alreadyvoted" href="javascript:;" title="">Like</a>
<span class="pluck-score">00000</span>
<a class="pluck-dislike" href="javascript:;" title="">Dislike</a>
</div>
</div>
<div class="commentText">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur a sapien vitae enim sagittis sodales at sit amet leo. Aenean cursus euismod blandit. Suspendisse potenti. Pellentesque vestibulum nisi id dui aliquet consequat. Nulla egestas tortor vel metus dapibus luctus. Nullam rhoncus ullamcorper lorem, non vehicula nulla euismod viverra. Morbi tempus dui ut ipsum interdum ut dapibus est venenatis.
</div>
</div>
<div class="commentBottom clrd">
<div class="getReplies">
See Replies
<span>2</span>
</div>
<!-- To delete -->
<div style="display:block;clear:both;float:none;height:0"></div>
</div>
<!-- REPLIES -->
<div id="nestedcommentslist-CommentKey:f8b1-45f2-b4f6-68ba740ca9c3" class="repliesWrapper"></div>
<!-- END REPLIES -->
</li>
<!-- END COMMENT ITEM -->
<!-- START COMMENT ITEM -->
<li id="CommentKey-f8b1-45f2-b4f6-68ba740ca9c3" class="commentItem">
<div class="commentTop clrd">
<span class="badges">
<img style="width: 32px; height: 32px;" src="http://z.x.co.uk/ver1.0/Content/images/store/5/6/3262-4af5-8654-ef59a25b24e1.Full.png" alt="" title="">
<img style="width: 32px; height: 32px;" src="http://z.x.co.uk/ver1.0/Content/images/store/5/6/3262-4af5-8654-ef59a25b24e1.Full.png" alt="" title="">
</span>
<a class="avatar" href="javascript:;" title="">
<img src="http://z.x.co.uk/ver1.0/Content/images/store/13/3/f175-45b8-931b-28619aadfd2a.Small.png" alt="Photo of editor1">
</a>
<a class="username" href="javascript:;" title="">And Finally</a>
</div>
<div class="commentBody clrd">
<div class="commentOver">
<div class="submDateAndTime">26 April 2011</div>
</div>
<div class="commentText">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur a sapien vitae enim sagittis sodales at sit amet leo. Aenean cursus euismod blandit. Suspendisse potenti. Pellentesque vestibulum nisi id dui aliquet consequat.
</div>
</div>
<div class="commentBottom clrd">
<div class="getReplies">
See Replies
<span>2</span>
</div>
<div class="share">
Report abuse
Share
</div>
<!-- To delete -->
<div style="display:block;clear:both;float:none;height:0"></div>
</div>
<!-- REPLIES -->
<div id="nestedcommentslist-CommentKey:f8b1-45f2-b4f6-68ba740ca9c3" class="repliesWrapper"></div>
<!-- END REPLIES -->
</li>
<!-- END COMMENT ITEM -->
</ul>
<div id="shareTip" class="popup">Share and things</div>
</body>
</html>
CSS:
body {
font-family: Arial,Helvetica,sans-serif;
font-size: 62.5%;
}
#comments-list {
width: 480px;
margin: 20px auto;
border: 1px solid #ccc;
list-style-type: none;
padding: 0;
}
.commentItem {
margin-left: 0;
padding-left: 0;
font-size: 13px;
}
.avatar {
margin-right: 5px;
}
.avatar img {
width: 45px;
height: 45px;
}
.commentTop {
position: relative;
padding: 5px;
min-height: 48px;
background: #e8e8eb;
}
.username {
position: absolute;
top: 5px;
height: 1em;
font-size: 14px;
text-decoration: none;
}
.badges {
float: right;
}
.badges img {
margin-left: 2px;
}
.commentBody {
padding: 5px;
background: #f3f2f2;
}
.commentText {
margin-right: 75px;
line-height: 16px;
}
.commentOver {
clear: both;
float: none;
height: 14px;
padding: 0 3px 10px 0;
}
.submDateAndTime {
float: left;
color: #777;
font-size: 11px;
}
.getReplies {
float: left;
padding: 0;
}
.getReplies a {
background-color: #ED9430; /* Put elsewhere */
background-image: url("http://z.x.co.uk/images/comments-wide.png");
background-position: -508px -245px;
background-repeat: no-repeat;
display: block;
float: left;
height: 20px;
text-indent: -9999px;
width: 60px;
}
.getReplies span {
background-image: url("http://z.x.co.uk/images/comments-wide.png");
background-position: -569px -245px;
background-repeat: no-repeat;
display: block;
float: left;
font-size: 14px;
font-weight: bold;
height: 21px;
padding-left: 2px;
text-align: center;
width: 41px;
line-height: 19px;
}
.commentBottom {
padding: 5px;
background: #f3f2f2;
}
.share {
float: right;
}
.popup {
position: absolute;
border: 1px solid #ccc;
padding: 10px;
background: #fff;
z-index: 1;
}
.hidden {
display: none;
}
#shareTip {
width: 100px;
height: 20px;
overflow: hidden;
}
=======================================
LATER
For anyone else coming across a similar problem, I found it went away when I measured the tip element right before showing it, instead of when the object's initialised. So I changed my reveal method to:
toggleTip: function(e) {
e.stopPropagation();
if (!this.showing) {
// HIdden, so show
var posn = e.target.getPosition();
var targetPosnY = posn.y;
var targetPosnX = posn.x;
var targetWidth = e.target.getSize().x;
var targetHeight = e.target.getSize().y;
var tipSize = this.tip.getSize();
var tipPosnY = targetPosnY - (tipSize.y + 10);
var tipPosnX = targetPosnX - (targetWidth / 2);
this.tip.setStyle('z-index', 1);
this.tip.setPosition({x: tipPosnX, y: tipPosnY});
this.tipFx.start({'opacity': 1});
document.addEvent('click', this.bodyClick.bind(this));
} else {
// Visible, so hide
if (!this.tipMousedOver) {
this.tipFx.start({'opacity': 0});
this.tip.setStyle('z-index', 1);
document.removeEvent('click', this.bodyClick);
}
}
},
I also found that setPosition() is a more reliable way of positioning the element than setStyle().
If you target the recent browsers only you can use window.getComputedStyle that returns all the css properties and values as they are painted on the screen.
Or just make a workaround for chrome using it.

Categories