2 Links in One Anchor - javascript

I have a <ul><li><a> structure that is stylized very specifically and has 9 elements separated in 3 columns. I want to add another item without making a 4th column so the solution I'm considering is having 2 links in one 'slot'.
The problem with this is that the <ul><li><a> is structured such that adding an <a> will automatically create another slot (vertically).
I'm hoping not to have to recreate the entire structure from scratch in order to accommodate this change, so I'm trying to come up with a hack.
I KNOW THIS IS UGLY AND WEIRD but it does make for an interesting problem atleast...
I tried doing:
link1 <span onclick="location.href ='link2.html'">link2</span>
But that doesn't work - I also tried with jQuery but that didn't work either. Is there a workaround/hack here or do I have to restructure the entire list?

Here's a quick and easy way to have the a and span elements take you to different links. (I commented out the actual link and used alerts instead, since the links won't load in the frame anyway.)
function goToLink(e, that) {
e.stopPropagation();
if (that.tagName.toUpperCase() == "A") {
// if anchor was clicked
alert("1st link");
//window.location.href = "http://www.google.com";
}
else {
// if span was clicked
alert("2nd link");
//window.location.href = "http://www.yahoo.com";
}
}
link1 <span onclick="goToLink(event, this);">link2</span>
The stopPropagation() call prevents the first link from loading when the second link is clicked.

