Tracking onClick links not working as hyperlinks - javascript

<li>KONKURRANSEREGLER</li>
<div class ="contactButton"> <span>Kontakta Oss</span></div>
These two buttons don't work as links, see: http://www.undergroundblc.co.uk/chaqwa/ i.e. you click but nothing happens. If you change 'return false' to 'return true' the buttons work again but no longer register with the tracking company. So my question is how do I keep 'return false' yet get them to work as links.

First of all. If you HAVE to have javascript embedded in your html (not recommended) you don't need to have the javascript: declaration in events (onclick in your example). It would be much better to use dom methods el.addEventListener('click', kenshoo_conv, false).
If you need to fire a function before the page unloads you will need some control of that function to know when it has successfully fired the tracking becon.
Once you have your onclick attached, you can use the event argument (that is passed to the function) to stop the event from firing, evt.preventDefault(), do everything you need to do, then set the location.href when your tracker becon has successfully fired.
All up your code could look something like this (assuming everything is normalised, so not in IE):
HTML
<a href="konkurranseregler.html" data-args="rules,0,,sem,NOK"
class="kenshoo_conv_link">KONKURRANSEREGLER</a>
JAVSCRIPT
function kenshoo_conv(evt) {
var dest = this.href,
args = this.getAttribute('data-args').split(",");
evt.preventDefault();
//add success event to arguments
args.push(function () {
location.href = dest;
});
//fire the tracking function
trackMe.apply(this, args);
}
var kenshoo_conv_links = document.getElementsByClassName("kenshoo_conv_link");
for (var i = 0, il = kenshoo_conv_links.length; i < il; i += 1) {
kenshoo_conv_links[i].addEventListener('click', kenshoo_conv, false);
}
This will make the last argument in the trackMe function a callback to change the location to the destination of the link. So you'll have to fire that function once the tracker has successfully fired. If you don't know that, you could do it after a timeout (not ideal)

Related

How can I call an ajax click event from page load?

I have a click event which fires when I click on a button, it opens a modal interface:
$(".profileF2fClinicalServiceDetails").live("click", function(){
var requestUrl = '/php/includes/ajax.php?operation=profile_edit_f2f_clinical_service_details&service=f2f&counsellor_id='+getPractitionerId($(this))+'&counsellor_address_id='+getAddressId($(this))+'&edit_level='+getEditLevel($(this))+'&tab='+getTab($(this));
openDialog(requestUrl, "Edit Face to Face Service Details", 850, "location.replace(getCleanedLocationHref()+'&tab="+getTab($(this))+"');");
return false;
});
But now I want to prompt this to be fired when a page loads, how do I call it directly from the HTML?
Add the code in the click event to an independent function (rather than a closure) called, for example, showPopup. Then change the function bound to the click event to call showPopup, and add a call to showPopup function on page load.
A note, as of 1.7 jQuery's live function is deprecated, you should use on instead (source)
You will have to pass some arguments to the function, since you won't be able to use this during the initial call. You will have to pass those arguments to the main function the first time you call it, I won't presume to guess how you'll determine that.
When the click event is fired, you can extract the arguments from the element in the fashion you're currently using. You'd have something like this:
$(document).ready(function() {
// add the click event
$(".profileF2fClinicalServiceDetails").on("click", function () {
var Me = $(this);
showPopup(
getPractitionerId(Me),
getAddressId(Me),
getEditLevel(Me),
getTab(Me)
);
});
// call the function right away
showPopup(
[initial_counsellor_id],
[initial_address_id],
[initial_level],
[initial_tab]
);
});
function showPopup(counsellor_id, address_id, level, tab) {
var requestUrl = '/php/includes/ajax.php?operation=profile_edit_f2f_clinical_service_details&service=f2f&counsellor_id='+counsellor_id+'&counsellor_address_id='+address_id+'&edit_level='+level+'&tab='+tab;
openDialog(
requestUrl,
"Edit Face to Face Service Details",
850,
"location.replace(getCleanedLocationHref()+'&tab="+tab+"');"
);
return false;
}
Documentation and Related Reading
jQuery.ready - http://api.jquery.com/ready/
jQuery.on - http://api.jquery.com/on/
jQuery.live - http://api.jquery.com/live/ [DEPRECATED]
Javascript functions on MDN - https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Functions

