targeting only same page anchor links - javascript

From a web analyst perspective on any given website i am looking find out which same page anchors are clicked the most by console logging the anchor's text value (inner html text) in the console for now.
The approach i took was to take the current page url after every anchor click and check to see if their had been any hash changes at the end of the url string and if so print that anchor's text value in the console.
var anchor = $("a[href^=\\#]");
anchor.on("click", function(){
if("onhashchange" in window) {
var anchorText = this.text;
console.log(anchorText);
}
});
I'm having issues with the code I wrote because its returning the inner Html text for any anchors on the page(except the ones with external links) but I only want to track the ones that lead to a section on the same page.
Would the approach i took need to be revised to even begin with ?
Here is some of the html I am working with and different anchors I want to track and ones I don't.
<!-- Where the click on the anchor i want to target happens -->
<nav>
<h2 class="wb-inv">Promotions</h2>
<ul class="toc lst-spcd col-md-12">
<li class="col-md-4">
Anchor for section 1
</li>
</nav>
<!-- below is the section of the same page the anchors would point to -->
<div class="col-md-12 pull-left">
<h2 id="story1">Section 1 Title </h2>
<p>Random paragraph 1</p>
</div>
<!-- The html I'm working with contains a set of tabs that reveal information as you click them, the href attribute and the id are both in the anchor. This is an example of anchors I wouldn't want to track-->
<a tabindex="-1" id="details-panel1-lnk" role="tab" aria-selected="false" aria-controls="details-panel1" href="#details-panel1">
<h2 class="h5 mrgn-tp-sm mrgn-bttm-sm">Online</h2>
</a>

