Ahref links/anchors moving page down vertically preventDefault(); - html

This is no doubt very basic HTML, but I have a problem with some anchor tags. I have a page with three overlapping tabs. You click on the tab and the contents come to the front. THe problem is that the page moves vertically down so that the tab is at the top of the page (they are halfway down usually).
Attached is my script to perform the function, as well as a version of the HTML associated.
I think I need to use preventDefault(); somewhere, but not sure where. Any ideas appreciated.
<!--Javascript function to brings tabs to the front-->
<script type="text/javascript">
$(document).ready(function () {
$("div.tab-headers>a").click(function () {
// Grab the href of the header
var _href = $(this).attr("href");
// Remove the first character (i.e. the "#")
_href = _href.substring(1);
// show this tab
tabify(_href);
});
tabify();
});
function tabify(_tab) {
// Hide all the tabs
$(".tab").hide();
// If valid show tab, otherwise show the first one
if (_tab) {
$(".tab a[name=" + _tab + "]").parent().show();
} else {
$(".tab").first().show();
}
}
// On page load...
$(document).ready(function () {
// Show our "default" tab.
// You may wish to grab the current hash value from the URL and display the appropriate one
// tabify();
});
</script>
My HTML is:
<div class="glossary">
<div class="tab-headers">
</div>
<!--Tab 1-->
<div class="tab">
<a name="tab1"></a>
contents 1 here
</div>
<!--Tab 2-->
<div class="tab">
<a name="tab2"></a>
contents 2 here
</div>
<!--Tab 3-->
<div class="tab">
<a name="tab3"></a>
contents 3 here
</div>
</div>

