How to prevent users from clicking multiple times on a linked image? - javascript

I have a page with a linked image, where the link takes a bit of time to load. Therefore, users tend to click multiple times on it. This occasionally causes errors to crop up in the code. How do I prevent users from clicking on the link more than once?
In an attempt to remedy this, I changed the link to an onClick event and then in the function I used the code:
$('#myImageId').unbind('click');
window.location.href = "myLink";
However, that doesn't seem to be helping. Also, I'd prefer to keep it a simple linked image instead of using javascript.

Once solution is to add a class to the element that is used as a flag to determine of the code should run.
Here's an example: http://jsfiddle.net/qLhr8/
$('#myImageId').click(function() {
var $th = $(this);
if( !$th.hasClass( "pending" ) ) {
// Add the "pending" class, so subsequent clicks will not
// run the code inside this if()
$th.addClass( "pending" );
window.location.href = "myLink";
// you could do a setTimeout to remove the class
// if the new page never loads
}
});
With the added class, you can also change the look of the image (lower its opacity perhaps) to indicate that it shouldn't be clicked again.
.pending {
opacity: .4;
filter:alpha(opacity:40);
cursor: wait;
}

<img src="..." id="myImageId">
$('#myImageId').bind('click', function() {
$(this).unbind('click');
/* do long time task....
});
if your image is wrapped by a link the code will be
<img src="..." id="myImageId">
$('#myImageId').parent().bind('click', function(evt) {
$(this).unbind('click');
/* do long time task....
evt.preventDefault();
});

A hacky CSS solution that might/might not work: create another image element, without the link and make it a sibling to the link, like this:
<div>
<img src="my_img.png" id="img_link" alt="GO" />
<img src="my_img.png" id="img_nolink" alt="GO" />
</div>
Now apply this CSS:
#img_nolink { display: none; position: relative; top: -200px; /* Height of the image */ }
#link:active + #img_nolink { display: block; }
This should show the non-link image when the link is clicked (theoretically).

Related

How to navigate to a section in the page without using id?

I know you can navigate to a section in the page using anchor tags, but doing this adds unwanted keywords to the URL.
So if the original URL was www.xyz.com, clicking on an anchor tag abc would change the URL to www.xyz.com/#abc. I do not want the URL to change since this every time you click on "back", it just goes to the previous section that the URL held previously. Is there any way to stop this from happening? Maybe reroute the back button to leave the website or something?
Have you tried using JavaScript? Use scrollintoview function.
Here's an example:
<a onclick="scrollthere()">go to the content<\a>
<h1 id="stophere">This is content</h1>
<script>
function scrollthere(){
var element = document.querySelector("#stophere");
element.scrollIntoView();
}
</script>
Something like that. Onclick is an event. And in brackets we write function that we want to execute when clicked on it. In our case it's scrollthere which scrolls to our h1 element that has is "stophere". It will scroll untill our element won't get into view. You could read more about it here . Good luck with your website. I'm making website as well :).
My solution is to use JS instead of using <a> behavior.
for example
document.querySelectorAll("a").forEach((item, idx) => {
item.addEventListener("click", (e) => {
e.preventDefault();
const hash = e.target.hash;
window.scrollTo({
top: document.querySelector(hash).offsetTop,
behavior: "smooth"
});
});
});
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.section {
width: 100%;
height: 100vh;
}
.sec-1 {
background-color: salmon;
}
.sec-2 {
background-color: teal;
}
Section 1
Section 2
<div id="sec-1" class="section sec-1"></div>
<div id="sec-2" class="section sec-2"></div>
In my case, I use the scrollTo() property.
Hope this might help you.
You can set your href attribute to empty string.
abc

Controlling toggling buttons with CSS and jQuery

As you can see in this jsfiddle, I'm trying to make a toggle switch (a mute button) that
displays the current setting, i.e. mute or unmute
when hovered upon, displays the alternative
However, my problem is when the user clicks the button, instead of displaying the opposite button, it shows that opposite buttons hover state. I hope this is making sense, haha. Basically the interaction is:
view button in unmute state
hover over and see the mute icon
click and see the unmute icon again, because it is the mute states hover image
when the icon is not hovered upon, it displays the proper icon, i.e. mute
In the jsfiddle example, I want a click to display the button, not the :hover attribute... any help? I'm aware that this kinda thing can't be handled by css alone.. (sorry if this seems confusing, ive been working in codespeak for a while today...)
Consider this alternative solution:
uses single button
manipulates .text() and .css() to change button attribute
custom toggler implemented because of special cases you require
Here is the code:
CSS:
button { width: 200px; height: 60px; color: white; font-size: 20px; background-color: red; }
HTML:
<button class=''> Mute </button>
JS:
function unmute() {
$('button').removeClass('muted');
$('button').text('Unmute');
$('button').css('background-color','blue');
}
function mute() {
$('button').addClass('muted');
$('button').text('Mute');
$('button').css('background-color','red');
}
function customToggler() {
if (disableToggle) return;
if ($('button').hasClass('muted')) unmute(); else mute();
}
var disableToggle = false;
$(document).ready(function() {
customToggler();
$('button').click(function() {
disableToggle = true;
customToggler();
});
$('button').mouseover(function() {
customToggler();
}).mouseout(function() {
customToggler();
disableToggle = false;
});
});
--
To see the above code in action, see http://jsfiddle.net/fwjz5/ Good luck!
​
You can handle hover states in javascript and remove CSS ones.
Well, I think this is the shortest solution right now:
http://jsfiddle.net/4mK9q/

HTML Divs show/hide issue

Hi friends I have issue with divs.
I have a link show/hide dive on my page on clicking which i have to show or hide specific divs.
I am successful with doing it.
But my issue is that whenever I click on that link div is get hide or shown but page get directly on the top & I have to scroll to down again.
I don't want to scroll this and don't want to get to top.
Please help me out with this.
Thank You in advance.
Update:
Friend I got the answer from one of my friend.
Actually I was using
Because of href="#" URL get changed and page got to top every time I click on that link.
Are you trying to do this?
<!DOCTYPE html>
<html lang="en">
<head>
<title></title>
<meta charset="utf-8">
</head>
<body>
<div id="wrapper">
<div id="container">
</div><!-- end of #container div -->
<a id="showdiv">Show the div</a>|<a id="hideDiv">Hide the div</a>|<a id="toggle">Toggle</a>
</div><!-- end of #wrapper div -->
</body>
</html>
Here's the css:
#container {
width: 300px;
height: 300px;
background: red;
margin-bottom: 20px;
}
#wrapper {
margin: 40px auto;
width: 400px;
}
And here's the jquery
$(function() {// When document is ready, run this...
//Get hold of the link with the id #showdiv and do something when you click it
$("#showdiv").click(function() {
// Grab the div with the id #container and show it
// Alert me when you're done
$("#container").show(2000, function() {
alert("I'm done showing");
});
});
//Get hold of the link with the id #hideDiv and do something when you click it
$("#hideDiv").click(function() {
// Grab the div with the id #container and hide it
// Alert me when you're done
$("#container").hide(2000, function() {
alert("I'm done hiding");
});
});
// Toggle - This is like a On/Off Switch
//Get hold of the link with the id #toggle and do something when you click it
$("#toggle").click(function() {
// Grab the div with the id #container and show if hidden / hide if shown
$("#container").toggle(2000);
});
});
Of course you'd have to link to a copy of jQuery before using the script above.
Here's a link to a demo: http://jsfiddle.net/tonystark/HhNBA/
Assuming you have a link
Inline (not recommended but likely what you have)
<script>
function showhide(id) {
var elem = document.getElementById(id);
elem.style.display=elem.style.display=="none"?"block":"none";
return false; // MANDATORY
}
</script>
Toggle
<div id="someId">Show or hide me when you click a link</div>
You have to cancel the default behavior of the onclick handler of your link. For doing so, don't use return false in your click handler, but rather use event.preventDefault():
HTML:
hide me
<div id="#targetdiv">blah</div>
Javascript:
document.querySelector('a.foo').onclick = function(event) {
try {
document.querySelector(this.getAttribute('href')).style.display = 'none';
} catch (e) {
console.error("couldn't find element to hide");
}
event.preventDefault();
}
JQuery:
$('a.foo').click(function(event) {
try {
$($(this).attr('href')).hide();
} catch (e) {
console.error("couldn't find element to hide");
}
event.preventDefault();
})
More informations:
http://www.quirksmode.org/js/events_early.html
http://fuelyourcoding.com/jquery-events-stop-misusing-return-false/
It happens because your link is pointing to something like #foo or just #, whereas it should not have a href (or have an empty one)...
remove the href attribute and apply a text-decoration style
<a style="text-decoration: underline;" title="click me"></a>
that'd seem to make more sense than applying an href you dont want, to block its normal operation later. an alternative for graceful degradation would be to use the href to point to the shown/hidden div, displaying normally by default and having javascript hide it where javascript is available.
"Change your anchor (link) to a span so that it doesn't have that behaviour. Then, style it using css so it looks how you want it to look."
i often use that techique. i.e., use a span or div with an onclick, styled with text-decoration: underline, cursor: pointer and possibly display: inline if you decide on a div. one caveat is that in IE6, css hover won't work on anything other than an anchor. that's easily fixed with javascript.
you could probably remove the href attribute completely. anchors have advantages as above (cross-browser :hover styles) and allow for a title attribute for tool tips etc.
you probaby have a # in href attribute like href=# please remove hash and instead of that write href='javascript:void(null);'