document and image onclick priority

I have a document. I can't change it.
It has an image.
Image has onclick event (imageCallback).
Also I have a bookmarklet. I want to do document.onclick = documentCallback;
And I want to make documentCallback have priority: it should runs first. And imageCallback shouldn't run at all until I close the bookmarklet.
How can I do it?
Add the event handler through addEventListener and set useCapture parameter to true:
document.addEventListener('click', documentCallback, true)
Events can be dispatched in two phases, the bubbling phase and the capture phase, the capture phase comes first, you should Take a look at this
delete your imageCallback-function, and lookup the event-Source in your document.onclick:
html:
<img id="id-of-your-img" src="...">
javascript:
document.onclick = function (event) {
// do what needs to be done first
//do whatever you want to do when the img was clicked
if(event.srcElement.id === 'id-of-your-img') {
}
};
edit (i think i know now what you want to achieve (the hint "bookmarklet" was important):
var yourimg = document.getElementById('your-img-id')
, imgCallback = yourimg.onclick;
yourimg.onclick = function () {};
document.onclick = function (event) {
// do what needs to be done first
if(event.srcElement === yourimg) {
imgCallback();
}
};
what is done here? we get the image, overwrite the current click handler (but save it into our imgCallback-Var. when the document is clicked, we do whatever we want to do, and then take a look if the event-source was our image. if so, we execute our imgCallback-Function.

Prevent calling a function

I have two parts of scripts.
Part 1 :
$("mySelector").click(function() {
alert('you call me');
})
Part 2 :
$("mySelector").click(function() {
if(myCondition) {
//how can i prevent calling the first function from here ???
}
})
The whole problem, is that i have no access to part1. So i need to unbind the event allready specified in part 1, if myCondition is true, but otherwise i need to call the first function.
Thanks
UPDATE:
Thank you. I didn't know about stopImmediatePropagation(). But i feel, that there must be something like that :)
But actually in my case it doesn't work :(
Please have a look at my site
http://www.tours.am/en/outgoing/tours/%D5%80%D5%B6%D5%A4%D5%AF%D5%A1%D5%BD%D5%BF%D5%A1%D5%B6/Park-Hyatt-Goa/
Under the hotel description tab i have cloud carousel, when i click on not active image (not the front image), as you can see i'm consoling that i stopImmediatePropagation() there, but the event however calls :(
If your handler is registered first, then you can use event.stopImmediatePropagation like this:
$("mySelector").click(function(event) {
if(myCondition) {
event.stopImmediatePropagation();
}
})
Be aware that this will also stop event bubbling, so it will also prevent click handlers on parent elements from being invoked.
Update: If this does not work, then your handler is attached after the one you want to control. This is a problem that makes the solution much more difficult. I suggest seeing if you can bind "before the other guy", otherwise you will have to unbind the existing handler and then conditionally invoke it from within your own by retaining a reference to it. See jQuery find events handlers registered with an object.
No access:
$("#mySelector").click(function() {
alert('you call me');
})
Access:
var myCondition = true, //try false too
fFirstFunction = $("#mySelector").data("events").click[0].handler;
$("#mySelector").unbind("click");
$("#mySelector").click(function() {
if(myCondition) {
alert(myCondition);
} else {
$("#mySelector").click(fFirstFunction);
}
});
Look at this example
You can call
$('mySelector').unbind('click');
to get rid of all the click handlers. If your script is loaded after the other one (which appears to be the case), then that should do it. However note that it does unbind all "click" handlers, so make sure you call that before you add your own handler.
If you can't ensure your handler is attached first, try the following code:
var events = $('mySelector').data("events"); //all handlers bound to the element
var clickEvents = events ? events.click : null;//all click handlers bound to the element
$('mySelector').unbind('click'); //unbind all click handlers
//bind your handler
$("mySelector").click(function(e) {
if (myCondition) {
//do what you want
} else {
//call other handlers
if (clickEvents) {
for (var prop in clickEvents)
clickEvents[prop].call(this, e);
}
}
})
Update:
Above code is for jQuery 1.3.2
Above code is based on internal implementation of jQuery 1.3.2, so please check it carefully once you update jQuery.
return false;
-or-
event.preventDefault();

jQuery: Get reference to click event and trigger it later?

I want to wrap an existing click event in some extra code.
Basically I have a multi part form in an accordion and I want to trigger validation on the accordion header click. The accordion code is used elsewhere and I don't want to change it.
Here's what I've tried:
//Take the click events off the accordion elements and wrap them to trigger validation
$('.accordion h1').each(function (index, value) {
var currentAccordion = $(value);
//Get reference to original click
var originalClick = currentAccordion.click;
//unbind original click
currentAccordion.unbind('click');
//bind new event
currentAccordion.click(function () {
//Trigger validation
if ($('#aspnetForm').valid()) {
current = parseInt($(this).next().find('.calculate-step').attr('data-step'));
//Call original click.
originalClick();
}
});
});
jQuery throws an error because it's trying to do this.trigger inside the originalClick function and I don't think this is what jQuery expects it to be.
EDIT: Updated code. This works but it is a bit ugly!
//Take the click events off the accordion elements and wrap them to trigger validation
$('.accordion h1').each(function (index, value) {
var currentAccordion = $(value);
var originalClick = currentAccordion.data("events")['click'][0].handler;
currentAccordion.unbind('click');
currentAccordion.click(function (e) {
if ($('#aspnetForm').valid()) {
current = parseInt($(this).next().find('.calculate-step').attr('data-step'));
$.proxy(originalClick, currentAccordion)(e);
}
});
});
I think this:
var originalClick = currentAccordion.click;
Isn't actually doing what you think it is - you're capturing a reference to the jQuery click function, rather than event handler you added, so when you call originalClick() it's equivalent to: $(value).click()
I finally came up with something reliable:
$(".remove").each(function(){
// get all our click events and store them
var x = $._data($(this)[0], "events");
var y = {}
for(i in x.click)
{
if(x.click[i].handler)
{
y[i] = x.click[i].handler;
}
}
// stop our click event from running
$(this).off("click")
// re-add our click event with a confirmation
$(this).click(function(){
if(confirm("Are you sure?"))
{
// if they click yes, run click events!
for(i in y)
{
y[i]()
}
return true;
}
// if they click cancel, return false
return false;
})
})
This may seem a bit weird (why do we store the click events in the variable "y"?)
Originally I tried to run the handlers in x.click, but they seem to be destroyed when we call .off("click"). Creating a copy of the handlers in a separate variable "y" worked. Sorry I don't have an in depth explanation, but I believe the .off("click") method removes the click event from our document, along with the handlers.
http://www.frankforte.ca/blog/32/unbind-a-click-event-store-it-and-re-add-the-event-later-with-jquery/
I'm not a jQuery user, but in Javascript, you can set the context of the this keyword.
In jQuery, you use the $.proxy() method to do this.
$.proxy(originalClick, value);
originalClick();
Personally, I'd look at creating callback hooks in your Accordion, or making use of existing callbacks (if they exist) that trigger when opening or closing an accordion pane.
Hope that helps :)
currentAccordion.click is a jQuery function, not the actual event.
Starting with a brute-force approach, what you'd need to do is:
Save references to all the currently bound handlers
Unbind them
Add your own handler, and fire the saved ones when needed
Make sure new handlers bound to click are catched too
This looks like a job for an event filter plugin, but I couldn't find one. If the last point is not required in your application, then it's a bit simpler.
Edit: After some research, the bindIf function shown here looks to be what you'd need (or at least give a general direction)

Passing argument to JS function from link onclick

I have a link that looks like this:
<a id="mylink" onclick="deleteHike( 3 );" href="javascript:void(0);">Yes</a>
It is able to call this JavaScript:
window.onload = function()
{
//Get a reference to the link on the page
// with an id of "mylink"
var a = document.getElementById("mylink");
//Set code to run when the link is clicked
// by assigning a function to "onclick"
a.onclick = function( hike_id )
{
// Somecode her
// But when I try to use the hike_id it displays as [object MouseEvent]
}
}
But the value that comes in is [object MouseEvent], not the number that I was expecting. Any idea why this happens and how to fix this? :)
Thanks!
You are trying to assign the function to your link in two different and conflicting ways.
Using the eval-ed function string, onclick = "function(value)", works but is deprecated.
The other way of binding the click handler in the onload event works too, but if you want a particular value to be passed, you'll have to change your script a bit because the value as given in the initial onclick is completely lost when you set the onclick to a new function.
To make your current method work, you don't need an onload handler at all. You just need this:
function deleteHike(hike_id) {
// Some code here
}
To do it the second way, which I recommend, it would look like this:
<a id="mylink" href="javascript:void(0);">Yes</a>
with this script:
function deleteHike(e, hike_id) {
// Some code here
// e refers to the event object which you can do nifty things with like
// - learn the actual clicked element if it was a parent or child of the `this` element
// - stop the event from bubbling up to parent items
// - stop the event from being captured by child items
// (I may have these last two switched)
}
function getCall(fn, param) {
return function(e) {
e = e || window.event;
e.preventDefault(); // this might let you use real URLs instead of void(0)
fn(e, param);
};
}
window.onload = function() {
var a = document.getElementById("mylink");
a.onclick = getCall(deleteHike, 3);
};
The parameter of a DOM event function is the event object (in Firefox and other standards-compliant browsers). It is nothing in IE (thus the need to also grab window.event). I added a little helper function for you that creates a closure around your parameter value. You could do that each time yourself but it would be a pain. The important part is that getCall is a function that returns a function, and it is this returned function that gets called when you click on the element.
Finally, I recommend strongly that instead of all this, you use a library such as jQuery because it solves all sorts of problems for you and you don't have to know crazy JavaScript that takes much expertise to get just right, problems such as:
Having multiple handlers for a single event
Running JavaScript as soon as possible before the onload event fires with the simulated event ready. For example, maybe an image is still downloading but you want to put the focus on a control before the user tries to use the page, you can't do that with onload and it is a really hard problem to solve cross-browser.
Dealing with how the event object is being passed
Figuring out all the different ways that browsers handle things like event propagation and getting the clicked item and so on.
Note: in your click handler you can just use the this event which will have the clicked element in it. This could be really powerful for you, because instead of having to encode which item it was in the JavaScript for each element's onclick event, you can simply bind the same handler to all your items and get its value from the element. This is better because it lets you encode the information about the element only in the element, rather than in the element and the JavaScript.
You should just be able to declare the function like this (no need to assign on window.onload):
function deleteHike(hike_id)
{
// Somecode her
// But when I try to use the hike_id it displays as [object MouseEvent]
}
The first parameter in javascript event is the event itself. If you need a reference back to the "a" tag you could use the this variable because the scope is now the "a" tag.
Here's my new favorite way to solve this problem. I like this approach for its clarity and brevity.
Use this HTML:
<a onclick="deleteHike(event);" hike_id=1>Yes 1</a><br/>
<a onclick="deleteHike(event);" hike_id=2>Yes 2</a><br/>
<a onclick="deleteHike(event);" hike_id=3>Yes 3</a><br/>
With this JavaScript:
function deleteHike(event) {
var element = event.target;
var hike_id = element.getAttribute("hike_id");
// do what you will with hike_id
if (confirm("Delete hike " + hike_id + "?")) {
// do the delete
console.log("item " + hike_id + " deleted");
} else {
// don't do the delete
console.log("user canceled");
}
return;
}
This code works because event is defined in the JavaScript environment when the onclick handler is called.
For a more complete discussion (including why you might want to use "data-hike_id" instead of "hike_id" as the element attribute), see: How to store arbitrary data for some HTML tags.
These are alternate forms of the HTML which have the same effect:
<a onclick="deleteHike(event);" hike_id=4 href="javascript:void(0);">Yes 4</a><br/>
<button onclick="deleteHike(event);" hike_id=5>Yes 5</button><br/>
<span onclick="deleteHike(event);" hike_id=6>Yes 6</span><br/>
When you assign a function to an event on a DOM element like this, the browser will automatically pass the event object (in this case MouseEvent as it's an onclick event) as the first argument.
Try it like this,
a.onclick = function(e, hike_id) { }

Categories

Resources