Anchor element onClick makes page jump to top of page - javascript

I have a few buttons on my page and onclick they show or hide a few <div> elements.
The <div> elements are positioned towards the bottom of the page so scrolling to those <div> elements is necessary.
Whenever I click on a button, the page jumps to the top. So how do I create an anchor so that when the user clicks the button it will stay on that section of the page?
Here is one of the buttons:
<p class="text-center"><a id="Button-1" class="btn btn-default" href="#" role="button">View Details</a></p>
Here is the <div> that appears when the button above is clicked:
<div class="row">
<div id="Section-1" class="col-md-10">
<p>The section to appear.</p>
</div>
</div>
Here is the JavaScript:
$("#Button-1").click(function () {
$("#Section-2").hide();
$("#Section-3").hide();
$("#Section-1").toggle("show");
$("#Button-1").text(function(i, text) {
return text === "View Details" ? "Hide Details" : "View Details";
});
return false;
});
Here is my research:
Article 1
Any help would be appreciated.
UPDATE
<p class="text-center"><a id="Button-1" class="btn btn-default" href="javascript:void();" role="button">View Details</a></p>
When I click the button.. I scroll down to see the div that appeared.. then click on another button (that look the exact same as above) and the page returns to the top.

Firstly mention the element correctly in the title. Its a a not button.
Next: The # in your a tag will by default take you to the top of the page when you click on it.
Use a javascript:void() in the href attribute to overcome this.
Like <a href='javascript:void();'>something</a>
Example snippet
<div>
Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>Something<br>
<a href='javascript:void();'>this</a>
</div>