setInterval works only the first time

I am trying to use setTimer to animate a slide show using straightforward jQuery. I provide the user with a button (in the form of a "DIV" with a button background image) that he clicks to start the show and which then turns into a pause button. The slides are supposed to change every 3 seconds. Here is the relevant code:
playLink = $('<div id="lbPlayLink" />').click(function(){
$(playLink).hide();
$(pauseLink).show();
slideInterval = setInterval(function(){next()}, 3000)
})[0];
pauseLink = $('<div id="lbPauseLink" />').click(function(){
$(playLink).show();
$(pauseLink).hide();
clearInterval(slideInterval);
}).hide()[0];
The next() function call does the work of replacing the slide with the next one. I have checked out this function and it works perfectly if I call it directly (synchronously), however, when it gets called asynchronously by the setInterval, it works fine the first time (3 seconds after I click on the button), but is never called again, even though it should be called 3 seconds later. I know it's never called as I put an "alert" call at the beginning and end of the function.
If I replace the next() call in the setInterval with alert('test') then I can see the setInterval is doing what it is supposed to. I can't for the life of me see why alert() is OK but next() isn't, unless it has something to do with "scope" of functions, but in that case why does it work the first time?
I've tried debugging the code with firebug, but it can't really help with timeout functions like this. Neither Firefox nor IE8 show any error messages.
I've looked through the various posts here and elsewhere on setInterval, but can't see anything relevant that I haven't tried already. I've been experimenting now for about 3 hours and it's doing my head in. Can anyone suggest what I can try next?
Hmm, I don't like the way you wrote the code, it is not very readable, I would rather suggest something like the following (not tested yet, not sure if it works):
The CSS:
#slides{
/* So you can position your elements under the div#slides */
position: relative;
}
.button {
width: 50px;
height: 10px;
/* So you can position your button anywhere you like */
position: absolute;
bottom: 10px;
right: 10px;
}
.play {
background:url(..) no-repeat;
}
.pause {
background:url(..) no-repeat;
}
The HTML consist of the parent slides holding everything relating to slides, and the controller, basically holds your button image.
<div id="slides">
<div id="controller" class="button play"></div>
</div>
The code:
(function() {
//Let's wrap everything in an anonymous function, so to avoid variable confusion
function next() {
//Assume this is your code doing the sliding. I don't touch
}
var invt;
function play() {
//Always clear interval first before play
if (invt) clearInterval(invt);
invt = setInterval(function() {
next();
}, 3000);
}
function pause() {
if (invt) clearInterval(invt);
}
$(document).ready(function() {
$('#controller').click(function() {
//It's not playing so it has the play class
if ($(this).hasClass('play')) {
$(this).removeClass('play').addClass('pause');
pause();
}else{
$(this).removeClass('pause').addClass('play');
play();
}
});
});
})();
change this line on both:
$('<div id="lbPlayLink" />').click(function(){
to:
$('<div id="lbPlayLink" />').live("click", function(){
To clarify how I solved the problem:
I took onboard Ivo's suggestion to have a single button (though in the form of a "DIV" element rather than a "BUTTON") and change the class of this button between "lbPlay" and "lbPause" to change the background image and trigger the correct action.
My main problem was that I was unknowingly setting the event on this button multiple times and I believe this is what was causing the strange behaviour.
I got round it by putting the return code from the "setInterval" call into a variable ("ppHandler") attached to the DIV, using the jQuery "data" method.
The new code is:
if (typeof($(playPauseLink).data('ppHandler')) == 'undefined'){
$(playPauseLink).click(function(){
var $this = $(this);
if ($this.hasClass('lbPlay')) {
if ($this.data('ppHandler') != -1) clearInterval($this.data('ppHandler'));
$this.data('ppHandler', setInterval(function(){next();}, slideInterval*1000));
$this.removeClass('lbPlay').addClass('lbPause');
} else {
if ($this.data('ppHandler') != -1) clearInterval($this.data('ppHandler'));
$this.data({ppHandler: -1});
$this.removeClass('lbPause').addClass('lbPlay');
}
});
Thanks to all who responded. To see the final result go to "www.trips.elusien.co.uk" and click on the "slimbox examples" link and go to "example 9".

How to disable user's input while loading page with jQuery?

I have a heavy-jquerized page with some links, various user inputs and such.
I use jquery, with actions defined in a
$(document).ready( function() {
....
} );
block.
But while the page is loading (or, even worse - reloading), and a user clicks a link, the href action from it is triggered, as the javascript isn't loaded / active yet.
I wanted to block it somehow. One way that came to my mind is to put a transparent div over whole document, that would receive the click events instead of the layer below it. Then, in my .ready function in javascript, I could hide that div making it possible to use the page.
Is it a good practice? Or should I try some different approach?
Another option is to use the jQuery BlockUI plugin (which probably usew the same or similar idea behind the scenes).
If you don't want your links to act like links (ie their href is never meant to followed), why make them links in the first place? You'd be better served by making your clickable elements a div or span (something without a default action), and attaching the click handler as per normal.
I'd really advise against blocking the ui with a div - it seems the entirely wrong approach, making the page non-functional to someone with JS disabled, as well as blocking other common tasks like copying text.
In light of the clarification, to block the UI only if JS is enabled, but not yet loaded, I'd suggest the following.
HTML (first thing after body):
<script type="text/javascript">document.write('<div id="UIBlocker">Please wait while we load...</div>')</script>
CSS:
#UIBlocker
{
position: fixed; /* or absolute, for IE6 */
top: 0;
bottom: 0;
left: 0;
right: 0;
}
Or, if you prefer not to use document.write, leave the UIBlocker div as straight HTML at the top of body, but have the following in head
HTML:
<noscript>
<style type="text/css">
#UIBlocker { display: none !important; }
</style>
</noscript>
This will ensure it does not block for non-JS enabled browsers
A transparent div could work, assuming it’s positioned above everything. (I’m never quite clear how visible an element has to be to receive click events.)
You might want to make the div visible though; it could be equally confusing for visitors if they can see everything on the page, but not click it.
You’ll probably need to use JavaScript to make the div as tall as the page though.
The overlay DIV should work. Another option would be to place all the content inside a hidden container visibility: hidden then toggle to visible as the last $(document).ready statement.
As you said it yourself javascript isn't loaded yet. Maybe the css isn't loaded either.
so something with visual element will not work i think. IF you want to do some with the viaual elements (css) you have to hardcode it in the html node <tagname style="blabla">
You could possibly add the href behavious in a later stadium when the js is loaded.
What you get is a <span> with a title and this should set the behaviour or something. I used a title, but can be a different attribute.
This doesn't use any jquery, only for loading
$(document).reade(function () {
relNoFollow();
});
function relNoFollow() {
var FakeLinks = document.getElementsByTagName('span');
if( FakeLinks.length > 0 ) {
for( var i = 0; i < FakeLinks.length; i++ ) {
if( FakeLinks[i].title.indexOf( 'http://' ) != -1 ) {
FakeLinks[i].onmouseout = fakelinkMouseOut;
FakeLinks[i].onmouseover = fakelinkMouseOver;
FakeLinks[i].onclick = fakelinkClick;
}
}
}
}
function fakelinkMouseOver() {
this.className = 'fakelink-hover';
}
function fakelinkMouseOut() {
this.className = 'fakelink';
}
function fakelinkClick() {
window.location.href = this.title;
}

Categories

Resources