I believe the preventDefault() should go here:
$("div.tab-headers>a").click(function(e){
e.preventDefault();
....
Notice the added (e) after the function. So that would result in the following code:
<!--Javascript function to brings tabs to the front-->
<script type="text/javascript">
$(document).ready(function () {
$("div.tab-headers>a").click(function (e) {
e.preventDefault(); // normal behavior is stopped
// Grab the href of the header
var _href = $(this).attr("href");
// Remove the first character (i.e. the "#")
_href = _href.substring(1);
// show this tab
tabify(_href);
});
tabify();
});
function tabify(_tab) {
// Hide all the tabs
$(".tab").hide();
// If valid show tab, otherwise show the first one
if (_tab) {
$(".tab a[name=" + _tab + "]").parent().show();
} else {
$(".tab").first().show();
}
}
// On page load...
$(document).ready(function () {
// Show our "default" tab.
// You may wish to grab the current hash value from the URL and display the appropriate one
// tabify();
});
</script>

Related

Attempting to remove anchor tags from the URL

Situation: I want to remove the anchor tags ( #tag ) from the end of the URL
What I have tried: I have been following "https://www.finsweet.com/hacks/15/" and "https://stackoverflow.com/questions/34175285/removing-anchor-tags-from-url". Its not working out very well though.
Code:
My snippet from the top nav bar
<ul class="nav">
<li class="scroll-to-section">
Home
</li>
</ul>
My use of Id
<div class="main-banner header-text" id="top">
Maybe the way i approached the edits to the navigation bar is wrong.. but im not sure what i need to to do to achieve the goal. Or how I used the classes and IDs is possibly incorrect?
--- Edit 1 ---
this is the snipper of the script im attempting to use to remove the anchor tag from the URL bar of a brower.
$("#js-anchor").click(function (evt) {
evt.preventDefault();
var anchor = $(this).text();
$("html, body").animate(
{
scrollTop: $("#" + anchor).offset().top,
},
1500
);
});
And the html im looking at
<li class="scroll-to-section">
<a id="js-anchor" href="#testimonials" class="active"
>staff</a>
</li>
The experment on it is here:
https://the-md.studio/indexhash.html
EDIT2
My new attempt
<li class="scroll-to-section">
Home
</li>
JS
$(document).ready(function () {
// get the anchor link buttons
const menuBtn = $(".scroll-to");
// when each button is clicked
menuBtn.click(() => {
// set a short timeout before taking action
// so as to allow hash to be set
setTimeout(() => {
// call removeHash function after set timeout
removeHash();
}, 5); // 5 millisecond timeout in this case
});
// removeHash function
// uses HTML5 history API to manipulate the location bar
function removeHash() {
history.replaceState(
"",
document.title,
window.location.origin + window.location.pathname + window.location.search
);
}
});
Just saw this Q. I guess this is what you tried to ask:
// first: get the full url
var hash_url = window.location.href;
// second: simply do a split
// can't go wrong here, because url's that show content are always in correct format
hash_url = hash_url.split('#'); var clean_url = hash_url[0];
alert(clean_url);
There's your clean url!

Hide div and store local storage not to show div on page refresh

I have an image button in a div when click I want to hide image button and somehow store to local storage not to show div again on page refresh.
<div class="whatsapp"><a href="https://chat.whatsapp.com/........." target="_blank">
<img src="/img/whatsapp_group.png" alt="Whatsapp Join Button"><div class="whatsappbut">To Find Out MORE!</div></a></div>
I added an ID(id="img-btn") to your div to use it in script tag. If user didn't click on your image button so far, localStorage.getItem('img-btn-clicked') will return null otherwise it'll return 'true'(as we set it in saveClicked function).
Just make sure to put the script tag before the body tag ends(or you can link a separated Javascript file).
<body>
<div id="img-btn" class="whatsapp">
<a href="https://chat.whatsapp.com/........." target="_blank">
<img src="/img/whatsapp_group.png" alt="Whatsapp Join Button" />
<div class="whatsappbut">To Find Out MORE!</div></a>
</div>
<script>
checkImgBtnClicked();
function checkImgBtnClicked() {
const clicked = localStorage.getItem('img-btn-clicked'); // if this is not set it will return null
if (clicked) {
document.getElementById('img-btn').style.display = 'none'; // hides the img-btn
} else {
// add event listener for image button click(saveClicked function will be executed if user clicks on image button
document.getElementById('img-btn').addEventListener('click', saveClicked);
}
}
function saveClicked() {
// set a flag in local storage that image button is clicked
localStorage.setItem('img-btn-clicked', 'true');
document.getElementById('img-btn').style.display = 'none'; // hides the img-btn after it gets clicked
}
</script>
</body>

JQuery populate div with link content but also need to move (like anchor link) to area where div located

I have unordered list of links. Using JQuery, when clicked, the link's contents (a div with image and text) are loaded into the section specified. This all works beautifully. But I'm wondering how to also get the onclick function to move the view to the div's location on the page similarly to how anchor tag works. Here is the site where you can see the div being populated, but not moving down to view it. https://www.thecompassconcerts.com/artists.php
My JQuery knowledge is not awesome (I'm being generous).
I followed Osama's suggestion to add event listener and I got almost correct results. Upon first click...contents are loaded but do not move. But on every successive click, it functions perfectly: Contents loaded and move to div (like an anchor link) works! BUT...not on Safari or Mobile Safari.
Here is my jQuery. I assume if first click is not working that I must add listener before the first click?? Can the event listeners be added on page load BEFORE the function to prevent default click, etc.?
<script>
// BEGIN FUNCTION TO CAPTURE AND INSERT CONTENT
$(document).ready(function () {
// PREVENT DEFAULT LINK ACTION
$('.bio').click(function (e) {
e.preventDefault();
// ADD LISTENER TO EACH ITEM BY CLASS
var list = document.getElementsByClassName("bio");
for (let i = 0; i < list.length; i++) {
list[i].onclick = moveToDiv;
}
// FUNCTION TO MOVE TO LOCATION
function moveToDiv() {
document.location = "#performbio";
}
// STORE the page contents
var link = $(this).attr("href");
// load the contents into #performbio div
$('#performbio').load(link);
});
});
</script>
Here is the HTML with links in unordered list
<!-- CONTRIBUTING ARTISTS LIST AND BIOS -->
<section id="artists">
<h2>Contributing Artists</h2>
<ul class="cols">
<li><a class="bio" href="performers/first-last.html">First Last</a></li>
<li><a class="bio" href="performers/first-last.html">First Last</a></li>
<li><a class="bio" href="performers/first-last.html">First Last</a></li>
</ul>
</section>
Here is HTML of Section where code is being inserted by function
<!-- Performer Bios Dynamically updated -->
<section id="performbio">
</section>
Here is div contents that are being inserted
<div class="artistbio">
<p class="artistname">First Last</p>
<img class="artistimg" src="performers/img/name.jpg">
<p>lots of text here</p>
</div>
If I understand it right, you want to scroll to the section where the details appear on clicking any item in the list but through js and not HTML. In that case, you would add an onclick listener on to the list elements like so:
listElement.onclick = moveToDiv;
The function:
function moveToDiv() {
document.location = "#performbio";
}
A simple way to add a listener to all of the elements:
var list = document.getElementsByClassName("bio");
for (let i = 0; i < list.length; i++) {
list[i].onclick = moveToDiv;
}
For the edited post, you need to move the function definition out of the document.ready function. you would change the script to:
// FUNCTION TO MOVE TO LOCATION
function moveToDiv() {
document.location = "#performbio";
}
$(document).ready(function () {
// PREVENT DEFAULT LINK ACTION
$('.bio').click(function (e) {
e.preventDefault();
// ADD LISTENER TO EACH ITEM BY CLASS
var list = document.getElementsByClassName("bio");
for (let i = 0; i < list.length; i++) {
list[i].onclick = moveToDiv;
}
// STORE the page contents
var link = $(this).attr("href");
// load the contents into #performbio div
$('#performbio').load(link);
});
});
Another Solution: Using scrollIntoView
First, get all the elements into a variable using querySelectorAll
var elements = document.querySelectorAll(".bio");
Then create a function, for the scrolling part:
function scroll(element) {
element.scrollIntoView();
}
Then just add the onclick listener:
for (let i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', function() {
scroll(elements[i]);
});
}
I found it very frustrating to try to accomplish these two tasks so instead of a jQuery solution I opted for a CSS solution.
I populated my DIV with all the php includes, gave them unique id's for the anchors to work and then used CSS to hide them by default until clicked and it works like a charm....shows only what I need to show and goes there like an anchor is supposed to.
I must thank Ghost for all of your help and efforts to try and solve this via jQuery. You were very kind and generous.
Here is the code I used:
My collection of links.
<li><a class="bio" href="#artist-name1">Name 1</a></li>
<li><a class="bio" href="#artist-name2">Name 2</a></li>
which anchors to these divs
<div class="bio-container" id="artist-name1">
<?php include('performers/name-lastname.html'); ?>
</div>
<div class="bio-container" id="artist-name2">
<?php include('performers/name-lastname.html'); ?>
</div>
Then I use this CSS to hide those divs until the anchors are clicked.
I'm using [id*="artist-"] to target only links with such text...very easy. Not ideal for a massive list...but mine is not so large so it will do for this situation.
[id*="artist-"] {display: none;}
[id*="artist-"]:target {display: block;}

Keep URL unaffected when anchor link is clicked

I've checked other posts on here, no results of what I'm looking for.
I want to click on
About
<div id="about">Content of this..</div>
and have it scroll to that element without putting www.domain.com/#about in the address bar
As a perfect example please check out this site that I found here and click on some of the links --they don't change the address bar when clicked.
You can do what you want using javascript and jquery, example below (note that this is using an old version of jquery):
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7/jquery.min.js"></script>
<script type='text/javascript'>
jQuery(document).ready(function($) {
$(".scroll").click(function(event){
event.preventDefault();
$('html,body').animate({scrollTop:$(this.hash).offset().top}, 1200);
});
});
</script>
</head>
<body>
<a class="scroll" href="#codeword">Blue Words</a>
<div id="codeword"></div>
</body>
</html>
Played around with this myself and here is a summary of my learnings on the subject.
Here's the basic link command:
Blue Words
Here's how you denote where the jump will scroll the page:
<A NAME="codeword">
Here's what's happening
The A HREF command is the same as a basic link except the link is to a codeword rather than a URL.
PLEASE NOTICE there is a # sign in front of the codeword. You need that to denote it is an internal link. Without the # sign, the browser looks for something outside the page named after your codeword.
Your "codeword" can be just about anything you want. I try my best to keep it short and make it denote what it is jumping to. There might be a limit to the number of letters you can use--but I haven't found it yet.
The point where the page will jump follows the same general format except you will replace the word HREF with the word NAME.
PLEASE NOTICE there is no # sign in the NAME command.
Note! Where you place the NAME target will appear at the top of the screen browser.
Hope it helps.
window.location.hash = ""
is the possible way I could find.
hash gives the string next to #.
//dont use a, use class
$(document).ready(function(){
$(".mouse").on('click', function(event) {
// Make sure this.hash has a value before overriding default behavior
if (this.hash !== "") {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (800) specifies the number of milliseconds it takes
to scroll to the specified area
$('html, body').animate({
scrollTop: $("#section").offset().top
}, 800, function(){
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = "";
});
} // End if }); });
One possible workaround is to use a <button> instead of a <a>.
So rather than....
About
<div id="about">Content of this..</div>
...you can change it to
<button href="#about">About</button>
<div id="about">Content of this..</div>
This way the anchor link will not affect the URL.
For me, only inserting "return false;" solved this issue.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.12.1/jquery-ui.min.js" async></script>
<script>
jQuery(document).ready(function($) {
$('a[href^=#]:not(a[href=#])').click(function() {
$('html, body').animate({scrollTop: $(this.hash).offset().top}, 1300, 'easeInOutExpo');
return false;
});
});
</script>
(This applies to all anchor links on the page.)
I tried to monitor window.location.hash using a MutationObserver, but that doesn't work, see How to use (or is it possible) MutationObserver to monitor window.location.pathname change?
So now I'm using the window.onpopstate() eventListener:
var flag_onpopstate=false; // use this global flag to prevent recursion
window.onpopstate = () => {
if (flag_onpopstate) return;
flag_onpopstate = true;
window.location.hash = "";
flag_onpopstate = false;
}
A popstate event is dispatched to the window each time the active history entry changes between two history entries for the same document.

Show div on image click then hide it after x seconds

I'm trying to show a div when an image is clicked and then hide it after a given number of seconds. I've found two separate code samples that match my needs but I don't have the knowledge to put them together.
the code which makes content disappear after x seconds:
<script>
window.setTimeout(function() {
$('#fadeout').hide(2000);
}, 4000);
</script>
The code which makes the div appear on imageclick:
<SCRIPT>
function fade(div_id, button) {
if(button.value == 'FadeOut') {
$('#'+div_id).fadeOut('slow');
button.value = 'FadeIn';
}
else {
$('#'+div_id).fadeIn('slow');
button.value = 'FadeOut';
}
}
$('#sometext').fadeOut(2);
</script>
Maybe this could help:
$('#fadeout').hide(); // hide div
$('img').live('click', function(e){
e.preventDefault(); //cancel default action of click
$('#fadeout').show().delay(5000).fadeOut(1000); //show div on img click then hide after 5 seconds
});
here's a working sample: http://jsfiddle.net/7X767/3/
Instead of using 'slow', you can use time value in milliseconds.