I'm trying to build a product configurator that shows the total weight of all selections.
I've noticed on IOS and phones the #2 button need to be clicked multiple time before registering and the #1 button a couple of times. I've added cursor:pointer but the problem remains.
Is this just the nature of Jquery and mobile touch/tap? If you can see any issues with the code or have any suggestions please let me know.
https://jsfiddle.net/pdrj5vmo/9/
// Matches and shows Butts to Car index order.
let $cars = $('.car');
$('.butts').on('click', e => {
let $target = $cars.eq($(e.target).index()).show();
$cars.not($target).hide();
});
// Finds all Butts and calls `sumBoxes` onclick
const boxes = document.getElementsByClassName("butts");
for (let butts of boxes){ butts.addEventListener("click", sumBoxes); }
// sumBox Calculates each visible Box
function sumBoxes(event) {
var total = 0;
$('.box:visible').each(function() {
total += parseInt($(this).text());
});
$('.sum').html("Total : " + total); // Replaces contents of `.sum`
}
body {background: #eeeeee;}
.car {display:none;}
.box {float: left;font: bold 17px arial;text-align: center;margin: 10px 10px 20px 0;padding: 10px 25.54px;background: #fff;color: blue}
.butts {cursor:pointer; width:200px;height:40px;background:#fff; margin-bottom:10px; margin-right:10px; float:left;border:1px solid blue;}
.sum {clear:both;margin-top:40px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="butts-container" style="float: left;width: 100%;">
<div class="butts">1</div>
<div class="butts">2</div>
</div>
<div class="car-container">
<div class="car">
<div class="box">1 CarBox</div>
</div>
<div class="car">
<div class="box">2 CarBox</div>
</div>
</div>
<div class="box">100 Box</div>
<div class="sum">Total</div>
Related
Im finishing up the last bit of a todo list app I am creating. Basically users generate todo tasks which show up on the screen along with a checkbox and trash can icon to the right of it. For the most part the app is working as it should. The last thing I need to do is have it that when a user clicks a checkbox, text-decoration:line through effect takes place and crosses out the corresponding list item. I used to have this working but I had to shift around some things so resizing the screen would look better. Now my old way wont work. Ill post some code and if anyone knows how I can get this working I would really appreciate it. Thanks everyone!
The input:checked + li css below is what was originally working before I had to rearrange the order of how list items were generated.
ul {
text-align:right; /*This pushes the checkbox/trash can right while the <li> in the js file floats the todo text left*/
list-style-type:none;
padding-left:0px; /*Makes up for not having the bullet point spacing on smaller screens*/
font-size:24px;
color:white;
font-weight:600;
}
li {
text-align:left;
}
input:checked + li { /*<<<<<------This is what I was using before and it worked*/
text-decoration:line-through;
}
.todo-item::after {
content: "";
clear: both;
display: table;
}
.todo-item {
text-align: right;
}
.todo-item .todo-label {
display: block;
float: left;
max-width: 80%; /* you can increase the size */
text-align: left;
/* you can use this props if you don't want another line
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden; */
}
</style>
</head>
<body>
<div class="header">
<div class="container" style="padding-top:50px;">
<div class="row justify-content-center"> <!--Input Box-->
<div class="col-sm-12 col-lg-8">
<h1>To-Do List</h1>
<div class="form-group">
<input type="text" class="form-control" id="task">
</div>
</div>
</div>
<div class="row"> <!--Add Button-->
<div class="col"></div>
<div class="col-xs-2" style="margin-right:15px; margin-top:30px;">
<button id="add" style="border-radius:50%; font-size:35px; width:65px;" class="btn btn-danger">+</button>
</div>
</div>
</div>
</div>
<div class="container text" style="display:inline-block;"> <!--ToDos-->
<div class="row justify-content-center" style="margin-top:20px;">
<div class="col-sm-12 col-sm-8">
<div id="todos"></div>
</div>
</div>
</div>
<script src="todo.js"></script>
</body>
</html>
Here is the javascript used to develop items for the todo list. Prior to rearranging, the checkbox was generated before the todo list item. Now, it was shifted to after. I thought I could just rearrange my css order or perhaps take out the li section and replace it with a class. I havent had much luck here.
function show() {
var todos = get_todos();
var html = '<ul>';
for(var i=0; i < todos.length; i++) {
html += '<li class="todo-item">' +
'<span class="todo-label">' + todos[i] + '</span>' +
'<input class="checkBox" type="checkbox">' +
'<button class="remove" id="' + i + '">' +
'<i class="fa fa-trash" aria-hidden="true"></i>' +
'</button>' +
'</li>';
};
html += '</ul>';
document.getElementById('todos').innerHTML = html;
var buttons = document.getElementsByClassName('remove');
for (var i=0; i < buttons.length; i++) {
buttons[i].addEventListener('click', remove);
};
}
A fairly simple way of adding the line-through effect when the checkbox is clicked and removing the effect when the checkbox is unclicked is using the toggle method to toggle a premade class with the line-through effect. This class should not be on by default because you don't want the line-through effect right away. When you click the checkbox, it will toggle the class on. When you unclick the checkbox, it will toggle the class off.
HTML should be something like:
<ul>
<li> Todo Item <input .....> </li>
Then create a CSS class for your code to toggle:
.lineThrough {
text-decoration: line-through;
}
The jQuery code would look like this:
$("ul").on("click", "li", function(){
$(this).toggleClass("lineThrough");
});
I've got 2 seperate divs that change background img src when clicked which works fine, but I would like it to change the other image its present with. E.g. div 1 is pressed and becomes "open", if div2 is "open" it then becomes closed. My jQuery is rather limited and have it functioning where it can change the image, but need to figure out how to apply the "closed" class to images that haven't just been clicked. Ideally it would use the attr() so I can add more later.
jQuery
$(".box").on("click", function() {
// need to make this function select the other div.
if ($(this).hasClass("closed")) {
$(this).addClass("open").removeClass("closed");
} else {
$(this).addClass("closed").removeClass("open");
}
var id = $(this).attr("data-id");
$(this).toggleClass("open");
$(".hideDivs").hide();
$("#" + id).show();
});
.container {
width: 640px;
height: 450px;
background-color: #eee;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.5);
}
.text-primary {
font-size: 14px;
text-align: center;
margin-bottom: 5px;
}
.box {
cursor: pointer;
width: 90px;
height: 180px;
display:block;
margin:auto;
background-image: url("http://res.cloudinary.com/dez1tdup3/image/upload/v1499052120/closed_vo1pn2.png");
}
.open {
background-image: url("http://res.cloudinary.com/dez1tdup3/image/upload/v1499052120/open_ihcmuz.png");
}
.closed {
background-image: url("http://res.cloudinary.com/dez1tdup3/image/upload/v1499052120/closed_vo1pn2.png");
}
.hideDivs {
display: none;
}
.panel-body {
padding: 10px;
margin-top: 5px;
}
.title {
font-weight: bold;
font-size: 14px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<div class="row">
<div class="col-xs-6">
<div class="box" data-id="divId1">
</div>
</div>
<div class="col-xs-6">
<div class="box" data-id="divId2">
</div>
</div>
</div>
<div class="row">
<div class="col-xs-12">
<div class="panel panel-default hideDivs" id="divId1">
<div class="panel-body">
<span class="title">Practices for safe packaging of cooked foods</span>
<ul>
<li>Label and date all food.</li>
<li>Package high-risk food in small batches for refrigeration and return to refrigerated storage as soon as possible (within 20 minutes).</li>
<li>Store packaging products in a clean environment and protect from contamination.</li>
</ul>
</div>
</div>
<div class="panel panel-default hideDivs" id="divId2">
<div class="panel-body">
<span class="title">Practices for safe freezing of cooked foods</span>
<ul>
<li>When packaging food for freezing, cover or wrap, label and date (production and freezing date) all foods.</li>
<li>Freeze food in small quantities to ensure food is frozen quickly.</li>
<li>Do not overload freezer units and ensure air can circulate.</li>
<li>Do not freeze foods that have been cooked then refrigerated and reheated.</li>
</ul>
</div>
</div>
</div>
</div>
</div>
Please check the jsfiddle and let me know if you are looking something like this.
https://jsfiddle.net/314sybno/2/
$(".box").on("click", function() {
var id = $(this).attr("data-id");
if( id === 'divId1') {
$('div[data-id="divId2"]').addClass('closed').removeClass('open');
} else {
$('div[data-id="divId1"]').addClass('closed').removeClass('open');
}
// need to make this function select the other div.
if ($(this).hasClass("closed")) {
$(this).addClass("open").removeClass("closed");
} else {
$(this).addClass("closed").removeClass("open");
}
$(".hideDivs").hide();
$("#" + id).show();
});
This might be a better approach:
$(".box").on("click", function() {
// Hide all detail divs
$(".hideDivs").hide();
if ($(this).is(".closed")) {
// Close other open boxes
$(".box.open").removeClass("open").addClass("closed");
// Open this box and show the corresponding details div
$(this).removeClass("closed").addClass("open");
var id = $(this).attr("data-id");
$("#" + id).show();
} else {
// Close this box
$(this).removeClass("open").addClass("closed");
}
});
Also, I would recommend changing your HTML to have your 'box' elements also have a 'closed' class, so you do not repeat/need the CSS background attribute on the 'box' class.
See it working on this fiddle
What I want is to click on #bt-1 and change the color of #target-1, click on #bt-2 and change the color of #target-2...
I started writing a particular click event handler for each #bt-n / #target-n but as the site got bigger I thought about using a loop. My approach was using a for loop with variables in jQuery selectors. Here is my code:
$(document).ready(function() {
var total = $('.target').length;
for(n=1; n<=total; n++) {
var num = String(n);
$('#bt-'+num).on('click', function() {
$('#target-'+num).toggleClass('yellow');
});
}
});
.wrapper {
display: flex;
text-align: center;
}
.button, .target {
padding: 20px;
margin: 10px;
}
.button {
background: gray;
}
#target-1 {
background: red;
}
#target-2 {
background: green;
}
#target-3 {
background: blue;
}
.yellow {
background: yellow !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div id="bt-1" class="button">
<h1>Button 1</h1>
</div>
<div id="target-1" class="target">
<h1>Target 1</h1>
</div>
</div>
<div class="wrapper">
<div id="bt-2" class="button">
<h1>Button 2</h1>
</div>
<div id="target-2" class="target">
<h1>Target 2</h1>
</div>
</div>
<div class="wrapper">
<div id="bt-3" class="button">
<h1>Button 3</h1>
</div>
<div id="target-3" class="target">
<h1>Target 3</h1>
</div>
</div>
I don't understand why it only targets the last #target-n as the loop seems to be working on #bt-n. I also thought about using an array but can't figure out how to implement it.
I managed to make it work using $(this).siblings('.target')... which do not require the for loop and ids but a parent element for each .button / .target, in this case .wrapper Code Here. Although this was a good solution, I would like to understand what I did wrong and how to properly implement a loop to achieve this without using the parent .wrapper. Thank you.
The reason that only the last item gets affected is because the loop has completed before any event fires. Therefore n holds the last value in the loop. To fix this you need to use a closure:
for (n = 1; n <= total; n++) {
(function(n) {
$('#bt-' + n).on('click', function() {
$('#target-' + n).toggleClass('yellow');
});
})(n);
}
That said, a much better approach would be avoid the loop and to use DOM traversal to find the .target related to the clicked .button, like this:
$('.button').click(function() {
$(this).next('.target').toggleClass('yellow');
});
.wrapper {
display: flex;
text-align: center;
}
.button,
.target {
padding: 20px;
margin: 10px;
}
.button {
background: gray;
}
#target-1 {
background: red;
}
#target-2 {
background: green;
}
#target-3 {
background: blue;
}
.yellow {
background: yellow !important;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrapper">
<div id="bt-1" class="button">
<h1>Button 1</h1>
</div>
<div id="target-1" class="target">
<h1>Target 1</h1>
</div>
</div>
<div class="wrapper">
<div id="bt-2" class="button">
<h1>Button 2</h1>
</div>
<div id="target-2" class="target">
<h1>Target 2</h1>
</div>
</div>
<div class="wrapper">
<div id="bt-3" class="button">
<h1>Button 3</h1>
</div>
<div id="target-3" class="target">
<h1>Target 3</h1>
</div>
</div>
It is unwise to register a lot of event handlers. You can bind one event handler and perform action for given specific idx read from element id, eg:
$('body').on('click', function (event) {
if (!event.target.id.match(/^bt-\d+/)) {
return; //id of clicked element does not match bt-{number}
}
var idx = event.target.id.replace('bt-', ''); //remove prefix "bt-" and leave only numeric postfix
$('#target-' + idx).toggleClass('yellow');
});
Explanation:
When you bind click on body element You are getting access to all click events from child elements that not cancelled passing that event up. Element that has been clicked in saved inside event.target and it has property id in event.target.id.
On this id property I call match function with regular expression - it will match string which starts ^ from bt- and have any number \d at least one one + .
if (!event.target.id.match(/^bt-\d+/)) {
return; //id of clicked element does not match bt-{number}
}
There is negation of this statement, so If this id is not in format bt-someNumber it will not go further.
var idx = event.target.id.replace('bt-', '');
Than takes id and replaces bt- part in it with empty string ''
$('#target-' + idx).toggleClass('yellow');
Finally You are toggling class on element with same number as button but with different prefix target- instead of bt-.
Happy hacking!
Hitting a wall with this one, hope someone can lend a hand. I have a wrapper div containing many fixed-width "content" divs. It's like a table, except that the number of items "per row" aren't fixed, so that whenever the screen size is wide, more items fit onto the screen. Pretty basic.
Also, each of these "content" divs has an adjacent "details" div that is hidden by default ("style=display:none"), and an adjacent "separator" div that is empty, containing only the style "clear:both;".
Each content/details/separator div has a unique number in its ID, so that I can tell they are related (e.g., content123, details1234, separator1234)
Now, when one of these content divs is clicked, I want to reveal its "details" div below it. That part, I've got working partially, by wrapping an anchor tag around the content div, which fires an onClick javascript event, which in turns runs a jQuery statement to make visible the details and separator divs jQuery(".details1234").css("display","block");"
But you can imagine my problem. Once that "separator" div is reveled, it pushes down (clears) any "content" divs that appears to the right of it, ugly. My thought, what I have been wrestling with for hours, is to reveal the "separator" div of the content div, that is the last one appearing in the "row" that was clicked. That way, a new "row" will be opened up by the separator, so that when the "content" div is revealed it appears below the clicked item in the new row. To do that, I need to figure out the elementID of the last content div in the "row", and I was thinking about using the Y-coord of the mouse click event, plus the X-coord = to the right-most edge of the wrapper div minus half the width of the fixed-width content div. Something like that. But I am smashed into a wall and can't figure it out.
Can anyone help me do that? Or offer a different solution?
If sample code would help let me know, I could whip up an example, but it may take some screen space in this post.
Thanks everyone.. going nuts with this.
EDIT: the sample code below is based on my site. When a cell is clicked, you can see its "details" div appear below it, but unfortunately the other divs in the "row" get pushed down. that is the effect I'm trying to avoid. When a cell is clicked, I want the "details" to appear below it, but also the other divs to stay in their positions above the other cell's details, basically I want to keep the "row" intact. In the code, you can see my fruitless experiments using a "separator" div, because my assumption is that if I can insert that after the last div in the row, then the "details" div will become the next row, followed then by the next row of cells. Hope I explained it OK. Thanksgiving feast causing blood to divert from brain ;)
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<style type="text/css">
#overallwrapper{
background: #CCCCCC;
padding-top: 4px;
padding-left: 4px;
padding-right: 4px;
padding-bottom: 4px;
margin-top: 5px;
}
.contentcell{
border: 2px solid blue;
padding: 4px;
float: left;
width: 200px;
}
.separator{
clear:both;
display: none;
}
.details{
background:lightgreen;
border: 2px solid green;
width:450px;
display:none;
float:left;
clear:both;
}
</style>
<script type="text/javascript">
function showDetails(contentid){
//first, reset all highlights and close any open content divs
$("#overallwrapper .contentcell").css("border","2px solid blue");
$(".details").css("display","none");
$(".separator").css("display","none");
//now highlight the clicked div and reveal its content div
var contentHI = "#content"+contentid;
var detailsON = "#details"+contentid;
var separatorON = "#separator"+contentid;
$(contentHI).css("border","2px solid green");
//$(separatorON).css("display","block");
$(detailsON).css("display","block");
}
</script>
</head>
<body>
<div id="overallwrapper">
<div id="contentwrapper01">
<div id="content01" class="contentcell">cell01</div>
<div id="details01" class="details">here are details about cell01</div>
<div id="separator01" class="separator"> </div>
</div>
<div id="contentwrapper02">
<div id="content02" class="contentcell">cell02</div>
<div id="details02" class="details">here are details about cell02</div>
<div id="separator02" class="separator"></div>
</div>
<div id="contentwrapper03">
<div id="content03" class="contentcell">cell03</div>
<div id="details03" class="details">here are details about cell03</div>
<div id="separator03" class="separator"></div>
</div>
<div id="contentwrapper04">
<div id="content04" class="contentcell">cell04</div>
<div id="details04" class="details">here are details about cell04</div>
<div id="separator04" class="separator"></div>
</div>
<div id="contentwrapper05">
<div id="content05" class="contentcell">cell05</div>
<div id="details05" class="details">here are details about cell05</div>
<div id="separator05" class="separator"></div>
</div>
<div id="contentwrapper06">
<div id="content06" class="contentcell">cell06</div>
<div id="details06" class="details">here are details about cell06</div>
<div id="separator06" class="separator"></div>
</div>
<div style="clear:both;"></div><!-- to prevent parent collapse -->
</div>
</body>
</html>
User ,
if you give as regular position be default , it pushes the other contents definetly down as they come in squence.
Change the hidden divs position to absolute so that it will go out of sequence and you can position at anywhere on the page by top and left property.
get the offset of the div you want next to...
http://api.jquery.com/offset/
it will have top and left property , use those property's and position next to them.
let me know if you need anything else.
give a bigger z-index for the hidden divs.
What about showing the details div with position: absolute, on top of everything else? (See here, the code's a little messy but you get the idea).
I partially figured it out, but the logic may be very clunky. I basically walk left by 100px from the width of the container div until I find a content div. Plus it doesn't work in IE8, because IE is not getting the same results from jQuery's offset() or position() as firefox, it always reports "19". So in IE, I can never get a Y-coordinate value. I'm too sleepy now to work on this anymore today. If someone can lend a hand or tell me how to improve the javascript that would be cool.
Here is the working code for Firefox (I changed javascript and css of the detail divs, compared to original question):
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<style type="text/css">
#overallwrapper{
background: #CCCCCC;
padding-top: 4px;
padding-left: 4px;
padding-right: 4px;
padding-bottom: 4px;
margin-top: 5px;
}
.contentcell{
border: 2px solid blue;
padding: 4px;
float: left;
width: 200px;
}
.separator{
clear:both;
display: none;
}
.details{
background:lightgreen;
border: 2px solid green;
display:none;
clear:both;
}
</style>
<script type="text/javascript">
function showDetails(contentid){
//first, reset all highlights and close any open content divs
$("#overallwrapper .contentcell").css("border","2px solid blue");
$(".details").css("display","none");
$(".separator").css("display","none");
//now highlight the clicked div and reveal its content div
//first, figure out which separator to display.
//1.get the y-pos from the clicked element, this gives y-coord of the row
contentClicked = "#content"+contentid;
var clickedoffset = $(contentClicked).offset();
var ypos = clickedoffset.top;
var wrapperwidth = $("#overallwrapper").width();
for (var xpos=wrapperwidth; xpos>0; xpos-=100){
var elematpos = document.elementFromPoint(xpos, ypos);
var elematposid = elematpos.id;
if (elematposid.substring(0,7) == "content") {
var lastcontentdivID = elematposid.substring(7);
break;
}
}
$(contentClicked).css("border","2px solid green");
var detailsON = "#details"+contentid;
$(detailsON).css("display","block");
var lastidonscreen = "#content"+lastcontentdivID;
$(detailsON).insertAfter(lastidonscreen);
}
</script>
</head>
<body>
<div id="overallwrapper">
<div id="contentwrapper01">
<div id="content01" class="contentcell">cell01</div>
<div id="separator01" class="separator"> </div>
<div id="details01" class="details">here are details about cell01</div>
</div>
<div id="contentwrapper02">
<div id="content02" class="contentcell">cell02</div>
<div id="separator02" class="separator"></div>
<div id="details02" class="details">here are details about cell02</div>
</div>
<div id="contentwrapper03">
<div id="content03" class="contentcell">cell03</div>
<div id="separator03" class="separator"></div>
<div id="details03" class="details">here are details about cell03</div>
</div>
<div id="contentwrapper04">
<div id="content04" class="contentcell">cell04</div>
<div id="separator04" class="separator"></div>
<div id="details04" class="details">here are details about cell04</div>
</div>
<div id="contentwrapper05">
<div id="content05" class="contentcell">cell05</div>
<div id="separator05" class="separator"></div>
<div id="details05" class="details">here are details about cell05</div>
</div>
<div id="contentwrapper06">
<div id="content06" class="contentcell">cell06</div>
<div id="separator06" class="separator"></div>
<div id="details06" class="details">here are details about cell06</div>
</div>
<div style="clear:both;"></div><!-- to prevent parent collapse -->
</div>
</body>
</html>
EDIT:
Blasted IE. I just can't trust it to determine screen coordinates. I got it working though, but only for Firefox. again IE is trying to drive me insane by not handling insertAfter properly. arrgh! here is the final code:
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<style type="text/css">
#overallwrapper{
background: #CCCCCC;
padding-top: 4px;
padding-left: 4px;
padding-right: 4px;
padding-bottom: 4px;
margin-top: 5px;
}
.contentwrapper{
}
.contentcell{
padding: 4px;
float: left;
width: 200px;
height: 100px;
border: 2px solid blue;
}
.separator{
clear:both;
display: none;
}
.details{
background:lightgreen;
border: 2px solid green;
display:none;
clear:both;
}
</style>
<script type="text/javascript">
function showDetails(contentid){
//first, reset all highlights and close any open content divs
$("#overallwrapper .contentcell").css("border","2px solid blue");
$(".details").css("display","none");
$(".separator").css("display","none");
var contentClicked = "#content"+contentid;
var thisypos = $(contentClicked).offset().top;
var nextdivid = contentClicked;
var countid = contentid;
do
{
var prevdivid = nextdivid;
var nextcontentid = (countid * 1) + 1;
var nextcontentid = '' + nextcontentid;
if ( nextcontentid.length < 2)
{ nextcontentid = "0" + nextcontentid; }
nextdivid = "#content" + nextcontentid;
if ( $(nextdivid).length ) {
var nextypos = $(nextdivid).offset().top;
countid++;
} else {
break;
}
}
while (thisypos == nextypos);
$(contentClicked).css("border","2px solid green");
var detailsON = "#details"+contentid;
$(detailsON).css("display","block");
$(detailsON).insertAfter(prevdivid);
}
</script>
</head>
<body>
<div id="overallwrapper">
<div id="contentwrapper01" class="contentwrapper">
<div id="content01" class="contentcell">cell01</div>
<div id="separator01" class="separator"> </div>
<div id="details01" class="details">here are details about cell01</div>
</div>
<div id="contentwrapper02" class="contentwrapper">
<div id="content02" class="contentcell">cell02</div>
<div id="separator02" class="separator"></div>
<div id="details02" class="details">here are details about cell02</div>
</div>
<div id="contentwrapper03" class="contentwrapper">
<div id="content03" class="contentcell">cell03</div>
<div id="separator03" class="separator"></div>
<div id="details03" class="details">here are details about cell03</div>
</div>
<div id="contentwrapper04" class="contentwrapper">
<div id="content04" class="contentcell">cell04</div>
<div id="separator04" class="separator"></div>
<div id="details04" class="details">here are details about cell04</div>
</div>
<div id="contentwrapper05" class="contentwrapper">
<div id="content05" class="contentcell">cell05</div>
<div id="separator05" class="separator"></div>
<div id="details05" class="details">here are details about cell05</div>
</div>
<div id="contentwrapper06" class="contentwrapper">
<div id="content06" class="contentcell">cell06</div>
<div id="separator06" class="separator"></div>
<div id="details06" class="details">here are details about cell06</div>
</div>
<div style="clear:both;"></div><!-- to prevent parent collapse -->
</div>
</body>
</html>
On facebook for example - when you put your mouseover a news item, a remove button appears. How can I go about making this happen?
Thanks,
Elliot
Modern Browsers
In modern browsers, you can leverage the :hover pseudo class in our selector. As an example, consider the following markup:
<div class="item">
<p>This is a long string of text</p>
<div class="adminControls">
Delete Item
</div>
</div>
By default, we would want the .adminControls to be hidden. They should, however, become visible once the user has hovered the .item element:
.item .adminControls {
display: none;
}
.item:hover .adminControls {
display: block;
}
JavaScript and jQuery
If you're using jQuery, you can accomplish this rather easily using the $.hover() method. If you're using Prototype, you can get the protoHover plugin to achieve the same result, or view this blog post.
$("div.item").hover(
function () { $(this).find(".adminControls").show(); },
function () { $(this).find(".adminControls").hide(); }
);
That would accomplish the show/hide effect for the following:
<div class="item">
<p>This is a long string of text</p>
<div class="adminControls">
Delete Item
</div>
</div>
<div class="item">
<p>This is a long string of text</p>
<div class="adminControls">
Delete Item
</div>
</div>
<div class="item">
<p>This is a long string of text</p>
<div class="adminControls">
Delete Item
</div>
</div>
If you don't need to support IE6, you can use the :hover pseudoclass like so:
CSS:
.link { display: none; }
.item:hover > .link { display: inline; }
HTML:
<div class="item">
Remove
Lorem Ipsum...
</div>
Position the link as you'd like it to appear on hover, then hide it with JavaScript and use the onmouseover event to show it. (i.e., it's display: none; and then turns to display: block; when the onmouseover event is triggered).
Something like this:
window.onload = function(){
document.getElementById('mylink').style.display = 'none';
document.getElementById('mydiv').onmouseover = function(){
document.getElementById('mylink').style.display = 'block';
}
}
You need to write a Javascript function that manipulates the DOM and you need to associate the OnMouseOver attribute of your HTML element with that function. For example, on my home page a picture of my face changes every time the mouse rolls over it. The Javascript function is defined in the HTML page itself.
<script type="text/javascript">
<!--
faceCnt = 7;
var faces = new Array( faceCnt );
var faceDates = new Array( "1982", "1986", "1991", "1999", "2004", "2006", "2009" );
var faceIdx = 7; /* So that first change is to earliest one. */
for( var idx = 0 ; idx < faceCnt ; idx++ )
(faces[idx] = new Image(150, 116)).src = "david/david" + (idx + 1) + ".jpg";
function nextFace( ref )
{
faceIdx = faceIdx >= faceCnt - 1 ? 0 : faceIdx + 1;
ref.src = faces[ faceIdx ].src;
ref.title = "David-" + faceDates[ faceIdx ];
}
//-->
</script>
<img id="myface" src="david/david7.jpg" alt="david" title="David-2009"
width="150" height="116"
style="margin: 0 0 5px 15px; /* -10px -5px 10px 10px; */
padding: 0;
border: solid black;
border-width: 1px;
float: right;"
onMouseOver="nextFace( this )"
onClick="nextFace( this )" >