Disable a link for couple of seconds - javascript

I'm making a book-website with a jQuery-plugin. Every time a link is clicked, the book-page switches to the next page and the .active class switches from link. The problem is that if you click fast between the pages, the active class switches but the movement of the book is too slow so you don't hop to the next page.
I'm trying disable the link after u clicked on one. My idea was just removing an attribute for a couple of seconds like this:
$('.button').click(function(e){
.. switch page using id
.. switch .active
$(".button li a").removeAttr("id");
}
So when the page is loaded, and the active class is switched. U cannot click on another link until the attribute is put back on.
How can remove an attribute for a couple of seconds? Or are there other options to disable a link for a period of time without removing the attribute?

An easy (but a bit hacky) way to accomplish this is returning early out of the handler if the action is already in progress:
var pageIsTurning = false;
$('.button').click(function(e){
if (pageIsTurning) { return; }
// do your stuff and change the page
}):
According to the docs of the booklet plugin you can bind to the bookletstart and bookletchange events which are where you'd update the pageIsTurning variable.
$(".selector").bind("bookletstart", function(event, data) {
pageIsTurning = true;
});
$(".selector").bind("bookletchange", function(event, data) {
pageIsTurning = false;
});
Note that this approach wouldn't work if you have more than one booklet on the page but could easily be adapted.

Related

Unable to open link with jQuery click()

I want to open some relevant links after a button click by user. All these links have to open in a new tab.
I tried using the following code but it does not open the links:
$("div.relevant-links").on('click', function() {
var count = 0;
var relevant_links = $(this);
function open_link() {
if (count < relevant_links.siblings("a.sections").length) {
relevant_links.siblings("a.sections").eq(count).css({
background: 'yellowgreen'
});
relevant_links.siblings("a.sections").eq(count).click();
count++;
} else {
clearInterval(link_interval);
}
}
open_link();
var link_interval = setInterval(open_link, 5000);
});
All other code works fine because I can see the background color of the link change. However, the click() method does not seem to work.
How can I trigger the click on different links? All the links have to open in a new tab. I have set their target attributes to _blank.
First of all, remove the interval, if you're going recursive, use setTimeout, if there's even a minor flaw in your code you've got yourself an annoying memory leak.
Second, when you want to open a webpage, new tab or not. You'll need to do it right after a user initiated action like a click. If you're gonna trigger it again after 5 seconds it will get blocked in modern browsers.
Third, you could also retrieve the href of the links and perform a window.open('your href here', '_blank') instead of triggering the click event.
Last, don't open a bunch of "relevant" links. You're not making anyone happy with that. Especially not a new one every 5 seconds!

Single Page Site and Back Button Confusion

I have been searching for hours about how to do this, trying different things and not succeeding.
All I want to do is make a one-page site that shows/hides divs and does one simple animation. I have already made it do everything I want and look the way I want it to look: When you click a link in my navbar, there is a script that runs that hides one div, shows another, and also changes the size of the header image. This is all done with simple JS and CSS, but the back button doesn't work and the URL does not change even when I make the link a hash anchor. Maybe having all the divs on the index and showing/hiding them isn't even the best way to do this.
The implementation of the HTML5 History API (If I should even be using that) has got me stumpped, and I can't seem to find a simple straightforward working example of this.
Can anyone point me to a fiddle or codepen of something like this working properly?
This is the basics of what I'm doing:
Link:
Work
Function:
function work() {
document.getElementById("work").style.cssText = 'display: block; opacity: 1;'
document.getElementById("about").style.cssText = 'display: none; opacity: 0;'
document.getElementById("hero").style.cssText = 'height: 85px; transition: 200ms ease-in-out;'
document.getElementById("introcontainer").style.cssText = 'visibility: hidden; opacity: 0; transition: visibility 200ms, opacity 200ms linear;';
}
When my "Work" link is clicked, "about" is hidden, "introcontainer" is hidden, height of "hero" is changed, and "work" is displayed. I have two other "pages" and they function the same way.
History API is made just for such scenarios , instead of scanning url hashes and running complex if else you can use pushState to keep track of application state and decide what happens at each state.
The gist of this API is when you push something using pushState it gets returned to you on popState (on hitting back button).
history.pushState(objState,title,Url);
The first argument is where we pass stuff that will help identify application state you can put anything but it has to be enclosed in an object
I will ignore the 2nd one(pass any string). 3rd one is what URL bar would show relative to current path on executing PushState()
Assuming you have nav something like this
<ul id="nav">
<li>About</li>
<li>Contact</li>
<li>Team</li>
</ul>
assign click handlers for pushing state
$('a').click(function(e){
e.preventDefault();
var targetUrl = $(this).attr('href');
history.pushState({url:targetUrl}, targetUrl, targetUrl);
applyState(targetUrl); //will show div associated with this anchor
});
Now when user clicks a link you need to push something related to this say its href or title to identify it later (I've used its href but you are free to use anything) after it gets pushed you may animate and show div associated with this link eg. If I click <a href="work"> then push “work” and show the div that holds your work details(while minimizing/hiding other divs) .Your url reads xyz/work atm
Next if I click <a href="contact"> state for contact gets pushed and same way it's associated div gets highlighted.Your url reads xyz/contact atm
Now when I hit back history will pop and url will change from xyz/contact to xyz/work popping the latest inactive state (wiz. work and not contact!)
If you have assigned handler for onpopstate you can catch the popped content
window.onpopstate = function(e) {
var popie = e.state ? e.state.url : null;
applyState(popie);
}
so popie would be “work” , applyState will do its fancy animation and show work div
applyState might look like
function applyState(url) {
$('#status').text('Current active page ' + url);
switch(url){
case "work": //show work details div hide others
break;
case "about": //show aboutdetails div hide others
break;
}

Activate style with if statements for anchor position

I am a beginner and have searched thoroughly, finding not a solution for this problem.
I've written a code where a css style changes when you click on a link, such as the one below:
function spHome(){
document.getElementById("btnHome2").style.background = "url(../images/btn_navHoverArrow.png) no-repeat center bottom";
document.getElementById("btnAccount").style.background = "0";
}
function spAccount(){
document.getElementById("btnHome2").style.background = "0";
document.getElementById("btnAccount").style.background = "url(../images/btn_navHoverArrow.png) no-repeat center bottom";
}
This code works perfectly fine. The problem for me is that when I refresh the page, the click state is no longer active. Is there a code that can allow the function to stay active only when the user is at a certain anchor point of the page. For example, if we have an anchor location called index.html#home, the home button will be active and when index.html#account is clicked, the account button will stay on clicked even after page refresh.
The example below doesn't seem to be working on jsfiddle but it is fine on all browsers:
http://jsfiddle.net/JoshuaWaheed/HZLVt/3/
Is there a way to make this happen?
Add href hashes and return false onclick to avoid page reloading
You need to execute js at page load, check the url's hash, and put the button's state accordingly to the hash.
Using jQuery, it would be something like (not tested):
$(function() {
if (document.location.hash == "#home")
spHome()
else
if (document.location.hash == "#account")
spAccount()
})
If you don't want to use jQuery, you can put that code on docuent event "load"

Perform a jQuery event before opening up a link

I have a simple javascript/jQuery related question:
I have the following markup in my tumblr blog:
NEXT
The # above changes according to which page the user is on. ie: # is variable, and cannot be static.
With jQuery, I would like to perform an effect (slideUp();, to be specific) before the new link is opened.
Is that possible?
I have tried both .click() and .mousedown(). Doesn't seem to work, since when I click the link, the new page opens up before any effects take place.
I have heard of preventDefault(), but I'd like to shy away from that, for that would mean I must create a separate function to detect the page #, etc. (too much work~)
I recommend against doing that. Just let the user change pages.
However, if you really want to, what you need to do is indeed preventDefault (explicitly, or by returning false from your handler), do the slideUp, and then in the slideUp completion function, trigger the change in URL.
Like this:
$("a.pagination").click(function() {
// Grab the link's href
var href = this.href;
// Slide up the content you want to slide up
$("some_selector_here").slideUp(function() {
// Slide is finished, navigate
location.href = href;
});
// Prevent the default action of the link
return false;
});
You just need to defer changing of page's url:
$('.pagination').click(function(){
var link = this;
$('.some-other-element').slideUp(500, function(){
location.href = this.getAttribute('href');
});
return false;
});

Javascript : Change the function of the browser's back button

Is there a way to make the user's back button on their browser, call a javascript function instead of going back a page?
You can't override the behaviour that if a user follows a link to your page, clicking Back will take them off it again.
But you can make JavaScript actions on your page add entries into the history as though they were clicks to new pages, and control what happens with Back and Forward in the context of those clicks.
There are JavaScript libraries to help with this, with Really Simple History being a popular example.
yes, you can. Use this js:
(function(window, location) {
history.replaceState(null, document.title, location.pathname+"#!/stealingyourhistory");
history.pushState(null, document.title, location.pathname);
window.addEventListener("popstate", function() {
if(location.hash === "#!/stealingyourhistory") {
history.replaceState(null, document.title, location.pathname);
setTimeout(function(){
location.replace("http://www.programadoresweb.net/");
},0);
}
}, false);
}(window, location));
That will redirect your back button to the location.replace you specify
I think this will do the trick.
you can write your custom code to execute on browser back button click inside onpopstate function.
This works in HTML5.
window.onpopstate = function() {
alert("clicked back button");
}; history.pushState({}, '');
I assume you wish to create a one-page application that doesn't reload the website as the user navigates, and hence you want to negate the back button's native functionality and replace it with your own. This can also be useful in mobile web-apps where using the back button inside apps is common to close an in-app window for example. To achieve this without a library, you need to:
1st. Throughout your application modify the window's location.hash instead of the location.href (which is what tags will do by default). For example, your buttons could fire on click events that modify the location.hash like this:
button.addEventListener('click', function (event) {
// Prevent default behavior on <a> tags
event.preventDefault()
// Update how the application looks like
someFunction()
// Update the page's address without causing a reload
window.location.hash = '#page2'
})
Do this with every button or tag you have that would otherwise redirect to a different page and cause a reload.
2nd. Load this code so that you can run a function every time the page history changes (both back and forward). Instead of the switch that I used in this example, you can use an if and check for other states, even states and variables not related to location.hash. You can also replace any conditional altogether and just run a function every time the history changes.
window.onpopstate = function() {
switch(location.hash) {
case '#home':
backFromHome()
break
case '#login':
backFromLogin()
break
default:
defaultBackAnimation()
}
}
This will work until the user reaches the first page they opened from your website, then it will go back to new tab, or whatever website they were in before. This can't be prevented and the teams that develop browsers are patching hacks that allow this, if a user wants to exit your website by going back, they expect the browser to do that.
If you are creating a one-page web application, where your html body has different sections and you want to nevigate through back button to the previous section you were. This answer will help you.
Where your website sections are differentiated by #. Such as:
your-web-address.com/#section-name
Just follow a few steps:
Add a class and a id in every section in you html body. Here it is ".section"
<section class="section" id="section-name">...</section>
Add two CSS class in your linked css (e.g., style.css) file to your html (e.g., index.html) file such:
.section .hide {
display: none;
}
.section .active{
dislplay: block;
}
Add this JavaScript function in you linked .js (e.g., main.js) file to your html file.
window.onpopstate = function () {
if (location.hash !== "") {
const hash = location.hash;
// Deactivating existing active 'section'
document.querySelector(".section.active").classList.add("hide");
document.querySelector(".section.active").classList.remove("active");
// Activating new 'section'
document.querySelector(hash).classList.add("active");
document.querySelector(hash).classList.remove("hide");
}
}

Categories