Jquery On("Click") hook on links interefering with each other - javascript

Hi I have two Jquery function. One function is set for hash scrolls and the other to show a modal on click. The functions are hooked to Links . I have set empty links with a href="#". However my two hooks are interfering with each other. If I check for empty hashlinks in my first function and return a false then my second function in gallery to display Image modal is deactivated. Is there any way around this. I am sure that the obvious answer is adding some variable to my function. But I want to make a function that will check if the href="#" is true and not scroll but won't interfere with any other function that may be hooked by Jquery on to that link. Also why do the two hooks interfere with each other?
<div>Some text<div>
<div id="gallery>
<div class="item">
<a class="thumbnail thumbnail-sm" href="#" rel="tooltip">
<img src="...jpg" class="img-rounded">
</a>
</div>
<div>
//smooth scroll hashes function.
('a[href*=#]').on('click', function () {
var href = $.attr(this, 'href');
href = href.replace(/^\//, '');
if (href == '#') {
return false;// but if I return false here modal does not work.
}
else { //smooth scroll code here }
return false;// if I return false here my modal function works.
});
//Display gallery item in modal function.
$('#gallery').on('click', '.item a', function () {
$('#myModal').modal('show');
return false;
});
Edit: I am puzzled by this behaviour
if (href == '#') {
return false;// but if I return false here modal does not work.
}
else { //smooth scroll code here }
return false;// if I return false here my modal function works.

When you return false from the event handler, it prevents the default action of the <a> element, but it also stops the propagation of the event -- that means other attached event handlers will not get executed. If you want the event handler for the smooth-scroll jump links to allow for other event handlers on those links to execute, you should just prevent the default action, but still allow the event to propagate. You can do that by calling event.preventDefault(), instead of returning false.
Start your event handlers like this:
$('a[href*=#]').on('click', function (event) {
event.preventDefault();
...
And:
$('#gallery').on('click', '.item a', function (event) {
event.preventDefault();
...
And don't return false from them.

It may be happening because the second case uses event delegation, so as the first event is cancelled, it doesn't bubble for the delegation. Try this:
$('#gallery .item a').on('click', function () {
alert("hhh");
$('#myModal').modal('show');
return false;
});
Hope this helps. Cheers

Have you tried something like this?
('a[href*=#]').on('click', function () {
var href = $.attr(this, 'href');
href = href.replace(/^\//, '');
if (href != '#') {
//smooth scroll code here
}
return false;
});

Related

html div onclick event

I have one html div on my jsp page, on that i have put one anchor tag, please find code below for that,
<div class="expandable-panel-heading">
<h2>
<a id="ancherComplaint" href="#addComplaint"
onclick="markActiveLink(this);">ABC</a>
</h2>
</div>
js code
$('.expandable-panel-heading:not(#ancherComplaint)').click(function () {
alert('123');
});
function markActiveLink(el) {
alert($(el).attr("id"));
}
here I when I click on div I got alert with 123 message, its fine but when I click on ABC I want message I want to call markActiveLink method.
JSFiddle
what is wrong with my code? please help me out.
The problem was that clicking the anchor still triggered a click in your <div>. That's called "event bubbling".
In fact, there are multiple solutions:
Checking in the DIV click event handler whether the actual target element was the anchor
→ jsFiddle
$('.expandable-panel-heading').click(function (evt) {
if (evt.target.tagName != "A") {
alert('123');
}
// Also possible if conditions:
// - evt.target.id != "ancherComplaint"
// - !$(evt.target).is("#ancherComplaint")
});
$("#ancherComplaint").click(function () {
alert($(this).attr("id"));
});
Stopping the event propagation from the anchor click listener
→ jsFiddle
$("#ancherComplaint").click(function (evt) {
evt.stopPropagation();
alert($(this).attr("id"));
});
As you may have noticed, I have removed the following selector part from my examples:
:not(#ancherComplaint)
This was unnecessary because there is no element with the class .expandable-panel-heading which also have #ancherComplaint as its ID.
I assume that you wanted to suppress the event for the anchor. That cannot work in that manner because both selectors (yours and mine) select the exact same DIV. The selector has no influence on the listener when it is called; it only sets the list of elements to which the listeners should be registered. Since this list is the same in both versions, there exists no difference.
Try this
$('.expandable-panel-heading:not(#ancherComplaint)').click(function () {
alert('123');
});
$('#ancherComplaint').click(function (event) {
alert($(this).attr("id"));
event.stopPropagation()
})
DEMO
Try following :
$('.expandable-panel-heading').click(function (e) {
if(e.target.nodeName == 'A'){
markActiveLink(e.target)
return;
}else{
alert('123');
}
});
function markActiveLink(el) {
alert($(el).attr("id"));
}
Here is the working demo : http://jsfiddle.net/JVrNc/4/
Change your jQuery code with this. It will alert the id of the a.
$('.expandable-panel-heading:not(#ancherComplaint)').click(function () {
markActiveLink();
alert('123');
});
function markActiveLink(el) {
var el = $('a').attr("id")
alert(el);
}
Demo
You need to read up on event bubbling and for sure remove inline event handling if you have jQuery anyway
Test the click on the div and examine the target
Live Demo
$(".expandable-panel-heading").on("click",function (e) {
if (e.target.id =="ancherComplaint") { // or test the tag
e.preventDefault(); // or e.stopPropagation()
markActiveLink(e.target);
}
else alert('123');
});
function markActiveLink(el) {
alert(el.id);
}
I would have used stopPropagation like this:
$('.expandable-panel-heading:not(#ancherComplaint)').click(function () {
alert('123');
});
$('#ancherComplaint').on('click',function(e){
e.stopPropagation();
alert('hiiiiiiiiii');
});
Try out this example, the onclick is still called from your HTML, and event bubbling is stopped.
<div class="expandable-panel-heading">
<h2>
<a id="ancherComplaint" href="#addComplaint" onclick="markActiveLink(this);event.stopPropagation();">ABC</a>
</h2>
</div>
http://jsfiddle.net/NXML7/1/
put your jquery function inside ready function for call click event:
$(document).ready(function() {
$("#ancherComplaint").click(function () {
alert($(this).attr("id"));
});
});
when click on div alert key
$(document).delegate(".searchbtn", "click", function() {
var key=$.trim($('#txtkey').val());
alert(key);
});

X-Editable: stop propagation on "click to edit"

I have an editable element inside a div which itself is clickable. Whenever I click the x-editable anchor element, the click bubbles up the DOM and triggers a click on the parent div. How can I prevent that? I know it's possible to stop this with jQuery's stopPropagation() but where would I call this method?
Here's the JSFiddle with the problem: http://jsfiddle.net/4RZvV/ . To replicate click on the editable values and you'll see that the containing div will catch a click event. This also happens when I click anywhere on the x-editable popup and I'd like to prevent that as well.
EDIT after lightswitch05 answer
I have multiple dynamic DIVs which should be selectable so I couldn't use a global variable. I added an attribute to the .editable-click anchors which get's changed instead.
editable-active is used to know if the popup is open or not
editable-activateable is used instead to know if that .editable-click anchor should be treated like it is
$(document).on('shown', "a.editable-click[editable-activateable]", function(e, reason) {
return $(this).attr("editable-active", true);
});
$(document).on('hidden', "a.editable-click[editable-activateable]", function(e, reason) {
return $(this).removeAttr("editable-active");
});
The check is pretty much like you've described it
$(document).on("click", ".version", function() {
$this = $(this)
// Check that the xeditable popup is not open
if($this.find("a[editable-active]").length === 0) { // means that editable popup is not open so we can do the stuff
// ... do stuff ...
}
})
For the click on the links, simply catch the click event and stop it:
$("a.editable-click").click(function(e){
e.stopPropagation();
});
The clicks within X-editable are a bit trickier. One way is to save a flag on weather the X-editable window is open or not, and only take action if X-editable is closed
var editableActive = false;
$("a.editable-click").on('shown', function(e, reason) {
editableActive = true;
});
$("a.editable-click").on('hidden', function(e, reason) {
editableActive = false;
});
$("div.version").click(function(e) {
var $this;
$this = $(this);
if(editableActive === false){
if ($this.hasClass("selected")) {
$(this).removeClass("selected");
} else {
$(this).addClass("selected");
}
}
});
Fixed Fiddle
It's not pretty, but we solved this problem with something like:
$('.some-class').click(function(event) {
if(event.target.tagName === "A" || event.target.tagName === "INPUT" || event.target.tagName === "BUTTON"){
return;
}
We're still looking for a solution that doesn't require a specific list of tagNames that are okay to click on.

Hiding Bootstrap Popover on Click Outside Popover

I'm trying to hide the Bootstrap Popover when the user clicks anywhere outside the popover. (I'm really not sure why the creators of Bootstrap decided not to provide this functionality.)
I found the following code on the web but I really don't understand it.
// Hide popover on click anywhere on the document except itself
$(document).click(function(e) {
// Check for click on the popup itself
$('.popover').click(function() {
return false; // Do nothing
});
// Clicking on document other than popup then hide the popup
$('.pop').popover('hide');
});
The main thing I find confusing is the line $('.popover').click(function() { return false; });. Doesn't this line add an event handler for the click event? How does that prevent the call to popover('hide') that follows from hiding the popover?
And has anyone seen a better technique?
Note: I know variations of this question has been asked here before, but the answers to those questions involve code more complex than the code above. So my question is really about the code above
I made http://jsfiddle.net/BcczZ/2/, which hopefully answers your question
Example HTML
<div class="well>
<a class="btn" data-toggle="popover" data-content="content.">Popover</a>
<a class="btn btn-danger bad">Bad button</a>
</div>
JS
var $popover = $('[data-toggle=popover]').popover();
//first event handler for bad button
$('.bad').click(function () {
alert("clicked");
});
$(document).on("click", function (e) {
var $target = $(e.target),
var isPopover = $target.is('[data-toggle=popover]'),
inPopover = $target.closest('.popover').length > 0
//Does nothing, only prints on console and wastes memory. BAD CODE, REMOVE IT
$('.bad').click(function () {
console.log('clicked');
return false;
});
//hide only if clicked on button or inside popover
if (!isPopover && !inPopover) $popover.popover('hide');
});
As I mentioned in my comment, event handlers don't get overwritten, they just stack. Since there is already an event handler on the .bad button, it will be fired, along with any other event handler
Open your console in the jsfiddle, press 5 times somewhere on the page (not the popover button) and then click bad button you should see clicked printed the same amount of times you pressed
Hope it helps
P.S:
If you think about it, you already saw this happening, especially in jQuery.
Think of all the $(document).ready(...) that exist in a page using multiple jquery plugins. That line just registers an event handler on the document's ready event
I just did a more event based solution.
var $toggle = $('.your-popover-button');
$toggle.popover();
var hidePopover = function() {
$toggle.popover('hide');
};
$toggle.on('shown', function () {
var $popover = $toggle.next();
$popover.on('mousedown', function(e) {
e.stopPropagation();
});
$toggle.on('mousedown', function(e) {
e.stopPropagation();
});
$(document).on('mousedown',hidePopover);
});
$toggle.on('hidden', function () {
$(document).off('mousedown', hidePopover);
});
short answer
insert this to bootstrap min.js
when popout onblur will hide popover
when popout more than one, older popover will be hide
$count=0;$(document).click(function(evt){if($count==0){$count++;}else{$('[data-toggle="popover"]').popover('hide');$count=0;}});$('[data-toggle="popover"]').popover();$('[data-toggle="popover"]').on('click', function(e){$('[data-toggle="popover"]').not(this).popover('hide');$count=0;});
None of the above solutions worked 100% for me because I had to click twice on another, or the same, popover to open it again. I have written the solution from scratch to be simple and effective.
$('[data-toggle="popover"]').popover({
html:true,
trigger: "manual",
animation: false
});
$(document).on('click','body',function(e){
$('[data-toggle="popover"]').each(function () {
$(this).popover('hide');
});
if (e.target.hasAttribute('data-toggle') && e.target.getAttribute('data-toggle') === 'popover') {
e.preventDefault();
$(e.target).popover('show');
}
else if (e.target.parentElement.hasAttribute('data-toggle') && e.target.parentElement.getAttribute('data-toggle') === 'popover') {
e.preventDefault();
$(e.target.parentElement).popover('show');
}
});
My solution, works 100%, for Bootstrap v3
$('html').on('click', function(e) {
if(typeof $(e.target).data('original-title') !== 'undefined'){
$('[data-original-title]').not(e.target).popover('hide');
}
if($(e.target).parents().is('[data-original-title]')){
$('[data-original-title]').not($(e.target).closest('[data-original-title]')).popover('hide');
}
if (typeof $(e.target).data('original-title') == 'undefined' &&
!$(e.target).parents().is('.popover.in') && !$(e.target).parents().is('[data-original-title]')) {
$('[data-original-title]').popover('hide');
}
});

Modify target url in onclick handler

Is it possible to modify the target URL in the onclick handler? How?
I don't want to use things like window.location = ... because it changes the browsers' behaviour (click vs ctrl-click, opening in new tab, opening in particular window/frame etc...). I want a clean solution - just change the url and the rest should be done itself as it would normally be.
$(...).click(function () {
if (check_some_condition)
// modify target url here...
// do not want to do window.location= - this is not clean
// as it changes the browsers' behaviour (ctrl-click, opening in particular window/frame etc.)
return true;
});
Try
​$(function(){
$("#theLink").click(function(){
$(this).attr("href","http://tnbelt.com");
});
});​​​​
Edit: Updated code because the event handler script is executed first and then the default action takes place.
Added below version to show you that you can use .click as you didn't notice the quirks mode link I shared with you. DEMO
$(document).ready (function () {
$('#changeMe'). click (function (e) {
var goLucky = Math.floor(Math.random()*12);
if (goLucky % 2 == 0) {
this.href = "http://www.google.com";
} else {
this.href = "http://www.hotmail.com";
}
});
});
Commented e.preventDefault(); & $(this).click() as it is not required..
DEMO
$(document).ready (function () {
$('#changeMe').one ('click', function (e) {
//e.preventDefault();
this.href = "http://www.google.com";
//$(this).click();
});
});
Let us consider a hidden anchor tag
<a id="linkId" href="myPageToGo.html" class="thickbox" title="" style="visibility:hidden;">Link</a>
Then you can simulate the anchor click in your code...
$(...).click(function () {
if (check_some_condition)
$('#linkId').click();
return true;
});
EDIT - Alternative way
Wrap the element clicked inside a anchor tag...
$(...).click(function () {
if (check_some_condition)
$(this).wrap('<a id="new1" />');
$('#new1').click();
return true;
});
Yup.
$(this).attr('href', 'http://example.com/');
A lot of the answers including the top comment have missed out on an important point. If a user simply right clicks the URL to perhaps open in a new tab/window, this method won't work because you're directly requesting at the location specified by the 'href' URL instead of going through the onclick event.
You could try the same at this demo fiddle mentioned on Gourneau's post.
http://jsfiddle.net/skram/PtNfD/7/
$(document).ready (function () {
$('#changeMe').one ('click', function (e) {
this.href = "http://www.google.com";
});
});

Prevent page scroll after click?

After clicking on the link, Click Me, the page scrolls back to the top. I do not want this. How can fix it?
Example: http://jsfiddle.net/Y6Y3Z/
Scroll-bar:
function myalert() {
var result = true;
//var hide = $('.alert').fadeOut(100);
//var css = $('#appriseOverlay').css('display','none');
var $alertDiv = $('<div class="alert">Are you sure you want to delete this item?<div class="clear"></div><button class="ok">no</button><button class="cancel">yes</button></div>');
var link = this;
$('body').append($alertDiv);
$('.ok').click(function () {
$('.alert').fadeOut(100);
$('#appriseOverlay').css('display', 'none');
callback(true, link);
});
$('.cancel').click(function () {
$('.alert').fadeOut(100);
$('#appriseOverlay').css('display', 'none');
callback(false, link);
});
$alertDiv.fadeIn(100);
$('#appriseOverlay').css('display', 'block');
return result;
};
$('.click').click(myalert);
function callback(result, link) {
//
if(result){
}
}
You only need to change the "#" to "javascript:void(0)" on HTML code:
Click Me
Another solution is add a "/" after the "#":
Click Me
The reason that it is going to the top of the page is because your anchor tag has a hash symbol as the href. The hash syntax allows you to refer to a named anchor in the document, with the link taking you to that place in the document. The default action for an anchor tag when you click on it and the href refers to a named anchor that doesn't exist is to go to the top of the page. To prevent this cancel the default action by returning false from the handler or using preventDefault on the event.
function myalert(e) {
e.preventDefault(); // <-- prevent the default action
...
return false; // <-- alternative way to prevent the default action.
};
simply prevent the default function (jump to #marker) from executing: http://jsfiddle.net/Y6Y3Z/1/

Categories

Resources