$('#link2').click(function() {
window.setTimeout(function() {
location.href = $('#link2').attr('data-href')
}, 10)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
link1 <span id='link2' data-href="link2.html">link2</span>

Related

How to reuse my code for opening Accordions on click

I'm currently using the following JS to open an accordion when an <a> tag is clicked. It uses the data-trigger value to determine what <a> to use.
<script type="text/javascript">
$('[data-trigger="accordion"]').on('click', function(e) {
var obj = $(this),
accordionButtons = $('[href*="#"]', '[data-accordion] .accordion-navigation'),
accordionPanels = $('.content.1', '[data-accordion]');
if (obj.hasClass('toggle-open')) {
accordionButtons.removeClass('active');
accordionPanels.removeClass('active');
obj.removeClass('toggle-open');
} else {
accordionButtons.addClass('active');
accordionPanels.addClass('active');
obj.addClass('toggle-open');
}
$('[href*="#"]', '[data-accordion] .accordion-navigation').trigger('click.fndtn.accordion');
window.location.href = "#" + anchor;
e.preventDefault();
});
</script>
This above JS will open an accordion based on it's class. Below is an example of the link that is used to open the Accordion:
<a href="#protect-the-nhs" data-trigger="accordion">
An example of the code that it is referencing to open the accordion:
<div id="protect-the-nhs" class="content 1">
I was wondering if anyone can help me change this code so that I can reuse it for each Accordion on the page. Let me explain. The page has 5 different accordions, above I have used generic naming for the data-trigger and the accordion class "content 1".
I'd like to know if it is possible to somehow make it so I can use this code for each different accordion (So for example accordion 1 would have a class of "content 1", accordion 2 would have a class of "content 2" etc. However, for each accordion, there would also be a different link you have to click to open the accordion.
For example: Accordion one would rely on an <a> tag with data-trigger="accordion1" and it would open the accordion with class="content 1".
I hope someone understands my ask and might be able to help! I've tried looking for something for this but haven't found anything. I'm still learning JS so TIA.
Thanks.
My basic idea is to listen to the entire document, determine where got clicked and activate the correct accordion
PLEASE NOTE: I'm assuming that every accordion has a number right after it that corresponds to the content classes like accordion1 content 1
document.onclick=function(e) {
if(!e.path[0].dataset.trigger){return;} //i forgot that not every element has a data-trigger
if(!e.path[0].dataset.trigger.startsWith('accordion')){return;} //listening to the whole document needs you have to ensure you aren't activating when you don't need to
var n=e.path[0]["data-trigger"].split('accordion')[1]
alert(n)
var obj = e.path[0],
accordionButtons = $('[href*="#"]', '[data-accordion] .accordion-navigation'),
accordionPanels = $(`.content.${n}`, '[data-accordion]');
if (obj.hasClass('toggle-open')) {
accordionButtons.removeClass('active');
accordionPanels.removeClass('active');
obj.removeClass('toggle-open');
} else {
accordionButtons.addClass('active');
accordionPanels.addClass('active');
obj.addClass('toggle-open');
}
$('[href*="#"]', '[data-accordion] .accordion-navigation').trigger('click.fndtn.accordion');
window.location.href = "#" + anchor;
e.preventDefault();
}

jQuery slideToggle for multiple divs

What I am trying to do is have four links that each will display and hide a certain div when clicked. I am using slideToggle and I was able to get it to work with really sloppy and repetitive code. A friend of mine gave me a script he used and I tried it out and finally was able to get something to happen. However, all it does is hide the div and wont redisplay. Also it hides all the divs instead of just the specific one. Here is a jsfiddle I made. Hopefully you guys can understand what I am trying to do and help! Thanks alot.
Here is the script I'm using.
$(document).ready(function () {
$(".click_me").on('click', function () {
var $faq = $(this).next(".hide_div");
$faq.slideToggle();
$(".hide_div").not($faq).slideUp();
});
});
http://jsfiddle.net/uo15brz1/
Here's a link to a fiddle. http://jsfiddle.net/uo15brz1/7/
I changed your markup a little, adding id attributes to your divs. The jquery, gets the name attribute from the link that's clicked, adds a # to the front, hides the visible div, then toggles the respective div. I also added e.preventDefault to stop the browser from navigating due to the hash change. As an aside, javascript don't require the $ prefix.
$(document).ready(function () {
$(".click_me").on('click', function (e) {
e.preventDefault();
var name = $(this).attr('name');
var target = $("#" + name);
if(target.is(':visible')){
return false; //ignore the click if div is visible
}
target.insertBefore('.hide_div:eq(0)'); //put this item above other .hide_div elments, makes the animation prettier imo
$('.hide_div').slideUp(); //hide all divs on link click
target.slideDown(); // show the clicked one
});
});
Welcome to Stack Overflow!
Here's a fiddle:
http://jsfiddle.net/uo15brz1/2/
Basically, you need a way to point to the relevant content <div> based on the link that's clicked. It would be tricky to do that in a robust way with your current markup, so I've edited it. The examples in the jquery documentation are pretty good. Spend some time studying them, they are a great way to start out.

jquery: if other slidetoggle is enabled (visible), close before initiating new slidetoggle

I've got the following script. I've got 3 div's that are all display: hidden; that I want to drop down from the top of the page using slideToggle.
<script type="text/javascript">
$(document).ready(function(){
$("#irN").click(function () {
$('#irN_dd').slideToggle();
});
$("#myir").click(function () {
$('#myir_dd').slideToggle();
});
$("#myirmsg").click(function () {
$('#myirmsg_dd').slideToggle();
});
});
</script>
HTML:
<a id="irN">irN</a>
<a id="myir">myir</a>
<a id="myirmsg">myirmsg</a>
This script works great. The only issue is that all 3 can be opened at the same time. I only want 1 to be able to be open at any given time. So...how would I modify the script to do the following..
... if none are open and the viewer clicks one of the id's, it opens....
... if one of the divs are open and the viewer clicks another one of the id's, it slides the one open up and then slides the new one down.
Thanks in advance!
Edit in regard to comments
If you didn't want to check the markup etc, you could use something like the following to acheive what you wanted:
$("#irN, #myir, #myirmsg").click(function () {
var example = "#" + this.id + "_dd";
$(example).siblings("div[id$=_dd]").slideUp()
.is(":visible")
? $(example).delay(1000).slideToggle()
: $(example).slideToggle();
});
This fits all your functions into one concise event (could probably look nicer but I'm too tired to think of anything better right now).
jsFiddle example

Need workaround for document.getElementById in order to cycle through multiple ID possibilities. Classes not working

I have 30 links in my HTML document, all of which, when clicked, trigger one specific div to change it's id using a js function.
Here are three of the 30 links followed by the single div with the id that changes.
Link 1
Link 2
Link 3
<div id="contain"></div>
Here is the div id change function (working, but not to my liking):
function changediv_1()
{
if (document.getElementById("contain")) {
document.getElementById("contain").setAttribute("id", "contain_1");
}
}
HERE IS THE PROBLEM: When I click Link 1 it changes the div id from "contain" to "contain_1", no problem there. Now the div name is "contain_1", so if I try to click Link 2 after clicking link 1 it won't work, because the div id is now "contain_1" and each function can only call for 1 id.
I need the above function to check for multiple divs (ie: #contain, #contain_1, #contain_2).
ideally like this:
function changediv_2()
{
if (document.getElementById("**contain, contain_1, contain_2, ...**")) {
document.getElementById("**contain, contain_1, contain_2, ...**").setAttribute("id", "contain_x");
}
}
I researched and tried applying .getElementByClass and it did not work - function seemed to only work with an id. There has to be a way around me posting the function 900 (no exaggeration) times to support each situation. Thank you so much for patience and reading my freaking novel of a post.
Try this use data and use on.click instead of inline javascript function
HTML
Link 1
Link 2
Link 3
<div id="contain" class="containDiv"></div>
jQuery
$(function () {
$('a').on('click', function () {
var contain = "contain_" + $(this).data('contain');
$('.containDiv').attr('id', contain);
//contain == contain_(1,2,3)
/*
Rest of your code to read from php and put into contain?
*/
});
});

anchor jumping by using javascript

I have a question that will be found very often. The problem is that nowhere can be found an explicit solution.
I have two problems regarding anchors.
The main goal should be to get a nice clean url without any hashes in it while using anchors to jump on a page.
So the structure of the anchors is:
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
</ul>
<div class="wrap">
<a name="one">text 1</a>
<a name="two">text 2</a>
<a name="three" class="box">text 3</a>
</div>
Okay, if you will click one of the links the url will automatically change to
www.domain.com/page#1
At the end this should be just:
www.domain.com/page
So far, so good. Now the second thing is, when you search the internet for that problem you will find javascript as a solution.
I have found this function:
function jumpto(anchor){
window.location.href = "#"+anchor;
}
and calling that function with:
<a onclick="jumpto('one');">One</a>
what will be the same like before. It will add the hash to the url. I also added
<a onclick="jumpto('one'); return false;">
without success. So if there is someone who could tell me how to solve this I really would appreciate.
Thanks a lot.
You can get the coordinate of the target element and set the scroll position to it. But this is so complicated.
Here is a lazier way to do that:
function jump(h){
var url = location.href; //Save down the URL without hash.
location.href = "#"+h; //Go to the target element.
history.replaceState(null,null,url); //Don't like hashes. Changing it back.
}
This uses replaceState to manipulate the url. If you also want support for IE, then you will have to do it the complicated way:
function jump(h){
var top = document.getElementById(h).offsetTop; //Getting Y of target element
window.scrollTo(0, top); //Go there directly or some transition
}​
Demo: http://jsfiddle.net/DerekL/rEpPA/
Another one w/ transition: http://jsfiddle.net/DerekL/x3edvp4t/
You can also use .scrollIntoView:
document.getElementById(h).scrollIntoView(); //Even IE6 supports this
(Well I lied. It's not complicated at all.)
I think it is much more simple solution:
window.location = (""+window.location).replace(/#[A-Za-z0-9_]*$/,'')+"#myAnchor"
This method does not reload the website, and sets the focus on the anchors which are needed for screen reader.
I don't have enough rep for a comment.
The getElementById() based method in the selected answer won't work if the anchor has name but not id set (which is not recommended, but does happen in the wild).
Something to bear in mind if you don't have control of the document markup (e.g. webextension).
The location based method in the selected answer can also be simplified with location.replace:
function jump(hash) { location.replace("#" + hash) }
Because when you do
window.location.href = "#"+anchor;
You load a new page, you can do:
One
<script>
function getPosition(element){
var e = document.getElementById(element);
var left = 0;
var top = 0;
do{
left += e.offsetLeft;
top += e.offsetTop;
}while(e = e.offsetParent);
return [left, top];
}
function jumpTo(id){
window.scrollTo(getPosition(id));
}
</script>
I have a button for a prompt that on click it opens the display dialogue and then I can write what I want to search and it goes to that location on the page. It uses javascript to answer the header.
On the .html file I have:
<button onclick="myFunction()">Load Prompt</button>
<span id="test100"><h4>Hello</h4></span>
On the .js file I have
function myFunction() {
var input = prompt("list or new or quit");
while(input !== "quit") {
if(input ==="test100") {
window.location.hash = 'test100';
return;
// else if(input.indexOf("test100") >= 0) {
// window.location.hash = 'test100';
// return;
// }
}
}
}
When I write test100 into the prompt, then it will go to where I have placed span id="test100" in the html file.
I use Google Chrome.
Note: This idea comes from linking on the same page using
Test link
which on click will send to the anchor. For it to work multiple times, from experience need to reload the page.
Credit to the people at stackoverflow (and possibly stackexchange, too) can't remember how I gathered all the bits and pieces. ☺
The first suggested solution of accepted solution did not work for me entirely. The main problem was when it was already jumped to hash, and hash already in url, jump did not happen again. I propose here, for the sake of completeness, somewhat more elaborate solution which works (tested in Chrome and FF). el is element with anchor tag.
el.addEventListener('click', function(ev) {
ev.preventDefault();
const href = ev.target.getAttribute('href');
const hashIndex = href.indexOf('#');
if (hashIndex !== -1) {
const hashPart = href.substring(hashIndex);
if (location.hash === hashPart) {
document.querySelector(hashPart).scrollIntoView();
}
else {
location.hash = hashPart;
}
}
})

Categories