Edit link on div mouseover - javascript

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 )" >

Related

How to use onclick event in JavaScript?

I'm trying to make a window that slide up when the X button(close.png) is clicked.
I added the Wrap element with JavaScript, and added an img element inside.
Then, I put following JavaScript, but there is no change when I press the X button.
<script>
const parent3 = document.querySelector('#wrap');
const billingField3 = document.querySelector('#woocommerce-input-wrapper');
const newImg = document.createElement('img');
newImg.setAttribute("src", "//t1.daumcdn.net/postcode/resource/images/close.png");
newImg.setAttribute('id', 'btnFoldWrap');
newImg.style.cssText = 'cursor:pointer;position:absolute;right:0px;top:-1px;z-index:1';
newImg.onclick = "offDaumZipAddress();"
parent3.insertBefore(newImg, billingField3);
</script>
function offDaumZipAddress() {
jQuery("#wrap").slideUp();
}
Website structure is
<div class="woocommerce-billing-fields__field-wrapper">
<p class="billing_postcode_find_field">..
<span class="woocommerce-input-wrapper">...
</span>
</p>
<div id="wrap" ..>
<img src="..."></img>
</div>
<p class="billing_address_1_field">
<span class="woocommerce-input-wrapper">
Checking with the console of chrome developer tools doesn't show any errors.
Could someone please let me know what am I missing?
Thank you.
The value of the onclick property must be a function reference, not a JavaScript string.
newImg.onclick = offDaumZipAddress;
You have your answer; here is a working example of that loosely based on your code (so the inserted image actually shows, added some CSS etc. to illustrate)
//gets first one of this type
const billingField3 = document.querySelector('.woocommerce-input-wrapper');
// Get a reference to the parent node/ gets first one of this type
const parent3 = billingField3.parentNode;
//console.log(parent3);
//console.log(billingField3);
// Create the new node to insert
const newImg = document.createElement('img');
newImg.setAttribute("src", "//t1.daumcdn.net/postcode/resource/images/close.png");
newImg.setAttribute('id', 'btnFoldWrap');
newImg.setAttribute('alt', 'folderWrap');
// no not this: newImg.style.cssText = 'cursor:pointer;position:absolute;right:0px;top:-1px;z-index:1';
// this:
newImg.classList.add("inserted-image");
newImg.onclick = offDaumZipAddress;
//console.log("Thing:",newImg);
//console.log("HTML:", parent3.innerHTML);
parent3.insertBefore(newImg, billingField3);
//console.log("New HTML:", parent3.innerHTML);
function offDaumZipAddress() {
console.log('here we go');
jQuery("#wrap").slideUp();
}
.billing_postcode_find_field {
border: solid blue 1px;
padding: 1rem;
}
.woocommerce-input-wrapper {
border: solid 1px lime;
padding: 1rem;
}
.inserted-image {
cursor: pointer;
/* This is odd, makes it not clickable:
position: absolute;
right: 0px;
top: -1px;
z-index: 1;*/
border: solid 1px red;
min-width: 1.5rem;
min-height: 1.5rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="woocommerce-billing-fields__field-wrapper">
<p class="billing_postcode_find_field">..
<span class="woocommerce-input-wrapper">...</span>
</p>
<div id="wrap">
<img src="//t1.daumcdn.net/postcode/resource/images/close.png" alt="png"></img>
</div>
<p class="billing_address_1_field">
<span class="woocommerce-input-wrapper"></span>
</div>

Jquery .on click not registering first few clicks mobile?

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>

Event handler for loop with dynamic jQuery selectors

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!

series of toggling divs (n number of two divs that is toggled like checkbox) - JS

I have a table each one of them have a favorite option. I have used two star images to toggle between favorite and not favorite. ( I didnt use the checkbox because I want IE8 too).
I came up with the example below.
HTML
<div class="on" id="on_1" onclick="div_off(this.id);" style="display:none">off</div>
<div class="off" id="off_1" onclick="div_on(this.id);">on</div>
<div class="on" id="on_2" onclick="div_off(this.id);" style="display:none">off</div>
<div class="off" id="off_2" onclick="div_on(this.id);">on</div>
<div class="on" id="on_3" onclick="div_off(this.id);" style="display:none">off</div>
<div class="off" id="off_3" onclick="div_on(this.id);">on</div>
<div class="on" id="on_4" onclick="div_off(this.id);" style="display:none">off</div>
<div class="off" id="off_4" onclick="div_on(this.id);">on</div>
CSS
<style>
.on, .off {
cursor: pointer;
}
.on{
color: red;
}
.off{
color: blue;
}
</style>
JS:
<script>
function div_on(onId){
onId = onId.replace('off_','');
var on = document.getElementById('on_'+onId);
var off = document.getElementById('off_'+onId);
on.style.display = "block"
off.style.display = "none"
}
function div_off(offId){
offId = offId.replace('on_','');
var on = document.getElementById('on_'+offId);
var off = document.getElementById('off_'+offId);
on.style.display = "none"
off.style.display = "block"
}
</script>
Is there an other simple way of doing the same. I am trying to avoid any js classes / jquery.
example:
http://jsfiddle.net/yellowandred/LZkVb/1/
How about this? I've also included an example on how to get the clicked element's ID.
HTML:
<div class="off" id="toggle1" onclick="toggle(this);">off</div>
<div class="off" id="toggle2" onclick="toggle(this);">off</div>
<div class="off" id="toggle3" onclick="toggle(this);">off</div>
<div class="off" id="toggle4" onclick="toggle(this);">off</div>
JAVASCRIPT:
function toggle(el) {
var newState = (el.className === "off") ? "on" : "off";
el.className = newState;
el.innerHTML = newState;
alert("\"" + el.id + "\" is now " + newState + "!");
}
CSS:
.on, .off {
cursor: pointer;
}
.on {
color: red;
}
.off {
color: blue;
}
JSFiddle here.
Browser support for these JavaScript properties.
If you are looking to use star images for on/off states I would create an image sprite (an image containing the two images of the star) and use it as background image in a div. Then you use CSS classes to control the position of the background image. For example:
HTML:
<div id="star1" class="star"></div>
<div id="star2" class="star"></div>
CSS:
.star {
width: 20px;
height: 20px;
background-image: url("img/starsprite.png");
background-size: 20px 40px; /*We assume that the sprite contains a 20x20 px star in off state above a 20x20 px star in on state. Notice that the background is bigger than the div */
background-position: 0px 0px;
cursor: pointer;
}
.star.on {
background-position: 0px 20px;
}
JS:
$('body').on('click', '#star', function(event) {
var $this = $(this);
if($this.hasClass('on')) {
$this.removeClass('on');
}
else {
$this.addClass('on');
}
});
This way you halve the amount of DIVs needed. This is a quick example so you get the logic of the image sprite solution.
If you want to avoid jQuery it is possible with plain JavaScript as well, but I don't see the reason for not keeping things simple with jQuery.
There are a lot of tutorials on the web if you google for CSS image sprites.
This fiddle http://jsfiddle.net/dJBKw/1/ uses on/off text like your example.

Chrome I JavaScript issue regarding change of display properties in css

I have been working with some JavaScript to change display properties for my website. it works fine for Firefox and IE, but Chrome and Safari do not respond at all. I am trying to change the display from "none" to "block", or the reverse. Here is the code:
function setStyleClass (classesOff,classesOn) {
var classOn;
if (document.all) {
for (var s = 0; s < document.styleSheets.length; s++) {
for (var r = 0; r < document.styleSheets[s].rules.length; r++){
if (document.styleSheets[s].rules[r].selectorText.indexOf(classesOff,0) > -1) {
document.styleSheets[s].rules[r].style.display = "none";
}
for(var j = 0; j < classesOn.length; j++){
classOn = classesOn[j];
if (document.styleSheets[s].rules[r].selectorText == '.' + classOn) {
document.styleSheets[s].rules[r].style.display = "block";
}
}
}
}
}
else if (document.getElementById) {
for (var s = 0; s < document.styleSheets.length; s++) {
for (var r = 0; r < document.styleSheets[s].cssRules.length; r++) {
if (document.styleSheets[s].cssRules[r].selectorText.indexOf(classesOff,0) > -1) {
document.styleSheets[s].cssRules[r].style.display = "none";
}
for(var j = 0; j < classesOn.length; j++){
classOn = classesOn[j];
if (document.styleSheets[s].cssRules[r].selectorText == '.' + classOn) {
document.styleSheets[s].cssRules[r].style.display = "block";
}
}
}
}
}
}
When this is called, it is given a list of style id's to turn off, and styles to turn "on".
Here is the call:
onClick="setStyleClass('book','book2_nl','book3_nl','book4_nl','B1_List_01_20','B1_Link_21_40']);
The way this works is to turn "off" any styles with "book" in the name, as well as, book2_nl, book3_nl, and book4_nl. The last two styles get turned "on". So I am replacing one "list of links to pages" with another, different list. The code above works fine in IE and FF, but does nothing at all that I can see in Chrome and Safari.
the styles all look like this coming in:
.B4_Link_21_40 {
display: none;
color: #f8fb24;
font : 90% Book Antiqua;
}
.B4_List_21_40 {
display: none;
color: #f8fb24;
font : 90% Book Antiqua;
}
I want to get these styles to turn on when I click the appropriate link. Are there any obvious errors in my code that could be causing this?
OK, you have seen the above question, now I have figured out how to go back and add html to this for your benefit :)
<html>
<head></head>
<title></title>
<script> //the script posted above </script>
<style>
.book1 {
position: absolute;
left:0px;
top:410px;
width:200px;
height:40px;
display: block;
}
.book2 {
position:absolute;
left:0px;
top:450px;
width:200px;
height:40px;
}
.B1_Link_01_20 {
display: none;
color: #f8fb24;
font : 90% Book Antiqua;
}
.B1_List_01_20 {
display: block;
color: #f8fb24;
font : 90% Book Antiqua;
}
.B1_Link_21_40 {
display: block;
color: #f8fb24;
font : 90% Book Antiqua;
}
.B1_List_21_40 {
display: none;
color: #f8fb24;
font : 90% Book Antiqua;
}
</style>
<div align="justify" align="center" class="mainBody"
<p>Here's some content...</p>
</div>
<div class="book1">
<a href="#" target="_self"
onClick="setStyleClass('book',['B1_List_01_20','B1_Link_21_40']);
switchStyleClass('B2_Li');
onMouseOut="window.status=''; return true;">
</a>
</div>
<div class="book2">
<a href="#" target="_self"
onClick="setStyleClass('book',['B2_List_01_20','B2_Link_21_40']);
switchStyleClass('B1_Li');
onMouseOut="window.status=''; return true;">
</a>
</div>
<div class="B1_List_01_20">
<a href=Link To Page 1.shtml>1. Link To Page 1</a><br>
<a href=Link To Page 2.shtml>2. Link To Page 2</a><br>
<br></div>
<div class="B1_List_21_40">
<a href=Link To Page 21.shtml>21. Link To Page 21</a><br>
<a href=Link To Page 22.shtml>22. Link To Page 22</a><br>
<br></div>
<div class="B1_Link_01_20">
<a ONCLICK="setStyleClass('B1_Li',['B1_List_01_20','B1_Link_21_40']);" href="#">List of Links 1 - 20</a><br><br>
</div>
<div class="B1_Link_21_40">
<a ONCLICK="setStyleClass('B1_Li',['B1_List_21_40','B1_Link_01_20','B1_Link_41_60']);" href="#">List of Links 21 - 40</a><br><br>
</div>
</html>
First if your just trying to change links then I would put the different links in 2 containers positioned in the same place via position: absolute then I would have one with a default style none. When the button is clicked then you don't even have to pass anything to your method since your only dealing with 2 containers and you know both their id's.
Then instead of going though the style sheets, just use document.getElementById('container_1').style.display = 'block';
document.getElementById('container_2').style.display = 'none';
As long as your container is a block level, such as a div, then this will change their display property in every browser.
if you want to do it through changing their class names then you could do this.
function changeStyles(){
document.getElementById('container_1').className = 'classOn';
document.getElementById('container_2').className = 'classOff';
//rest of your javascript
}
*This is still assuming you go with two containers instead of trying to change every link's individual style
Edit:
So not knowing what html you actually have makes it harder to answer your comment but here goes.
Your html could look something like this:
<div class='classOn' id='container_1'>
<a href='some_link'>some link</a>
<a href='some_link2'>some link2</a>
<a href='some_link3'>some link3</a>
<a href='some_link4'>some link4</a>
</div>
<div class='classOff' id='container_2'>
<a href='different_link'>different link</a>
<a href='different_link2'>different link2</a>
<a href='different_link3'>different link3</a>
<a href='different_link4'>different link4</a>
</div>
<button onclick='changeStyles()>See new Links!</button>
Then your css:
.classOn{
display: block;
position:absolute;
margin: 10px 10px 10px 10px;
//rest of your css
}
.classOff{
display: none;
position: absolute;
margin: 10px 10px 10px 10px;
//rest of your css
}
Notice how both classes have the exact same margin, they can have this because of the absolute position attribute. It effectively takes the space they would be using out of the page. now when the function changeStyles() is called by pressing the button the first div is hidden and the second div shows up with the new links in the exact same position. hope that helps.
Ok so my example above works fine with what you have just make class='classOn' your class='B1_List_01_20' and make class='classOff' your class='B1_Link_21_40' and use the function above and it should switch between them just fine.

Categories

Resources