This is because an href starting in "#" jumps to the element of that id. For example, href="#mydiv" jump to the element with an id of "mydiv" (nothing happens if that element doesn't exist, so this could be a solution). In the case where no id is provided (ie. Your case; href="#"), it jumps to the top of the page. My go-to solution is adding a preventDefault to the click handler, which "negates" existing behaviors. It can be done like so:
$('.button').click(function() {
$('#lastclicked').text(this.textContent);
});
$('.button-x').click(function(e) { // Passes the event to the function to allow the prevent default function.
e.preventDefault();
$('#lastclicked').text(this.textContent);
});
// Click each of the buttons and notice how the first two jumps to either the div of the top, but the third button ("button-x") doesn't move anything.
body {
height: 5000px;
padding: 50px;
}
.buttons {
position: fixed;
bottom: 0;
}
.button, .button-x {
display: inline-block;
padding: 20px;
background: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="buttons">
Link with href="#"
Link with href="#mydiv"
Link with href="#", but a preventDefault.
</div>
<div id="mydiv">
Last clicked: <span id="lastclicked"></span>
</div>
The important part is the e.preventDefault(), which is the function that blocks the initial behavior of the anchor tag. All you have to do is put that somewhere in your click handler. Make sure to pass "e" as a parameter.

General fix
Don't use <a>-Tags for your buttons. Convert the <a>-Tags to <button>-Tags or something else (span, p, etc.)
Explanation
That is pretty simple. Your <a>-Tags (namely the buttons) link to '#' which is the so called fragment part of an URI.
Usually fragments are HTML tags which are identified by a name (pre-HTML5)
<a name="top">This is the top section</a>
Jump to top
or an id (HTML5)
<div id="my-section">Coming soon</div>
Jump to my-section
Because you didn't specify the fragment or didn't use correct one the browser will scroll to the top of the page.

Have you tried this solution from http://stackoverflow.com/questions/11815295/javascript-inline-onclick-goto-local-anchor
You can use this function on your anchor:
function goToAnchor(anchor) {
var loc = document.location.toString().split('#')[0];
document.location = loc + '#' + anchor;
return false;
}
Usage:
Anchor
Note that the anchor needs to be enclosed in quotes, without the hash prefix.

update href property of a tag to javascript:void();
<p class="text-center"><a id="Button-1" class="btn btn-default" href="javascript:void();" role="button">View Details</a></p>
Demo
javascript:void(); It'll not let link to navigate anywhere.

I suggest you a different approach more generic. Easiest to use and maintain.
Use only one class for each button to detect the click. And store in data property the element that you want to show.
$(".btn-section").click(function(){
var classToShow = $(this).data("class-show");
$(".section").hide();
$("." + classToShow).show();
});
.section{
display:none;
}
.content{
width:100%;
height:2000px;
background-color:#ccc;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="content">Lot of content</div>
<button class="btn-section" data-class-show="section1">Section 1</button>
<button class="btn-section" data-class-show="section2">Section 1</button>
<button class="btn-section" data-class-show="section3">Section 1</button>
<div class="section section1">Section 1</div>
<div class="section section2">Section 2</div>
<div class="section section3">Section 3</div>
This resolve your problem too.

Related

How to hide an element in if statement?

I am making an html change to a CMS that will affect all pages when the changes are live. I would like this html alert to only affect 1 specific page. I am attempting to do an if statement for the page title.
The logic is that if the page title is Test Article Two then show the html that I have put in place, if not then display=none. With this logic in place, I am viewing the html on all pages not just the one I want it to show.
<div class="container">
<div class="title-wrapper">
<span id="article-banner-country">#countryFullText</span> /
<span id="article-banner-category">#subCatText</span>
<div id="article-banner-title">#pageTitle</div>
<!--page alert -->
<div class="feedback-container content-desktop" id="alert-dialog">
<div class="feedback-left">
<p>Have any feedback? Reach out to us!</p>
</div>
<div class="feedback-right">
<button class="feedback-button">Give Feedback</button>
<button class="feedback-button">Dismiss</button>
</div>
</div>
</div>
</div>
<script>
function showAlert() {
if(#pageTitle === "Test Article Two") {
document.getElementById('alert-dialog').style.display = 'block';
}else {
document.getElementById('alert-dialog').style.display = 'none';
}
}
</script>
I'd recommend changing a class on the body element so that you can use CSS for the styling.
HTML: nothing really changed here
<body>
<div class="container">
<div class="title-wrapper">
<span id="article-banner-country">#countryFullText</span> /
<span id="article-banner-category">#subCatText</span>
<div id="article-banner-title">#pageTitle</div>
<div class="feedback-container content-desktop" id="alert-dialog">
<div class="feedback-left">
<p>Have any feedback? Reach out to us!</p>
</div>
<div class="feedback-right">
<button class="feedback-button">Give Feedback</button>
<button class="feedback-button">Dismiss</button>
</div>
</div>
</div>
</div>
</div>
</body>
javascript: just check the document.title and add the class the the body element
<script>
if(document.title === "Test Article Two") {
document.body.classList.add("show-alert");
}
</script>
Use CSS for the styling. Always hide #alert-dialog and only show it when we add the class to the body.
<style>
#alert-dialog {
display: none;
}
.show-alert #alert-dialog {
display: block;
}
</style>
If you are making static pages or using server side rendering, you could add logic to add a class to show or hide the alert element without adding more javascript to the page. It will have the relevant class(es) when the html is generated and delivered. This way you won't have to create a function, call it and manipulate the DOM after everything is rendered.
I may have missed this in the code above, are you calling the showAlert function anywhere? If not, your alert won't be shown (or will be shown depending on the default styles).
One thing I'd caution against is the imperative nature of the code here. If you wanted to reuse this alert functionality on another page, you'd have to add another more logic to detect another page title every time you wanted to use the alert. Since you are using a CMS, you might consider adding a flag to show the alert, and on this specific page, turn that flag on.
If you wanted to use the function strategy, I'd set your default alert styles:
#alert-dialog {
display: none;
}
.show {
display: block;
}
and try something like this:
<script>
function showAlert() {
if(document.title === "Test Article Two") {
document.getElementById('alert-dialog').classList.add('show');
}
}
document.addEventListener("DOMContentLoaded", showAlert);
</script>
Another alternative is to take a look at the path of the page this is supposed to be on (window.location.pathname) and using regex to see if it matches what you want. I'd recommend that over looking at the title since it's more likely the title of the page will change rather than the url.
In JavaScript, you can access the page title with document.title. You should change the script like this:
function showAlert() {
if(document.title === "Test Article Two") {
document.getElementById('alert-dialog').style.display = 'block';
} else {
document.getElementById('alert-dialog').style.display = 'none';
}
}

Show/ hide multiple divs with closing function