Anchors that navigates to element on page is logged.
$(document).ready(function() {
var anchor = $("a[href^=\\#]");
var url = $(window);
anchor.on("click", function(e){
if ( $('#' + $(this).text()).length ) {
console.log($(this).text());
}
});
})
.section {
height: 400px;
}
.section:nth-child(even) {
background: grey;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="section" id="one">
one
</div>
<div class="section" id="two">
two
</div>
<div class="section" id="three">
three
</div>
<div class="section" id="four">
four
</div>

var anchor = $("a[href^=\\#]").not("a[href=#shr-pg0]");
anchor.on("click", function(){
var anchorText = this.text;
$(window).one("hashchange",function() {
console.log(anchorText);
});
});

Related

On click event backfiring after adding nested anchor tag to section element

I wanted to create a modal of sorts to open when a <li> offering additional information about a topic is clicked. I created a popUpTrigger that responds to a user "click" and then gathers the provided section (and all tags nested inside) and moves it to the popUp div that then appears on the page. I've taken necessary precaution in case the section is empty in which an alert will sound. However, the alert still fires when a section is not empty (it has text and contains an additional anchor tag). I'm not sure why this is happening.
When I console log, I see the nested anchor tag is being viewed by the browser as a separate entity to the section. I've tried nesting the anchor tag further within a div element and rewriting the javascript so the html of the nested anchor tag will be evaluated accordingly as part of the section but all to no avail. This backfiring only occurs when an additional anchor tag is included in the section element of the HTML.
HTML
<li id="card">
<a class="popUpTrigger" href="#">
Get a Library Card
<section class="hide">
<h6> How to Obtain a Library Card:</h6>
<p> Additional Info </p>
<p> Additional Info </p>
<p> Additional Info </p>
<p> Additional Info </p>
<a href="https://docs.wixstatic.com/ugd/858998_1fae2b5d06fa41a3ba3fcb493b349d19.pdf">
<img src="imgs/LibraryCardVector.png" alt="library card">
</a>
</section>
</a>
</li>
<div class="popUp">
<div>
<div id="popUpClose"> <button type="button" class="btn">X</button></div>
</div>
<div id="moreInfo">
<!--WILL BE FILLED IN WITH <section class="hide"> DATA ABOVE-->
</div>
</div>
JavaScript
$('a.popUpTrigger').on('click', function() {
$(this).addClass('selected');
if ($('.selected')) {
let messageArea = $('.selected > section.hide');
let strippedMessage = messageArea.text().replace(/(\r\n|\n|\r)/gm, "").replace(/\s/g, "");
let fullMessage = messageArea.html();
if (strippedMessage === "") {
alert("Sorry that page isn't available right now.");
$(this).removeClass('selected');
} else {
$('.popUp').css('display', 'block');
$('.popUp #moreInfo').html(fullMessage);
}
}
$('.popUp #popUpClose').on('click', function() {
$('.popUpTrigger').removeClass('selected');
$('.popUp').css('display', 'none');
});
});
I removed the children from your anchor, and instead used NEXT. Also your if statement was not needed. I left .selected in the code just in case you wanted to style the anchor when clicked.
$('a.popUpTrigger').on('click', function() {
$('a.popUpTrigger').removeClass("selected");
$(this).addClass('selected');
let messageArea = $(this).next("section");
let strippedMessage = messageArea.text().replace(/(\r\n|\n|\r)/gm, "").replace(/\s/g, "");
let fullMessage = messageArea.html();
if (strippedMessage === "") {
alert("Sorry that page isn't available right now.");
$(this).removeClass('selected');
} else {
$('.popUp').css('display', 'block');
$('.popUp #moreInfo').html(fullMessage);
}
$('.popUp #popUpClose').on('click', function() {
$('.popUpTrigger').removeClass('selected');
$('.popUp').css('display', 'none');
});
});
.selected{color:red;}
.hide{display:none;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<li id="card">
<a class="popUpTrigger" href="#">
Get a Library Card </a>
<section class="hide">
<h6> How to Obtain a Library Card:</h6>
<p> Additional Info </p>
<p> Additional Info </p>
<p> Additional Info </p>
<p> Additional Info </p>
<a href="https://docs.wixstatic.com/ugd/858998_1fae2b5d06fa41a3ba3fcb493b349d19.pdf">
<img src="imgs/LibraryCardVector.png" alt="library card">
</a>
</section>
</li>
<div class="popUp">
<div>
<div id="popUpClose"> <button type="button" class="btn">X</button></div>
</div>
<div id="moreInfo">
<!--WILL BE FILLED IN WITH <section class="hide"> DATA ABOVE-->
</div>
</div>
You have the following code
<a href="#">
</a>
It is not valid to have nested anchors in HTML. So the browser breaks it up when it renders. That is why you are seeing it act weird.
You will need to stick the pop up code outside of the element.
<a class="popUpTrigger" href="#">
Get a Library Card
</a>
<section class="hide">
<p>Foo</p>
Bar
</section>
and reference it with next()
$(".popUpTrigger").on("click", function (e) {
e.preventDefault();
var anchor = $(this);
anchor.next('section').toggleClass("hide");
});

Update div content when link is clicked

I'm trying to create a list of links that update the content in a div when clicked.
Looking at the code below, I want the div with id container to be populated with the content of the relevant div when a link is clicked.
<a class="glyphicon glyphicon-cutlery" onclick="fixScroll('food');"></a>
<a class="glyphicon glyphicon-cutlery" onclick="fixScroll('water');"></a>
<div id="food" style="height:20px;">Clicking Food Link Shows this in Div</div>
<div id="water" style="height:20px;">Clicking Water Link Shows this in Div</div>
<div id="container" style="width:100%; height:150px;">This Div box is Empty till you click one the links, then its Populated by the correct stuff</div>
I hope this is enough information. I'm basically trying to make the content of hidden divs (food & water) display in the container div when clicking a link.
This script should work.
function fixScroll(id) {
var text = document.getElementById(id).innerHTML;
document.getElementById("container").innerHTML = text;
}
<a class="glyphicon glyphicon-cutlery" onclick="fixScroll('food');">Food</a>
<a class="glyphicon glyphicon-cutlery" onclick="fixScroll('water');">Water</a>
<div id="food" style="display: none; height:20px;">Clicking Food Link Shows this in Div</div>
<div id="water" style="display: none; height:20px;">Clicking Water Link Shows this in Div</div>
<div id="container" style="width:100%; height:150px;">This Div box is Empty till you click one the links, then its Populated by the correct stuff</div>
Keeping it simple, you can add this below your other HTML (as the last element inside your body element):
<script>
const container = document.querySelector("#container");
function food(){
const foodText = document.querySelector("#food").innerHTML;
container.innerHTML = foodText;
}
function water(){
const waterText = document.querySelector("#water").innerHTML;
container.innerHTML = waterText;
}
</script>
You can improve on this by
1) putting the script in an external file and referencing it from your page, and/or
2) combining the two functions into one by giving it a parameter name (like myText) inside the parentheses, and using that parameter in place of foodText inside the function. Then when you call the function, instead of just saying food(), you would say myCombinedFunctionName(foodText).
Edited to use pure JS without jQuery:
var btn = document.querySelectorAll('.classNameYouLike');
for (var i in btn) {
btn[i].onclick = function(e) {
e.preventDefault();
document.querySelector('#container').innerHTML = document.querySelector(e.target.getAttribute('data-source')).innerHTML;
};
}
<a class="glyphicon glyphicon-cutlery classNameYouLike" data-source="#food">food</a>
<a class="glyphicon glyphicon-cutlery classNameYouLike" data-source="#water">water</a>
<div id="food" style="display:none;">Clicking Food Link Shows this in Div</div>
<div id="water" style="display:none;">Clicking Water Link Shows this in Div</div>
<div id="container" style="width:100%; height:150px;">This Div box is Empty till you click one the links, then its Populated by the correct stuff</div>
Original jQuery-powered solution:
$('.classNameYouLike').on('click', function(e) {
e.preventDefault();
$('#container').html($($(this).data('source')).html());
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a class="glyphicon glyphicon-cutlery classNameYouLike" data-source="#food">food</a>
<a class="glyphicon glyphicon-cutlery classNameYouLike" data-source="#water">water</a>
<div id="food" style="display:none;">Clicking Food Link Shows this in Div</div>
<div id="water" style="display:none;">Clicking Water Link Shows this in Div</div>
<div id="container" style="width:100%; height:150px;">This Div box is Empty till you click one the links, then its Populated by the correct stuff</div>

How to prevent named anchor jump/scroll in main page using easytabs jQuery plugin?

Here's a js fiddle to demonstrate the problem.
I have a fixed position floating/popup dialog on my page that contains a series of tabs using the easytabs jQuery plugin. When the dialog appears, any tab selection causes the webpage (behind the floating dialog) to jump/scroll to a different position on the page.
I've read in other places that forcing the click behavior of the anchor tags in the tab structure to prevent the default behavior will correct this issue, but it doesn't seem to be working for me e.g. assigning a class such as .prevent-default to each tab anchor element and doing:
$('.prevent-default').click(function(e) {
e.preventDefault();
return false;
});
Here's some html:
<h1>Top</h1><button onclick="showTabDialog();">Tabs</button>
<p id="spacer"></p>
<h1>Bottom</h1>
<div id="dialog" class="floating-dialog">
<div id="tabs" class="tab-container">
<ul class="tabs">
<li class="tab">
First
</li>
<li class="tab">
Second
</li>
</ul>
<div id="content-container">
<div id="first" class="tab-content">
<div class="tab-no-data">No data yet</div>
</div>
<div id="second" class="tab-content">
<div class="tab-no-data">No data yet</div>
</div>
</div>
</div>
</div>
...and some js:
$(document).ready(function() {
$('#tabs').easytabs({animationSpeed: 'fast'});
$('.prevent-default').click(function(e) {
e.preventDefault();
return false;
});
});
function showTabDialog() {
$('#dialog').fadeIn();
}
$('#tabs').easytabs({animationSpeed: 'fast', updateHash: false});
Demo: http://jsfiddle.net/naa22prw/3/
Another way to do this is to set a minimum height on the tabs container div. `
#tab-container{
min-height: 700px;
}
This means that you can use the updateHash: true so the URL can change each time a tab is clicked.
ref. https://github.com/JangoSteve/jQuery-EasyTabs/issues/40

mouseenter/leave & mouseover/out problems

Script:
$( ".title").mouseenter(function() {
var which = $(this).index();
$('.globalnav li').find('.dropdown').hide().eq(which).show();
}).mouseleave(function() {
var which = $(this).index();
$('.globalnav li').find('.dropdown').hide().eq(which).hide();
});
Navigation:
<ul class="globalnav">
<li>
<div class="title">Home</div>
<div class="dropdown">
<div class="navlinks">
<div class="linkstitle">Title</div>
<div class="navlink">Link1</div>
<div class="navlink">Link1</div>
</div>
</div>
</li>
...
The above code is what I am using right now which does not work in Chrome as intended *I need to hold my click down to view the div. I use mouseover, it does not work properly in IE and FF.
I am also having trouble showing the associated div of the title (on title hover, show specific div) due to the nature of the coding format itself (client given code). Right now, on hovering over a title, it shows the first li's content for "navlinks".
Here's a fiddle to show you
Thanks
Why are you using the index of the .title element, if the other LI's look like that, the which variable will always be 0, and it's not the way to target the right .dropdown ?
Try something more like this
$( ".title").on('mouseenter mouseleave', function(e) {
var dropdown = $(this).closest('li').find('.dropdown').toggle(e.type=='mouseenter');
$('.dropdown').not(dropdown).hide();
});
And if you want the dropdown to be visible while hovering it, place it inside the element that triggers the mouseleave
<li>
<div class="title">
Home
<div class="dropdown">
<div class="navlinks">
<div class="linkstitle">Title</div>
<div class="navlink">Link1</div>
<div class="navlink">Link1</div>
</div>
</div>
</div>
</li>
FIDDLE

JS Reveal/Hide toggle

Just a quick one, hopefully. I've coded up this:
<script>
$("div.design-project").css('display', 'none');
function InsertContent(tid) {
if(document.getElementById(tid).style.display == "none") {
document.getElementById(tid).style.display = "block";
}
else {
document.getElementById(tid).style.display = "none";
}
}
</script>
Which, if a link has the href:
href="javascript:InsertContent('design-project-1');"
it displays that div below. And if you click it again it disappears. Then if you click another link that say has the href:
href="javascript:InsertContent('design-project-2');"
it'll display that div and so forth.
However, if you have one div open, and click on another anchor link to open another div, it doesn't close the one already open.
Any ideas? Also, if there's a better way to do this then please let me know.
Thanks,
R
Here is the HTML as requested:
<a class="design-projects-slides-title" href="javascript:insertDesignProjectContent('design-project-1');">Title of project</a>
<!-- start of .design-project --><div class="design-project" id="design-project-1">
<div class="grid_6"><div class="project-info-area">
<h2>Title of project</h2>
<p>A rural retreat in the city. Built almost entirely from reclaimed element this little new-build timber cabin provides guest accommodation.<p>
<p>By coincidence a former chapel partition was found that matched the dimensions required. Used in their original painted condition, these doors became the front elevation and concertina open to one side - perfect for warm summer days. Further reclaimed elements include a bespoke curtain made from found patchwork, Victorian conservatory grills fitted over modern french heaters and industrial lights, taps, wash basin and an exposed shower fitting. Salvaged hardwood strip flooring and our Heathrow Terminal 2 stone fold from the floor to the walls. A thorough use of salvage all round!</p>
</div></div>
<div class="grid_6 project-info-images"><img src="http://placehold.it/460x540"></div>
<div class="grid_6 project-info-images"><img src="http://placehold.it/460x540"></div>
<div class="grid_6 project-info-images"><img src="http://placehold.it/460x540"></div>
<div class="grid_12 project-info-images"><img src="http://placehold.it/940x540"></div>
<div class="grid_6 project-info-images"><img src="http://placehold.it/460x540"></div>
<div class="grid_6 project-info-images"><img src="http://placehold.it/460x540"></div>
</div><!-- end of .design-project -->
UPDATE
In the end, I used a combination of your answers - thanks!
<!-- Reveal/hide sections on design projects/joinery -->
<script>
/* This is for the 'choose a project' reveal/hide */
$("div.slider-content").css('display', 'block');
$(".design-projects-slides-title").click(function() {
$(".slider-content").hide();
});
/* This is for reveal/hide on the product content */
$(".design-project").hide()
$('.design-projects-slides-title').click(function(){
var id = $(this).attr('id')
var content_id = id+"-content"
$('#'+content_id).slideDown('slow')
});
$(".slider-trigger").click(function() {
$(".design-project").hide();
});
</script>
First of all i see that you use jQuery so why not use it to achieve the entire flow?
You could do something like:
$(".mydivclass").click(function(){
$(".mydivclass").hide();
$(this).show();
})
Use jQuery toggle to achieve what you are trying to do. e.g.
function InsertContent(tid) {
$('#'+tid).toggle()
}
Another improvement you should do is that instead of hardcoding the id in each href, just add a class to element, override onclick of element and toggle related content. To get related content you can use a nomenclature e.g. if you use id='myid' for anchor, use id="myid_content" for content, so in click function you can toggle content e.g.
HTML:
<a class="content-link" id="myid">click me</a>
<div id="myid_content">
Here is the content
</div>
JavaScript:
$('.content-link').click(function(){
var id = $(this).attr('id')
var content_id = id+"_content"
$('#'+content_id).toggle()
}
Here is a working sample on jsFiddle
Better still is to keep clickable link and content inside a div, so that you don't need to set id, just set some classes and with parent and child relations you can get what is content e.g.
HTML
<div class="content-wrap">
<a class="content-link" >Click Me</a><br/>
<div class="content">
Here is the content for click me
</div>
</div>
JavaScript:
$('.content-link').click(function(){
var id = $(this).parent().find(".content).toggle()
})​
See it in action here
HTML
<a id="id1" href="#" rel="divContent1" >First</a><br/>
<a id="id2" href="#" rel="divContent2">Second</a><br/>
<div id="divContent1" class="content">
Content of Div 1
</div>
<div id="divContent2" class="content">
Content of Div2
</div>​
Javascript
$(function(){
$(".content").hide();
$("a").click(function(e){
e.preventDefault()
var divToShowId=$(this).attr("rel");
$(".content").hide();
$("#"+divToShowId).show();
});
})​
I used the id of Content divs as the rel attribute value of links as we need some way to connect a link with its content.
Here is the working demo : http://jsfiddle.net/Kx9Ma/5/

Categories

Resources