How to target a click event using hash value from external link - javascript

I've built a image gallery page using the following plugin found from a codrop article:
http://tympanus.net/Tutorials/ThumbnailGridExpandingPreview/
I've got the gallery working as intended but I would like to add another feature but I'm struggling to figure out and I would really appreciate any help.
Here's a jsfiddle showing a basic version with the open function working:
http://jsfiddle.net/yfmm6q0o/
Using Hash values loaded from external links I would like the page to load and automatically open the preview, depending on the hash value (for example www.page.com#item-2 would open the second item preview).
I was able to set the hash value using:
window.location.hash;
And by using the string replace I was able to add 'loc-' to the hash value and scroll the page to that ID, this worked great but I would like preview section to open as well.
Is there a way to link the hash value to the following function:
function initItemsEvents( $items ) {
$items.on( 'click', 'span.og-close', function() {
hidePreview();
return false;
} ).children( 'a' ).on( 'click', function(e) {
var $item = $( this ).parent();
// check if item already opened
current === $item.index() ? hidePreview() : showPreview( $item );
return false;
} );
}
Meaning if the page loaded with #item-2 hash value it would fire a click event or simulate a click on the second item, opening the preview.
Thanks in advance for any help.

I would set it up along these lines:
Working Demo
jQuery:
$(function() {
// give all of your elements a class and bind a handler to them
$('.myBtns').click(function() {
alert('button ' +$('.myBtns').index($(this))+ ' was clicked using the hash from the url ')
});
// get the hash on load
var hash = window.location.hash.replace(/^.*?(#|$)/,'');
// click one of the elements based on the hash
if(hash!='')$('.myBtns').eq(hash).click();
// bind to hashchange if you want to catch changes while on the page, or leave it out
$(window).bind('hashchange', function(e) {
var hash = e.target.location.hash.replace(/^.*?(#|$)/,'');
$('.myBtns').eq(hash).click();
});
});
HTML
<h3>Navigate to: http://dodsoftware.com/sotests/hash/hashTest.html#0 to see the first button clicked based on the url hash.</h3>
<h3>Navigate to: http://dodsoftware.com/sotests/hash/hashTest.html#1 to see the first button clicked based on the url hash.</h3>
<h3>Navigate to: http://dodsoftware.com/sotests/hash/hashTest.html#2 to see the second button clicked based on the url hash.</h3>
<h3>Navigate to: http://dodsoftware.com/sotests/hash/hashTest.html#3 to see the second button clicked based on the url hash.</h3>
<input type="button" class="myBtns" value="I get clicked by the url's hash"/>
<input type="button" class="myBtns" value="I get clicked by the url's hash"/>
<input type="button" class="myBtns" value="I get clicked by the url's hash"/>
<input type="button" class="myBtns" value="I get clicked by the url's hash"/>

So, you may want to try the following. Please see details as comments in the code.
//Let's say the hash is "#item-2" and always has a >0 number (i.e. #item-1, #item-2 and #item-n) at the end.
var indexFromHash = parseInt("#item-2".split("-").pop(), 10) - 1;
//this would trigger click and invoke
//$items.on( 'click', 'span.og-close', function() { part of your code
$items.eq(indexFromHash).find('span.og-close').trigger("click");
//this would trigger click and invoke
//}).children('a').on('click', function(e) { part of your code
$items.eq(indexFromHash).children('a').trigger("click");

Related

Link that preselect dropdown option with jQuery

I have a select with options that have values that are populated with jQuery based on data attributes from divs. When a user select an option, the div with the data attribute that matches the value of the option is displayed. Now I'm trying to create a deep linking option, so when I have a url like https://my-site.com/page/#option-2 the option-2 is preselected in the select and the div with data attribute option-2 is displayed. So far I have this javascript:
$(window).on('load', function() {
let urlHash = window.location.hash.replace('#','');
console.log(urlHash);
if ( urlHash ) {
$('.dropdown').val(urlHash);
$('body').find('.location').removeClass('is-active');
$('body').find(`.location[data-location-hash=${urlHash}]`).addClass('is-active');
}
});
If I enter the url https://my-site.com/page/#option-2 the site goes in infinite loop and never loads without displaying any error in the console.. If I refresh the page while loading, the console.log is displayed with the correct string that I'm expecting, but the .location[data-location-hash=option-2] is not displayed and the option is not selected... I'm using the same code for the change function of the dropdown and is working, but it's not working in the load function.. Is there anything I'm missing?
JSFiddle, if it's of any help:
https://jsfiddle.net/tsvetkokrastev/b0epz1mL/4/
Your site is looping because you are doing a window.location.replace To get the urlHash you should use
$(window).on('load', function() {
var href = location.href; // get the url
var split = href.split("#"); // split the string
let urlHash = split[1]; // get the value after the hash
if ( urlHash ) {
$('.dropdown').val(urlHash);
$('body').find('.location').removeClass('is-active');
$('body').find('.location[data-location-hash='+urlHash+']').addClass('is-active');
}
});
https://codepen.io/darkinfore/pen/MWXWEvM?editors=1111#europe
Solved it by using a function instead of $(window).on('load').. Also added $( window ).on( 'hashchange', function( ) {}); to assure that the js will run again after the hash is changed.
Here is an updated jsfiddle: https://jsfiddle.net/tsvetkokrastev/b0epz1mL/5/

Inject GET parameter to target URL of a button, on click

I have multiple buttons with the class myButton. Each button has a value which is send to a server on click. The target URL of the button does look like this:
http://mysite/test/test.html?cid=15
After I click on the button, the following GET parameter should be added to the URL and then the button should be submitted:
mySessionVar=1
So the new URL should look like this:
http://mysite/test/test.html?cHash=d009eb3f9f4e1020435b96a8f7251ad5&mySessionVar=1
Why I have to inject it?
I am working with fluid. AFAIK it is not possible to manipulate fluid tags with JavaScript. However, I need to add a sessionStorage item value to the fluid tags arguments attribute.
My fluid code:
<f:link.action controller="Download" action="download" arguments="{cid: category.uid}" class="myButton">Download</f:link.action>
So my attempt is to append my sessionStorage item as GET parameter to the target URL of the button and then send it, e.g.:
$(".myButton").on
(
"click",
function(event)
{
//First prevent the default event
event.preventDefault();
...inject the sessionStorage item as GET parameter to the target URL of the button, then do whatever the button would do normally...
//Go to new URL
window.location.replace(NEW URL);
}
);
Is this possible?
EDIT: This is how the rendered HTML of the buttons looks like:
<a class="myButton" href="/de/mysite/test/test.html?tx_mydownloads_myfilelist%5Bcid%5D=15&&tx_mydownloads_myfilelist%5Baction%5D=download&tx_mydownloads_myfilelist%5Bcontroller%5D=Download&cHash=d009eb3f9f4e1020435b96a8f7150ad5">Download</a>
EDIT: I have another idea, maybe I could just read the target URL somehow, then add my new GET param to it and then load that URL with window.location.replace?
You can indeed just use the href from the button and use it to feed window.location.href, like so:
$('.myButton').on('click', function(e) {
e.preventDefault();
var href = $(this).attr('href'),
queryString = 'mySessionVar='+sessionStorage.getItem("myItem"),
newHref;
if (href.indexOf('?') !== -1) {
newHref = href + '&' + queryString;
} else {
newHref = href + '?' + queryString;
}
window.location.href = newHref;
});
This also handles the case when there is no previous query string present on the link and appends it with ? instead of &, but that part can be omitted if that won't happen in your app.
The following snippet should be enough to add your mySessionVar=1 parameter to the href attribute:
$('.myButton').on('click', function(e) {
$(this).attr('href', $(this).attr('href') + "&mySessionVar="+ sessionStorage.getItem('myVar');
});
You don't have to prevent the default, because your click handler function is called before the default event handler (who does roughly speaking: read the href attribute and load it).
You can use .serialize function in jquery which is simple and modern function to get all the selected buttons/filters into a url param format with amberson simple. I can't explain more clear than what is said in Jquery website. Please refer the link below to find how to use the function. https://api.jquery.com/serialize/#serialize

Change url using jquery

Сan you explain please.
Why returned, only the first data attribute - "link-1.html", even if I click on the second link
<a class="project-link" href="link-1.html" data-url="link-1.html">
<a class="project-link" href="link-2.html" data-url="link-2.html">
var toUrl = $('.project-link').attr('data-url');
$('a').click(function() {
window.location.hash = toUrl;
});
The meaning of such action - my links open through Ajax, but I want to URL displayed in the browser.
I want to make it as behance, if you click on the cards portfolio, they displayed through Ajax in the same window, but it also left open the possibility of direct appeal to the links. That's why I want to URL displayed in the browser address bar
You have to get current target url by this
$('a').click(function() {
var toUrl = $(this).data('url'); // use this as current target
window.location.hash = toUrl;
});
I recommend you to use .data() when you're retrieving data attributes (only) instead of .attr()
Demo
.attr( attributeName )
Returns: String
Description: Get the value
of an attribute for the first element in the set of matched elements.
$('.project-link') matches more than one element. Therefore, $('.project-link').attr('data-url') will return the value of the data-url attribute for the first element in the set.
To solve this you have maintain the context of the clicked element as you get the attribute, and you do this by using the this keyword.
And if you have other event listeners attached to the element already and you do not want them to fire -- although ajax calls will abort when the user is redirected -- you can use event.stopImmediatePropagation():
$('a').on('click', function( event ) {
event.stopImmediatePropagation();
window.location.hash = $(this).data('url'); //this here refers to the element that was clicked.
});
$('a[data-url]').click(function() {
window.location.href = $(this).data("url");
});
You might want to try this:
$('.project-link').click(function(){
window.location.hash = $(this).data('url');
});

How do I use a javascript injection to click on links of a specific class?

I have a page with many links that execute certain actions on click. Example:
<a class="x" onclick="somefunction(does_something)" href="javascript:void(0)">x</a>
I want to use a javascript injection to click all of them on the page. So far, I tried:
javascript:document.getElementsByClassName("x")[0].click();
But that doesn't seem to work. What am I doing wrong?
If your JS is inline, you can simply call what you need right in the href...
<a href="javascript:functionName('parameter1','parameter1','parameter1')">
Click to execute JS</a>
...but not wise if the parameters aren't predefined by you. Definitely don't do this if your parameters take user input and update/execute against your database, but it does work.
First of all, I'd suggest using jQuery, it's a lot easier to understand. Next, you can't really 'click' links dynamically and run it's function. You need to simply run a function on all the links and use it's address.
window.open( $('.x').attr( 'href' ), '_blank' );
Iterating through all links and opening them inside a container...
jQuery
$('#some_link_container').find('a').each(function() {
var link = $(this); // This is the current link in the iteration
window.open( link.attr( 'href' ), '_blank' ); // Prepare for mass computer lag
});
HTML
<div id="some_link_container">
A link
A link
A link
A link
</div>
If you are trying to run a function onclick, it's best to use a event listener rather then onclick. Something like the following
Event Listener Demo
Here we listen to a click on any link inside our container, then we run a function.
$('#some_link_container').find('a').each(function() { // Each link inside our div container
var link = $(this); // The current link
link.on('click', function(e) { // When the link is clicked
e.preventDefault(); // Stop the link from forwarding to that page
goodbye( link.attr('href') ); // Run our function onclick
});
});
var goodbye = function(link) {
alert( 'Goodbye guest! Forwarding you to: ' + link );
window.open( link, '_self' );
}

Stuck: hide/show divs with next button, redirect last div

Here's what I have so far, which allows the user to click an image to open a new window and go to a location. When that click occurs, the image in the parent window is replaced with the next div.
Example: http://jsfiddle.net/rzTHw/
Here's the working code so far...
<div class = "box"><img src="http://placehold.it/300x150/cf5/&text=img+1"></div>
<div class = "box"><img src="http://placehold.it/300x150/f0f/&text=img+1"></div>
<div class = "box"><img src="http://placehold.it/300x150/fb1/&text=img+1"></div>
<div class = "box"><img src="http://placehold.it/300x150/444/&text=img+1"></div>​
Jquery:
$('.box').not(':first').hide();
$('.box a').click(
function(e){
e.preventDefault();
var newWin = window.open(this.href,'newWindow'),
that = $(this).closest('.box'),
duration = 1200;
if (that.next('.box').length){
that.fadeOut(duration,
function(){
that.next('.box').fadeIn(duration);
});
}
});
What I am having trouble with is:
Creating a "next" button so the user can cycle through to the next div without having the click the image, thus avoiding having to open a new window to get to the next image.
Having a click on the last div redirect the window location to a URL, while still doing the normal function of opening a new window to the a href location if the image is clicked. Otherwise if clicking the "next" button when the last div is shown, simply redirect the user.
What's the best way to go about this? Thanks!
Here is my attempt at tweaking your code to allow for a next button, and my best guess at what you want to happen for the last image:
var redirectUrl = 'http://www.google.com'; // replace in your code
function next(event, duration) {
duration = duration || 1200; // default value
var that = $('.box:visible');
if (that.next('.box').length) {
that.fadeOut(duration, function() {
that.next('.box').fadeIn(duration);
});
} else {
window.location.href = redirectUrl;
// the above line doesn't work inside jsFiddle, but should on your page
}
return false;
}
$('.box').not(':first').hide();
$('.box a').click(
function(e) {
e.preventDefault();
var newWin = window.open(this.href, 'newWindow'),
duration = 1200;
next(e, duration);
});
$('.next').click(next);
jsFiddle example here. Note the redirect is prevented in some browsers since it is running inside an iframe. But it should work in a normal page.
Perhaps look at a slideshow jquery plugin. JQuery Cycle being just one example. There are plenty. Just google jquery Slideshow or jquery cycle and pick the one that suites you best. The cycle plugin itself has a number of "pager" examples that let you change the contents of the displayed picture without leaving the page.
Most of them offer having the contents be html and not just a simple picture so you can play around with what exactly you want.
There's also Fancybox, lightbox, colorbox, etc. if that's what you're trying to accomplish.

Categories

Resources