I almost give up. Can't find any solution on this so I hope you can help me. I have a script that shows/hides divs and it's working like this. If you click one button a div shows and if you press another button it switches to that div. That's working great. But I want to be able to close all divs with the last button clicked.
This is my HTML
<div class="hidden-divs-buttons">
<a class="show-div btn" target="1">Div 1</a>
<a class="show-div btn" target="2">Div 2</a>
</div>
<div class="hidden-divs">
<div id="div1" class="target-div">Content div 1</div>
<div id="div2" class="target-div">Content div 2</div>
</div>
This script works but has no closing functionality
$('.show-div').click(function() {
$('.target-div').hide();
$('#div' + $(this).attr('target')).fadeIn(1000);
});
And this is the script I want to replace the working script with. I have been trying to change it to work with closing function. I might be totally of but hopefully you guide in the right direction. I get an error that tell me "box.hasClass() isn't a function".
$('.show-div').click(function() {
var box = $('#div' + $(this).attr('target'));
$('.target-div').hide();
if(box.hasCLass('close-div')) {
box.removeClass('close-div');
$('.target-div').fadeOut(1000);
} else {
box.fadeIn(1000);
box.addClass('close-div');
}
});
Edit Id's are updated.
This is how the code became. With this code I can click on a button and show a div, click the next one to show another div. If I click the same button again it will close all divs.
$('.show-div').click(function() {
var box = $('#div' + $(this).attr('target'));
if(box.hasClass('close-div')) {
$('.target-div').removeClass('close-div');
$('.target-div').fadeOut(1000);
} else {
$('.target-div').removeClass('close-div');
$('.target-div').hide();
box.fadeIn(1000);
box.addClass('close-div');
}
});
You have typo in if(box.has[CL]ass('close-div')) {
hasClass not hasCLass
hasClass does not have a capital L - it's hasClass not hasCLass not sure if this is just a typo in the question or your real code.
Also both your divs in the hidden-divs section have the same id of div1, when they should presumably be div1 and div2. In any event it would be better to specify the full id of the div as the target instead of building it.
In addition, you are applying hide to all elements of class target-div before fading them out, which rather defeats the idea of a fadeout
<div class="hidden-divs-buttons">
<a class="show-div btn" target="div1">Div 1</a>
<a class="show-div btn" target="div2">Div 2</a>
</div>
<div class="hidden-divs">
<div id="div1" class="target-div">Content div 1</div>
<div id="div2" class="target-div">Content div 2</div>
</div>
$('.show-div').click(function() {
var box = $('#' + $(this).attr('target'));
// this makes them invisible, so fadeOut is pointless
$('.target-div').hide();
if(box.hasClass('close-div')) {
box.removeClass('close-div');
$('.target-div').fadeOut(1000);
} else {
box.fadeIn(1000);
box.addClass('close-div');
}
});

How to simultaneously hide and show content and vice versa?

I have a problem and I need your help. I have several links (in <aside>) leading to several different menus (in <section>). On click over the link, only the relevant div in <section> is shown, the rest are hidden. This part is ok and working. What is not working is when I click over an image:
the current div (.menu) in <section> should be hidden;
the same picture (with bigger size) should be shown;
when you click once again over the big image, the big image should disappear and the current div in .menu (the one that was hidden on the first step) should appear one more time. Sort of toggling between content.
So if I click on a picture on the "second div" content, the same picture with bigger size should be show (the "second div" content should be hidden) and when I click once again over the big picture it should disappear and the "second div" content to be returned.
I tried with toggle() but had no success. Either I did not use it correctly, or it is not suitable for my case. This is where I managed to reach to.
I will really appreaciate your support - how to show only the hidden div, not all hidden div's. Right now, when you click on the big image it did not show the hidden div.
$(window).on("load", function() {
$("div.menu:first-child").show();
});
$(".nav a").on("click", function() {
$("div.menu").fadeOut(30);
var targetDiv = $(this).attr("data-rel");
setTimeout(function() {
$("#" + targetDiv).fadeIn(30);
}, 30);
});
var pictures = $(".img-1, .img-2").on("click", function() {
$("div.menu:active").addClass("hidden");
//how to reach out only the current, active div (not all div's in .menu)?
$(".menu").hide();
var par = $("section")
.prepend("<div></div>")
.append("<img id='pic' src='" + this.src + "'>");
var removePictures = $("#pic").on("click", function() {
$(this).hide();
$(".hidden").show();
});
});
.menu {
width: 100%;
display: none;
}
.menu:first-child {
display: block;
}
.row {
display: inline-block;
width: 100%;
}
.img-1,
.img-2 {
width: 120px;
height: auto;
}
<!doctype html>
<html>
<head>
</head>
<body>
<aside>
<ul class="nav">
<li>To first div
</li>
<li>To second div
</li>
<li>To third div
</li>
</ul>
</aside>
<section>
<div class="menu" id="content1">
<h3>First Div</h3>
<div class="present">
<div class="row">
<div>
<p>Blah-blah-blah. This is the first div.</p>
<img class="img-1" src="http://www.newyorker.com/wp-content/uploads/2014/08/Stokes-Hello-Kitty2-1200.jpg">
</div>
</div>
<div class="row">
<div>
<img class="img-2" src="https://jspwiki-wiki.apache.org/attach/Slimbox/doggy.bmp">
<p>Blah-blah-blah. This is the first div.</p>
</div>
</div>
</div>
</div>
<div class="menu" id="content2">
<h3>Second Div</h3>
<div class="present">
<div class="row">
<div>
<p>
Blah-blah-blah. This is the second div.
</p>
<img class="img-1" src="http://www.newyorker.com/wp-content/uploads/2014/08/Stokes-Hello-Kitty2-1200.jpg">
</div>
</div>
<div class="row">
<div>
<img class="img-2" src="https://jspwiki-wiki.apache.org/attach/Slimbox/doggy.bmp">
<p>
Blah-blah-blah. Yjis is the second div.
</p>
</div>
</div>
</div>
</div>
<div class="menu" id="content3">
<h3>Third Div</h3>
<div class="present">
<div class="row">
<div>
<p>
Blah-blah-blah. This is the third div.
</p>
<img class="img-1" src="http://www.newyorker.com/wp-content/uploads/2014/08/Stokes-Hello-Kitty2-1200.jpg">
</div>
</div>
<div class="row">
<div>
<img class="img-2" src="https://jspwiki-wiki.apache.org/attach/Slimbox/doggy.bmp">
<p>
Blah-blah-blah. This is the third div.
</p>
</div>
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
</body>
</html>
Sorry for the ugly sketch and pictures - it is only to get an idea what it should look like....
In general, it's poor form to ask on Stack Overflow how to code for a specific behavior. However, that takes some understanding of the libraries you're using, and what you are trying to achieve. Hopefully, my answer will help you better articulate and form your questions in the future.
Here's a fiddle for you: https://jsfiddle.net/hwd4b0ag/
In particular, I've modified your last click listener:
var pictures = $(".img-1, .img-2").on("click", function() {
var parentDiv = $(this).closest('div.menu').hide();
var blownUpPic = $("<img>").attr({
id: 'pic',
src: this.src,
'data-parent': parentDiv.attr('id')
})
.appendTo("section")
.on('click', function() {
$('#' + $(this).attr('data-parent')).show();
$(this).remove();
});
});
Now, let's review it!
First,
var parentDiv = $(this).closest('div.menu').hide();
In a jQuery listener, the this variable stores the current javascript DOM element that is the recipient of the event listener. In your case, it refers to an element that matches ".img-1, .img-2".
.closest(selector) will traverse up the DOM (including the current element) and find the first matching element for the provided selector. In this case, it finds your container div with class menu. Then we hide that div and save a reference to it in a variable.
Next, we create a full-sized version of the picture and assign it some attributes:
var blownUpPic = $("<img>").attr({
id: 'pic',
src: this.src,
'data-parent': parentDiv.attr('id')
})
We set the data-parent attribute to the id of our container div, so we have a reference back to it later.
We then add our image to the DOM:
.appendTo("section")
And declare a new click listener for it:
.on('click', function() {
$('#' + $(this).attr('data-parent')).show();
$(this).remove();
});
With $(this).attr('data-parent') we use the reference to our container div that we assigned earlier, and then retrieve that element by its id. We unhide the container div and remove the full-sized image.
All done!
There are better ways to code this, but I think this is a good next step for you that's analogous to your current code.

jquery toggle open all div s on one click

Please take a look at below codes, for whatever reason I am unable to open one div only when I click on the edit link, it opens all divs when I click the edit link.
jQuery
$(document).ready(function () {
$("input:button[name='uploadboy']").click(function () {
$(this).parent().children('.uploadboy').slideToggle(200, 'swing');
});
});
HTML
<div style="overflow:auto;" class="links-box ">
<p style="float:left; width:250px;" id="links">
<input type="button" name="uploadboy" id="uploadboy" value="Uploaded" title="Uploaded" style="text-decoration:none; color: white; text-shadow:none; background: #0692fe; float:left;" class="g-button">
</p>
</div>
<div class="uploadboy" width: 600px;min-height:50px;background-color: #F2FDD7;border-radius: 10px;border: 1px solid #8EBD43;">
<p>content</p>
</div>
<div style="overflow:auto;" class="links-box ">
<p style="float:left; width:250px;" id="links">
<input type="button" name="uploadboy" id="uploadboy" value="Uploaded" title="Uploaded" style="text-decoration:none; color: white; text-shadow:none; background: #0692fe; float:left;" class="g-button">
</p>
</div>
<div class="uploadboy" width: 600px;min-height:50px;background-color: #F2FDD7;border-radius: 10px;border: 1px solid #8EBD43;">
<p>content</p>
</div>
example in jsFiddle
Use the below script, .find method only searches for the descendants (http://api.jquery.com/find/).
$(document).ready(function () {
$("input:button[name='uploadboy']").click(function () {
$(this).parent().parent().next('.uploadboy').slideToggle(200, 'swing');
});
});
As I mentioned in my comment above, IDs must be unique. That said, try this:
$("input").click(function () {
$(this).slideToggle(200, 'swing');
});
jsFiddle example
What I initially see here that's an issue is that you have 2 input buttons with the same id. While this may not be the overall issue, you still can't have 2 elements with the same id. I also am not sure if this is just generic code you cleaned to ask a question, but your selectors seem pretty complicated. You attach the .click event to both input buttons, then you go to the buttons parent, which is the paragraph, then you go the child object which is the button. You are essentially going from point one spot, up a level, then back down a level. When the click handler is attached to the button, anytime you click a button, you can reference $(this) to refer to the button.
<input type="button" name="uploadboy" id="button1" />
<input type="button" name="uploadboy" id="button2" />
$(document).ready(function(){
$("input:button[name='uploadboy']").click(function () {
$(this).SlideToggle(200, 'swing');
});
});
If you look at the function that is ran when the input button is clicked, it simply refers to the $(this) object. This is a benefit of jquery and $(this) is the specific button that you clicked. Even if there are 20 buttons on the page, whatever button is clicked will be this. So in the above example, the button clicked will have the slide toggle occur. You could also navigate the dom off of this if you need to move around like before.

Javascript change div content upon a click

I'm pulling a content from PHP array and I have a situation like this:
<div class="weight-display">
<span>04/25/2011</span> <span>100lbs</span> <span>Edit</span> <a href="http://foo.com">Delete</span>
</div>
<div class="weight-display">
<span>04/27/2011</span> <span>150lbs</span> <span>Edit</span> <a href="http://foo.com">Delete</span>
</div>
etc...
Now when somebody clicks on Edit within, let's say, first div where weight is 100lbs, I just need that "div" to change and to have input field instead of simple text where weight is (while others will remain the same) and to be like this:
<div class="weight-display">
<span>04/25/2011</span> <input type="text" value="100" /> <span>Save</span> <span>Cancel</span>
</div>
<div class="weight-display">
<span>04/27/2011</span> <span>150lbs</span> <span>Edit</span> <a href="http://foo.com">Delete</span>
</div>
etc..
So basically div has to "reload itself" and change content. Now I really need some very simple Javascript solution. Preferably I would like a solution with a hidden div beneath original one, so they just swap places when user clicks on EDIT and in a case if CANCEL is pressed to swap places again so original div with text is displayed...
Thanks,
Peter
<style type="text/css">
/* Normal mode */
.weight-display div.edit {display:none}
/* Editor mode */
.weight-edit div.show {display:none}
</style>
<div class="weight-display">
<button onclick="toggle(this)">Edit this!</button>
<div class="edit"><input type="text" value="Test" /></div>
<div class="show">Test</div>
</div>
<script type="text/javascript">
function toggle(button)
{
// Change the button caption
button.innerHTML = button.innerHTML=='Edit this!' ? 'Cancel' : 'Edit this!';
// Change the parent div's CSS class
var div = button.parentNode;
div.className = div.className=='weight-display' ? 'weight-edit' : 'weight-display';
}
</script>
What you suggest is basically correct. I would generate two div's one for display and one edit. The edit div will initially have display: none. When the Edit is clicked, hide the display div and show the edit div.
How about something like:
onClick event calls a function (EDITED to be a little smarter than my original brute force method):
function swapdivs ( id_of_topdiv, id_of_bottomdiv ) {
var topdiv = getRefToDiv( id_of_topdiv );
var bottomdiv = getRefToDiv( id_of_bottomdiv );
var temp = topdiv.style.zIndex;
topdiv = bottomdiv.style.zIndex;
bottomdiv = temp.style.zIndex;
}
Could that or similar work for you? Or am I missing some subtle yet crucial requirement?

Categories