Make table cells with <a> clickable and respect tabbed browsing - javascript

Right now I'm doing a td.click() and then window.location = td.find('a').attr('href') but it doesn't work if I'm clicking to make a new tab.
And I can't programmatically click the <a>.
Any ideas?
Feel free to fork this fiddle http://jsfiddle.net/uDQPr/

You could make the <a> fill up the entire cell. That way, you won't need any additional JavaScript to handle the click event. Adding target="_blank" to your <a> link will make it always open in a new tab (or a new window, for browsers that don't support tabs). Working example at http://jsfiddle.net/vTyAc/2/.
Here's the table code:
<table>
<tr>
<td>
Apple
</td>
<td>
YouTube
</td>
</tr>
</table>
And the CSS:
td {
border: 1px solid;
}
a {
text-decoration: none;
display: block;
width: 100%;
height: 100%;
padding: 10px
}
a:hover {
text-decoration: underline;
}

Related

Hide popup when mouse moves off

I'm trying to add a popup when a td is mousedover. Each row has multiple td's and the popup should only work on the first one. This works as long as mouseout is in the same column. That is, if I move the mouse up and down, the popup appears and disappears as expected. But if I move the mouse horizontally into the next td, the popup doesn't disappear. I created a jsfiddle for this but the popup isn't working. The console is saying the javascript function isn't defined but it works fine here so I must have something wrong in the jsfiddle setup. Here's the code I am using. Td's are being used because this is the code I was given. Can anyone see what is needed to get the popup to hide no matter how the mouse moved?
EDITED to solve the problem.
<style>
#pop-description{
display : none;
position : absolute;
z-index : 99999;
left : 0px;
padding : 10px;
background : #3AB9AE;
border : 1px solid #9a9a9a;
margin : 0px;
}
</style>
<script>
$(document).ready(function(){
function ShowDescription(id) {
var position = $('.class-desc-'+id).position();
var desc = $('#desc-'+id).val();
$('#pop-description').css('top', position.top);
$('#pop-description').text(desc);
//$('#pop-description').toggle();
$('.class-desc-'+id).mouseenter(function() {
$('#pop-description').css('display', 'block');
}).mouseleave(function() {
$('#pop-description').css('display', 'none');
});
}
});
</script>
<div style="display:relative;"><div id="pop-description" style="display:none;"></div></div>
<table>
<tr>
<td class="class-desc-0" onmouseOver="ShowDescription('0');">title</td>
<td>Address</td>
<td>State</td>
<input type="hidden" name="desc-0" value="first test" id="desc-0">
</tr>
<tr>
<td class="class-desc-1" onmouseOver="ShowDescription('1');">title</td>
<td>Address</td>
<td>State</td>
<input type="hidden" name="desc-1" value="second test" id="desc-1">
</tr>
<tr>
<td class="class-desc-2" onmouseOver="ShowDescription('2');">title</td>
<td>Address</td>
<td>State</td>
<input type="hidden" name="desc-2" value="third test" id="desc-2">
</tr>
</table>
I think you are overthinking it. Here is what I would do. I would use jQuery as demonstrated below.
Trigger the action you need on mouseenter
Initiate the opposite action on mouseleave
$(function() {
$(".toggle").mouseenter(function() {
// Your code goes below: initiate first action
$(this).addClass("showOff");
}).mouseleave(function() {
// Your code goes below: Initiate opposite action
$(".toggle").removeClass("showOff");
});
});
div {
cursor: pointer;
width: 200px;
height: 200px;
line-height: 200px;
text-align: center;
transition: all 2s;
}
.showOff {
width: 200px;
height: 200px;
line-height: 200px;
text-align: center;
background: orange;
transition: all 2s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="toggle">Hove over me</div>
Note: In your case, you show the popup on mouseenter and hide it on mouseleave
Why not just using hover ? Like
class-desc:hover .popup{
display: block;
}

JavaScript link underline styling

I'm using an onmouseover/onmouseout over a table cell to change the styling for an image and a link in the cell. It works but is overriding the CSS link styling, namely the text-decoration: none and font color. I've tried correcting with inline CSS, but no dice. Any ideas? Also, I know the code is hideous. I just want to get it working before I put it into an external js file.
<td
onmouseover="
document.getElementById('myImage').style.border='3px solid #334f92';
document.getElementbyId('myLink').style.fontWeight='bold';
document.getElementbyId('myLink').style.textDecorationLine='none';""
onmouseout="
document.getElementById('myImage').style.border='1px solid #000000';
document.getElementbyId('myLink').style.fontWeight='normal';
">
First off, good thing you recognize that writing inline event listeners are not very conventional (and also hideous).
Have you considered achieving this through CSS? It may be a lot simpler and would eliminate the need for two separate event listeners for mouseover and mouseout. You would simply use the :hover css selector like so:
td {
border: 1px solid black;
/* Added padding for demonstration purposes */
padding: 20px;
}
td:hover {
border: 3px solid #334f92;
font-weight: bold;
text-decoration: none;
}
td:hover a {
color: orange;
}
td:hover img {
border-radius: 10px;
}
<table>
<tr>
<td>
Link
<img src="https://via.placeholder.com/100">
</td>
<td>
Link
<img src="https://via.placeholder.com/100">
</td>
</tr>
</table>
In addition, if you wanted to style an image within the <td> tag, you can do this:
td:hover img {
/*Apply CSS to image here*/
}

Using $(this) and addClass/removeClass simultaneously to show/hide content of a bottom navbar

THE AIM
I have the code below with a bottom navbar of three different menus showing three different contents in which I would like the following to happen:
The default active menu/content should be the first one (home menu).
One menu/content should always be active, i.e. if I click on the current menu nothing would happen and only if I click on a different one I would see some change (i.e. other menu and content would be active).
When refreshing the page, the user should remain in the menu/content they were before refreshing with the menu icon active (i.e. black) and the content of the respective menu shown.
When closing the browser/tab and reopening, the menu/content shown should be the default one (home menu).
THE PROBLEM
Once first opened the browser/tab the default menu/content (home) is shown as desired. However, when clicking in another menu icon, only it's icon menu is shown as active and the content does not shows at all, I think this is because I am using $(this) and it only represents a[class^=menu].
When refreshing, the content of the menu is shown as active but the menu icon is not (i.e. it is not black). As I keep clicking on other menus, their menu icons are shown as active but their respective contents are not shown at all.
THE ATTEMPT
By the doing the following I obviously got contents overlapping...
$("div[class^=content]").addClass("active");
It is not clear to me how I can make a proper use of $(this) to also target the respective content of the current menu.
SUMMARY
Set the content of the respective menu active when such menu is also active.
When refreshing the browser, both the menu and content should be active (i.e. menu icon is black and the content of the respective menu is shown).
$(document).ready(function() {
$("a[class^=menu]").click(function() {
if ($("a[class^=menu],div[class^=content]").hasClass("active")) {
$("a[class^=menu],div[class^=content]").removeClass("active");
}
var href = $(this).attr("href");
$(this).addClass("active");
$(href).addClass("active");
});
if (window.location.hash.substr(1) != "") {
$("a[class^=menu],div[class^=content]").removeClass("active");
$('a[href="' + window.location.hash.substr(1) + '"]').addClass("active");
$("#" + window.location.hash.substr(1)).addClass("active");
}
});
.container {
margin: 0 auto;
background-color: #eee;
border: 1px solid lightgrey;
width: 20vw;
height: 90vh;
font-family: sans-serif;
position: relative;
}
header {
background-color: lightgreen;
padding: 5px;
text-align: center;
text-transform: uppercase;
}
.bottom-navbar {
position: absolute;
bottom: 0;
width: 100%;
padding: 6px 0;
overflow: hidden;
background-color: lightgreen;
border-top: 1px solid var(--color-grey-dark-3);
z-index: 50;
display: flex;
justify-content: space-between;
}
.bottom-navbar>a {
display: block;
color: green;
text-align: center;
text-decoration: none;
font-size: 20px;
padding: 0 10px;
}
.bottom-navbar>a.active {
color: black;
}
.menu-1.active,
.menu-2.active,
.menu-3.active {
color: black;
}
.content-1,
.content-2,
.content-3 {
display: none;
}
.content-1.active,
.content-2.active,
.content-3.active {
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translateX(-50%) translateY(-50%);
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.11.2/css/all.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<div class="container">
<header>My header</header>
<div class="main-content">
<div class="content-1 active" id="firstPage">House content</div>
<div class="content-2" id="secondPage">Map content</div>
<div class="content-3" id="thirdPage">Explore content</div>
<div class="bottom-navbar">
<i class="fa fa-home"></i>
<i class="fa fa-map"></i>
<i class="fa fa-search"></i>
</div>
</div>
UPDATE
The URL solution is essentially answered in the link below, although the suggestions in the comments helped tremendously in solving most of the problem before the browser was refreshed.
Selecting the anchor tag of a particular href using jQuery
As the buttons aren’t separated in a way that allows them to affect visibility of the content, you’ll need to explicitly address the particular element whose visibility you want to show. I’d suggesting inspecting the class of the menu item referenced by $(this) and following it by a conditional branch that handles the case for each of menu-1, menu-2, and menu-3, referencing their respective contents to set them active, e.g., $(‘.content-1’).addClass(‘active’)
As for persistence, you can store a variable that keeps track of what item is currently active and then activate that on page load through conditionals. Give this a read to see how to store that info: https://stackoverflow.com/a/16206342/12380239

Re-closing hidden content

I have a large document where this is implemented A LOT. I am hoping there is a way to simply edit the JavaScript somehow, so I have less editing.
Basically, clicking on a line of text opens the hidden text beneath it. You can close and re-hide the text by clicking on that same line of text... THAT is the ONLY way I want it to operate. As it is now, you can click on the hidden text anywhere and that will also close it. That is becoming a problem because I have interactive content in the hidden text area, and an accidental click in the wrong area will collapse it all.
.results_container {
cursor: pointer;
line-height: 21px;
}
.hidden>span {
display: none;
}
.visible>span {
cursor: default;
display: block;
line-height: 18px;
background: #f5f5f5;
padding: 15px;
margin: 10px 0px 32px 25px;
}
<div class="results_container">
Click Me to show hidden content
<span>I am hidden in span tags. You can close me by clicking anywhere in this text, however, I ONLY want to close the same way I opened; by clicking "Click Me to show hidden content.</span>
</div>
Full Fiddle
NOTE: On the fiddle, my JavaScript is at the end, under the pasted-in jQuery... sorry, that's the only way I could get it to work.
See the fiddle or below snippet:
https://jsfiddle.net/ejbdb128/6/
By checking against "this" in regards to the parent selector, you can filter out when you click on the child "span" element. I should note a caveat to this is if you click anywhere outside the "span" and in the div element, it will hide the span, even if you don't click just on the "Click Me" text..
/* SCRIPT for HIDDEN DESCRIPTIONS for RESULTS */
$(document).ready(function() {
"use strict";
$('.results_container').addClass("hidden");
$('.results_container').click(function(e) {
if (e.target != this) {
return false;
}
var $this = $(this);
if ($this.hasClass("hidden")) {
$(this).removeClass("hidden").addClass("visible");
} else {
$(this).removeClass("visible").addClass("hidden");
}
});
});
.results_container {
cursor: pointer;
line-height: 21px;
}
.hidden>span {
display: none;
}
.visible>span {
cursor: default;
display: block;
line-height: 18px;
background: #f5f5f5;
padding: 15px;
margin: 10px 0px 32px 25px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="results_container">
Click Me to show hidden content
<span>I am hidden in span tags. You can close me by clicking anywhere in this text, however, I ONLY want to close the same way I opened; by clicking "Click Me to show hidden content.</span>
</div>
Add the click handler to to an external event and use that to hide . By the way, jQuery has built in functions hide and toggle for hiding elements.
HTML:
<div class="results_container">
<span class="clickme">Click Me to show hidden content</span>
<span class="hideme">
I am hidden in span tags. You can close me by clicking anywhere in this text, however, I ONLY want to close the same way I opened; by clicking "Click Me to show hidden content.
</span>
Javscript:
$(document).ready(function(){
"use strict";
$('.hideme').hide();
$('.clickme').on('click', function() {
$('.hideme').toggle();
});
});
Fiddle here: https://jsfiddle.net/fLj6c4q7/

I need these buttons to control which div is showing or "on top"

I have these buttons on the side of my page, and a main content area taking up the better part of the page.
What I am trying to do is get the button I click to change the main content to a div containing the corresponding information. This is very hard to find, perhaps because I am searching by the wrong terms, and I have covered a good portion of stackoverflow without much luck.
I have though about absolutely positioning the divs and using a script to change the z-index of the the divs to the highest amount using a "=+1" type situation, but I could see that getting messy.
I have considered adapting a script I have that replaces part of an image file name in order to change a main picture on a page to a larger version of the image corresponding to a thumb name, though this script targets file names so it isn't going well.
I have also tried something along the lines of:
"id of button" onclick function = "main content class" change id to "corresponding div"
only in javascript talk, and this isn't working at all so I can only assume that I am either looking at it wrong or I have some messed up in the code.
$('#tabhead1').click(function() {
document.getElementByClassName("maintab").id = "tabs1";
});
This is driving me crazy and I would really appreciate some ideas. I tried to leave it free formed so that noone gets hung up on anyone solution.
**** Just to clarify, I have 5 divs id'd at #tabhead1, #tabhead2, #tabhead3, etc. and 5 content divs classed as .maintab, and id'd as tabs1, tabs2, tabs3, etc. I need the first content div to show automatically, and for that div to change based on the button clicked. at the moment all content divs are set to display: none; except the first one.
For each button, add a data attribute related to the corresponding <div>
for example
<button id="tabhead1" data-content="tabs1" >first Tab</button>
apply a common class for the tabs, for example .tab
Then you can do the following
$('button').click(function(){
var contentId = $(this).data('content'); // get the id of corresponding tab
$('.tab').hide(); // hide all tabs
$('#'+contentId).show(); //show the corresponding tab
});
You are using getElementbyClassName which does not exists. Use:
document.getElementsByClassName("maintab")[0].id = "tabs1";
// Get all elements to match classname + get first element from array
And for the rest, I don't know why you want to add id with JS? Why not just add them to your HTML?
Try this
$('#tabhead1').click(function() {
// get element with class 'maintab' and replace its content with that of another tab
$(".maintab").html($(".tabs1").html());
});
To expand a little on the demo I posted in the comments earlier:
This uses a method very similar to #tilwin-joy, so I guess we were of like mindedness. There are a couple of small differences that I would point out:
jQuery:
$('button').on('click', function () {
var button = $(this);
var target = button.data('target');
button.prop('disabled', true).siblings().prop('disabled', false);
$(target).show('slow').siblings().hide();
});
This uses siblings to hide the other content (one less pass at the DOM).
I suggest just setting your data value with the id hash in the markup, I think it's a bit clearer to read and follow (IMHO) in both the script and markup.
This script also sets the current button to be disabled when clicked. The benefit of this is that you can use the disabled property to style up your buttons, and even if you don't style them it gives a visual cue to the user as to which tab content is currently displayed. Check out the demo to see how this can be used for styling purposes.
HTML: (I stripped some of the unneeded ids from what you described as your markup).
<div class="tabhead">
<button data-target="#tabs1" disabled="true">Content 1</button>
<button data-target="#tabs2">Content 2</button>
<button data-target="#tabs3">Content 3</button>
<button data-target="#tabs4">Content 4</button>
<button data-target="#tabs5">Content 5</button>
</div>
<div class="maintab">
<div id="tabs1">
<img src="http://placehold.it/350/e8117f/fff&text=Image+1" alt="Image 1" />
<p>This is the content of tabs1.</p>
</div>
<div id="tabs2">
<img src="http://placehold.it/350/9acd32/fff&text=Image+2" alt="Image 2" />
<p>This is the content of tabs2.</p>
</div>
<div id="tabs3">
<img src="http://placehold.it/350/9400d3/fff&text=Image+3" alt="Image 3" />
<p>This is the content of tabs3.</p>
</div>
<div id="tabs4">
<img src="http://placehold.it/350/ffd700/fff&text=Image+4" alt="Image 4" />
<p>This is the content of tabs4.</p>
</div>
<div id="tabs5">
<img src="http://placehold.it/350/1e90ff/fff&text=Image+5" alt="Image 5" />
<p>This is the content of tabs5.</p>
</div>
</div>
CSS: Not needed - just to give you an idea of how you can style the elements to look like tabs.
/*This sets all but the first tab to hidden when the page is loaded*/
.maintab>div:not(:first-child) {
display: none;
}
/*The rest is just to style the elements to look like tabs*/
body {
background-color: #eaeaea;
}
.maintab, .tabhead {
text-align: center;
margin:0 20px;
font-family: sans-serif;
}
.maintab {
border: 1px solid #1e90ff;
border-top: none;
padding-top: 20px;
background-color: #fff;
}
.tabhead {
border-bottom: 1px solid #1e90ff;
position: relative;
margin-top: 20px;
}
button {
background-color: #ccc;
padding: 10px;
border: 1px solid #999;
border-bottom: none;
-webkit-border-top-left-radius: 4px;
-webkit-border-top-right-radius: 4px;
-moz-border-radius-topleft: 4px;
-moz-border-radius-topright: 4px;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
color: #999;
font-size: 14px;
cursor: pointer;
position: relative;
top: 2px;
}
button:disabled {
background-color: #fff;
border-color: #1e90ff;
color: #1e90ff;
top: 3px;
padding-top: 11px;
cursor: not-allowed;
z-index: 10;
}

Categories