I'm working on a script that adds a button that floats on top of a Facebook user's profile photo thumbnail.
Here's a screenshot:
This button, when clicked, returns the Facebook ID of the profile that is being viewed in a prompt. That part works fine (but you'd need to be logged in and looking at a profile besides yours, otherwise there'd be a missing element).
Screenshot:
What's bothering me though, is after clicking the button, and pressing Cancel or Okay in the prompt, the click actually goes through the button and clicks the profile picture thumbnail itself. A single click is clicking both items!
Is there any way we can make it so that the area below the button itself is not clickable? But the rest of the profile picture is?
I've tried searching on this topic but couldn't find much results. Even if I try to search for something like "Add padding below/under button JavaScript", I'm getting padding around the button, and not directly below it
in a z-axis point of view.
Here's the script code, you can copy paste it in the console directly. That is, if you have a Facebook account and are logged in. Also this only works on profiles besides yours (otherwise data-profileid would be missing).
// Create the button
var btn = document.createElement("BUTTON");
var t = document.createTextNode("FBID"); // To replace with icon
btn.appendChild(t);
// Add a listener
btn.addEventListener("click", getFBID);
// Styling (positioning)
btn.style.display="block";
btn.style.position="absolute";
btn.style.top="4px";
btn.style.right="4px";
// Function to get Facebook ID
function getFBID() {
prompt("Copy it:", document.querySelectorAll("[data-profileid]")[0].getAttribute("data-profileid"));
}
// Append button to profile picture
document.getElementsByClassName("profilePicThumb")[0].appendChild(btn);
Oh yeah, I feel the reason why this is happening is because I am appending to an anchor link. Just in case this info would be useful.
Any help appreciated, thank you!
Try to prevent the default actions for the click like this:
btn.addEventListener("click", function(event){
event.preventDefault();
event.stopPropagation();
getFBID();
return false;
});
EDIT: use event.stopPropagation();
(compare to this thread How to stop event bubbling on checkbox click)
Try this
// Create the button
var btn = document.createElement("BUTTON");
var t = document.createTextNode("FBID"); // To replace with icon
btn.appendChild(t);
// Add a listener
btn.addEventListener("click", getFBID);
// Styling (positioning)
btn.style.display="block";
btn.style.position="absolute";
btn.style.top="4px";
btn.style.right="4px";
// Function to get Facebook ID
function getFBID() {
prompt("Copy it:", document.querySelectorAll("[data-profileid]")[0].getAttribute("data-profileid"));
return false; // Try returning false here..
}
// Append button to profile picture
document.getElementsByClassName("profilePicThumb")[0].appendChild(btn);
getFBID in this case is a callback for the event that is raised on the click of the button. returning false will make sure that the event is not propagated to its parent and hence will not raise the parent's event or call the eventhandler.
Related
Issue: generated button isn't registered on click ~1/20 times.
I'm generating a button :
var thebutton = document.createElement("BUTTON");
thebutton.setAttribute("id", "mybutton");
thebutton.setAttribute("class", "mybuttonclass");
thebutton.setAttribute("onclick","function()");
thebutton.innerHTML = '<i class="icon info"></i>';
document.getElementById("row").appendChild(thebutton);
Which is appended on top an existing button element as a second z-index layer:
.mybuttonclass {
z-index:9999;
}
I am also using
focusMethod = function getFocus() {
document.getElementById("mybutton").focus();
}
focusMethod();
In order to shift the browser selection from the trigger of the generating code (also a button) to #mybutton which works as it is highlighted.
Still for some reason, arbitrarily, every few times the button is created, any clicks will not registered to the created button, and in order to fix it and be able to trigger it, i need to right click the page -- after which the button starts to work.
Is there any way to have the browser rescan the page for elements after I generate the button? Or is there some other issue causing this that I'm missing?
Seems to happen in chrome more often, bootstrap is also run on CSS for the page.
I have a list of clickable buttons and use a flag variable to prevent a double click on the focused button. The flag works and I get the intended alert saying 'you have already clicked that'. The problem is that the following button will be treated as if it has also already been clicked and I'll get the alert again. I don't want this.
var _clickFlag = true;
/* #Volunteers is a table. Each row on the table has a button that says "accept",
I pass the function the 'event' object which I use to get specific data from that table
row and send it to a database*/
$('#Volunteers').on('click','#accept', function(event){
//if clickFlag = true then the button hasn't been clicked yet.
if(_clickFlag){
//here I send some stuff to a database. I don't want to send it twice for the same
//row, which is why I need to prevent a double click
//set clickFlag to false to prevent double submission
_clickFlag = false;
}else{
//alert if the button has been clicked once already
alert("already accepted");
}
});
Just use this:
$( "#Volunteers").unbind( "click" );
This will just make the button unclickable.
double click is a separate event, I assume you are talking about clicking the button more than once, if that is the case your variable that you defined is in the outer context is shared to all button, what you need is to define a variable inside the function and tie it to the button itself, try the below:
http://jsfiddle.net/4JFtw/
$('#Volunteers').on('click','.accept', function(event){
//if clickFlag = true then the button hasn't been clicked yet.
if(typeof this._clickFlag != 'undefined' && this._clickFlag){
//alert if the button has been clicked once already
alert("already accepted");
}else{
//here I send some stuff to a database. I don't want to send it twice for the same
//row, which is why I need to prevent a double click
alert('_clickFlag: '+this._clickFlag + ' First time processing!');
this._clickFlag = true;
}
});
In these situations I like to use attributes, ex:
$('some-button-here).attr('data-active','false') // This sets the attribute for that button
You can then check this attribute everytime one of the buttons is clicked.
I am trying to restrict the user from clicking on a button multiple times. They can click on the button once when the page loads. If the page is reloaded the same should apply the user can click on the button only once.
I am using the following code however it doesn't seem to work for me
$("#doAccess").click(function() {
$("#doAccess").removeAttr('onclick');
DoSave();
});
Disable the button after it's been clicked
var accessBtn = $('#doAccess');
accessBtn.click(function() {
accessBtn[0].disabled = true;
DoSave();
});
Sounds like what you really need is:
$("#doAccess").one('click', DoSave);
jsFiddle example
.one() - Attach a handler to an event for the elements. The handler is executed at most once per element per event type.
Why not this?
$("#doAccess").once('click', function() {
DoSave();
});
You should probably also gray out or disable #doAccess, whatever it is.
I used this code to change the class of an html-element when an onclick-event occurs. The change occurs(i.e. the text color changes) but the change is not stable, it goes back to the styling of its previous class, and my javascript code doesn't seem to have any effect.
function submitrequest(){
var x = document.forms["signupform"]["name"].value;
if(x.toString().length <= 0){
var y = document.getElementById("nametd");
y.className = 'change';
}
}
What should I do to make this effect permanent?
You do not have to define a click-handler to notice that a button of a form was clicked.
A form can have an submit-button:
and when this button is clicked an submit event is fired for the form.
Furthermore when an user do not clicks on the button and just presses enter then a submit-event is fired too. So you handle both situations automatically.
I suggest that you define you function that way:
window.onload = function(){
document.getElementById('signupform').addEventListener('submit',function(e){
changeClassOfNametd();
e.preventDefault(); // this prevents the side from being reloaded by the script.
});
};
function changeClassOfNametd(){
var nameValue = document.forms["signupform"]["name"].value;
if(nameValue){ // when value is "" (zero, no signs) it is false anyway
var y = document.getElementById("nametd");
y.className = 'change';
//y.classList.toggle('change'); you can toggle classname "change" too
// which works that way class="unchange" -> class="unchange change"
// you have to define appropriate css-classes for toggle.
}
}
The Code above works whereever you put it into your html-file.
By the name of the function it is called on a form submission.
Because the form submits and it goes back to the original that was set when the new page loads.
If you want to maintain that, you would have to apply the class on the next page load. Most developers will do that with the serverside. If you do not actually want the form to submit, cancel it.
I've got a child close button inside its parent, a notification box. When the parent is clicked, the notification box expands, with the notification's description and the child button becoming visible inside it.
The button, when clicked, should unexpand the notification and hide both itself and the description.
Because the button has a click event inside its parent click event, both were being called. I turned to event.stopPropagation() to have the parent notification stop re-expanding after I clicked. While this stopped the notification from expanding on a close button click, it presented a new problem that I don't understand.
In my test, I have two notifications set up, both unexpanded. When I click on a notification, it expands and shows the description and close button. When I click the close button, the notification unexpands and the button and description are hidden. But, I found that the description and close button were appearing for the other notification!
Code:
var $NotificationContainer = $("#NotificationContainer");
$NotificationContainer.append('<div class="Notification" title="'+title+'"></div>');
var $thisNotification = $NotificationContainer.children('.Notification[title='+title+']');
$thisNotification.append('<div class="NotificationTitle">'+title+'</div>');
$thisNotification.append('<div class="NotificationDescription">'+description+'</div>');
$(".NotificationDescription").hide();
// Button used to close an expanded notification
$thisNotification.append("<div class='NotificationCloseButton'></div>");
$('.NotificationCloseButton').hide();
// When the parent notification box is clicked
$thisNotification.click(function(event)
{
$thisNotification.animate({height:250}, 1000);
$thisNotification.find('.NotificationDescription').slideToggle('fast');
$thisNotification.find('.NotificationCloseButton').slideToggle('fast');
});
// When the child close button is clicked
$(".NotificationCloseButton").click(function(event)
{
event.stopPropagation();
$thisNotification.animate({height:50}, 1000);
$thisNotification.find('.NotificationDescription').slideToggle('fast');
$thisNotification.find('.NotificationCloseButton').slideToggle('fast');
});
I don't know how $thisNotification.find('element') is not catching the right notification.
Does it work if you change the event handling to
// When the parent notification box is clicked
$thisNotification.click(function(event)
{
var self = $(this);
self.animate({height:250}, 1000);
self.find('.NotificationDescription').slideToggle('fast');
self.find('.NotificationCloseButton').slideToggle('fast');
});
// When the child close button is clicked
$(".NotificationCloseButton").click(function(event)
{
var self = $(this);
event.stopPropagation();
self.animate({height:50}, 1000);
self.find('.NotificationDescription').slideToggle('fast');
self.find('.NotificationCloseButton').slideToggle('fast');
});
used this to identify the clicked element, instead of relying on the variable that was defined when you created the element (avoids cases in loops where the all elements reference the last value assigned to the variable..)
Additionally, since you are appending to the #NotificationContainer you can just select the last item instead of searching for identical titles..
var $thisNotification = $NotificationContainer.children().last();
removed the selector completely since you have just appended the last element..