onclick not firing for download - javascript-events

Im having trouble with a onclick event for a download. It does not want to fire when I click on the link. It just carries on as normal. But it does work with an external link. Have I done something obviously wrong?
Royal Society of Wildlife Trusts.
2010-2015 strategy,
Its doing the same in FF, Chrome and IE 8.
function trackExternalLink(link, action) {
_gaq.push(['_trackPageview', action]);
setTimeout('document.location = "' + link.href + '"', 25000)
return false;
}

You're not returning false from your onclick handler. You're returning false from the function it calls, but then throwing that away in the handler. You meant:
onclick="return trackExternalLink(this, '/links-the_royal_society_of_wildlife_trusts');"
However all this onclick stuff is pretty ugly. Consider unobtrusive scripting. And lose the nasty call to setTimeout creating script from a string. Do Google really recommend this code? It kinda sucks.
Here's a quick hack version that wraps the action into a class name:
Royal Society of Wildlife Trusts.
<script type="text/javascript">
for (var i= document.links.length; i-->0;)
if (document.links[i].className.substring(0, 5)==='ping-')
document.links[i].onclick= pingclick;
function pingclick() {
var action= this.className.substring(5);
var href= this.href;
_gaq.push(['_trackPageview', action]);
setTimeout(function() {
location.href= href;
}, 25000);
return false;
}
</script>
This still isn't great. 25 seconds (25000) is obviously way too long a delay; you probably want to pull that down to around 200ish. Really it should be following the link as soon as the XMLHttpRequest that passes the information to the server is complete, rather than using an arbitrary delay, but Google don't seem to give you that option. How poor. Then again, link-tracking pingback scripts are a nasty, user-hostile activity anyway.

I believe you need to return false to prevent the click from functioning as normal, this may, however, be jQuery specific.
I would also recommend using a framework rather than onclick attributes, they're messy and the framework will also be helpful in other respects.

Related

SiteCatalyst : Tracking Custom links on Webkit browsers

My query is that I have a link that redirects to another page. In webkit browsers, how to force the sitecatalyst server call (script execution) to finish before the redirect happens?
I am using sitecatalyst for a portal. I have
configured the custom link call to include the doneAction parameter for
successful call completion on webkit browsers (As mentioned in Adobe guide).
The custom link code for onClick event of button is as below:
<script language="javascript" >
function search(keyword)
{
var s=s_gi('testing');
s.linkTrackVars="prop11,events";
s.linkTrackEvents="event6";
s.prop11=keyword;
s.events="event6";
s.tl(this,'o','Search',navigate());
window.location=searchresults.html;
}
</script>
<script language="javascript" >
function navigate()
{
return false;
/*To induce a delay to ensure that image request is sent to Adobe before the
user leaves the page.(As given in Adobe guide - code release H.25))
Code version H.25 (released July 2012) includes an overloaded
track link method ( s.tl ) that forces WebKit
browsers to wait for the track link call to complete.)*/
}
</script>
However, even after this, I am getting error in custom link tracking. The redirect happens before the call can complete.
Please help on the same. Thanks in Advance.
Regards,
Harshil
Okay so firstly there are a number of issues with how you implemented it. Here is an example of how it should look like:
search
<script type='text/javascript'>
function search(keyword) {
var s=s_gi('testing');
s.linkTrackVars="prop11,events";
s.linkTrackEvents="event6";
s.prop11=keyword;
s.events="event6";
s.tl(this,'o','Search',null,navigate);
return false;
}
function navigate(){
window.location="searchresults.html";
}
</script>
Some points
You didn't actually post the link or whatever you are using that calls the search function so I have a link shown as an example.
You passed the navigate function as the 4th argument when it should be the 5th (with a null or blank string as a placeholder for the 4th)
It should be navigate not navigate(). The way you did it, you are making a call to the function and passing the result of the function as an argument. s.tl requires the actual function or reference to a function, and it will make the call to the function. In fairness, the Adobe document is typoed: it shows the example wrapped in quotes which doesn't work.
The redirect should be placed in navigate, not in search.
Replace the link href with javascript function
function trackLink(e) {
nextUrl = e.href;
e.href = "javascript:sendData('" + nextUrl + "')";
}
function sendData(url) {
s.tl(this, "o", "Link Name", null, function() {
window.location.href = url;
});
}
or try out the following
function sendData(obj) {
s.tl(obj, "o", "Link Name", null, "navigate");
return false;
}
Link
Link tracking is a dinosaur form of tracking as the numbers are barely accurate these days if you are not putting analytics before user experience. What I don't understand is that why don't you measure this on the next page instead of the link, unless you have no control over the next step?
As for your question: Previous examples on how to prevent link following before event is executed are quite solid, but remember if you have other JS code binded, be sure not to break it. As for the syntax, you can pass all variables to s.tl function as an object without setting linkTrackVars and linkTrackEvents for the s-object, which might have negative effects on events if case you use the code on dynamic pages.
E.g.
...
var data = {
linkTrackVars="prop11,events",
linkTrackEvents="event6",
prop11=keyword,
events="event6"
};
s.tl(this, "o", "Search", data, "navigate");
...
Note: You can't actually use props and events together in standard reporting. As per the code you pasted in comments to Crayon I can see that you are using eVars, so I assume that the example was not that accurate.

Auto save joomla article for client

i know its sounds a bit crazy, but so many clients have problems with not saving their article properly.
I just wanted to use a simple method to trigger the onclick of the APPLY button inside a joomla article in edit mode.
Primarily back end editing as i have a good admin template that allows me to show clients the bare bones.
I know that by clicking apply the page reloads but thats better than nothing.
How on earth do i add do this?
I was hoping something like this would work but i dont quite know how to trigger a button that seems to reside inside a toolbar function of some sort.
I have this:
<script type="text/javascript">
$(document).ready(function() {
$('??????').trigger('click');
});
</script>
What would replace the question marks?
Also i know i would need to put a timer into the jquery code but how do i get the link below to trigger?
http://mydomain.com/administrator/index.php?option=com_content&sectionid=1&task=edit&cid[]=97
In the toolbar.content.html.php file joomla has this:
class TOOLBAR_content
{
function _EDIT($edit)
{
$cid = JRequest::getVar( 'cid', array(0), '', 'array' );
$cid = intval($cid[0]);
$text = ( $edit ? JText::_( 'Edit' ) : JText::_( 'New' ) );
JToolBarHelper::title( JText::_( 'Article' ).': <small><small>[ '. $text.' ]</small></small>', 'addedit.png' );
JToolBarHelper::preview( 'index.php?option=com_content&id='.$cid.'&tmpl=component', true );
JToolBarHelper::save();
/////////////////////////////////////
JToolBarHelper::apply(); // < // THIS IS WHAT I WANT TO TRIGGER
/////////////////////////////////////
if ( $edit ) {
// for existing articles the button is renamed `close`
JToolBarHelper::cancel( 'cancel', 'Close' );
} else {
JToolBarHelper::cancel();
}
}
...... more stuff here
}
I know this might sound crazy but wouldnt it be great if autosave could happen even without a reload, but i guess that would mean posting all the data using jquery rather than the php post and reload page method.
Anyways im not expecting a miracle here but if anyone could help that would be great.
Cheers in advance
John
PS:
i just tried something like this hoping maybe it will work but it just reloads the page:
function autosave()
{
window.location = "index.php?option=com_content&sectionid=<?php echo $_GET['sectionid'];?>&task=edit&cid[]=<?php echo $row->id;?>"
}
You won't be able to do it without forcing a reload unless you decide to re-write the whole of com_content with an ajax implementation.
Looking at the code you've posted I guessing Joomla! 1.5 - which by default has MooTools 1.12 or 1.2.5 (if you enabled the MooTools upgrade plugin in later versions of 1.5.x) - so more of a question but why not use that?
You will have to modify the admin template to embed the JS you need, 1.5 has few triggers and none that are really worth using in the admin screens (unless you're up for a fair bit of PHP coding)
Somewhere in the <head> tag of com_content's Article view you will need to add this:
<script type="text/javascript">
var interval = 30 //seconds
var timer = setTimeout(submitbutton('apply'),(interval * 1000));
}
</script>
Please note I haven't tried this just typed it straight into here.
Since you're on 1.5 have you tried the Simple Content Versioning extension - it has autosave functionality that appears to be what you want - and probably works whereas who knows with my code in #3.

Track Youtube player's states in YUI.add

My embed code to play Youtube video is:
<object height="356" width="425" type="application/x-shockwave-flash" id="myytplayer" data="http://www.youtube.com/v/MTf6qXn5Prw?enablejsapi=1&playerapiid=ytplayer&version=3"><param name="allowScriptAccess" value="always"></object>
I want to track Youtube player's events (play/pause/stop etc)
The following piece of code works independently
window.onYouTubePlayerReady = function(playerId){
ytplayer = document.getElementById("myytplayer");
ytplayer.addEventListener("onStateChange", "onytplayerStateChange");
}
window.onytplayerStateChange = function (newState) {
alert("Player's new state: " + newState);
}
I am using YUI.
When I put the same in
YUI.add('module-name', function(Y) {
[some other code...]
window.onYouTubePlayerReady = function(playerId){
// console.log(playerId); console.log(ytplayer);
ytplayer = document.getElementById("myytplayer");
ytplayer.addEventListener("onStateChange", "onytplayerStateChange");
}
window.onytplayerStateChange = function (newState) {
alert("Player's new state: " + newState);
}
},'3.4.0', {requires:'module-a', 'module-b'})
Function onytplayerStateChange works in Firefox and Safari but not in other browsers.
Then I tried YUI functions to make that working in all browsers so I did some changes
window.onYouTubePlayerReady = function(playerId){
var shinyPlayer = Y.one("#myytplayer");
shinyPlayer.on('onStateChange', function (e) {
e.preventDefault();
alert('here');
});
}
but it didn't work for me.
I don't want to place window.onytplayerStateChange outside of YUI.add('module-name', function(Y) {})
Please suggest what should I do to track Youtube player's states in all browsers.
Thanks in advance.
I made a jsFiddle to test this:
http://jsfiddle.net/2Mj6b/4/
For me it feels like addEventListener is a custom implementation of Google.
Normally the second parameter is a callback/function-pointer and no string.
If you attach a variable to the window object it gets global and is from every scope visible. So it's no problem if you define it in the YUI module.
The second problem is that you cant use the player as YUI object you have to stay on dom objects to get this work.
Oh this is a old question. Damn. But i will post this anyway. ;)

jQuery — trigger a live event only once per element on the page?

Here's the scenario
$("p").live('customEvent', function (event, chkSomething){
//this particular custom event works with live
if(chkSomething){
doStuff();
// BUT only per element
// So almost like a .one(), but on an elemental basis, and .live()?
}
})
Here's some background
The custom event is from a plugin called inview
The actual issue is here http://syndex.me
In a nutshell, new tumblr posts are being infnitely scrolled via
javascript hack (the only one out there for tumblr fyi.)
The inview plugin listens for new posts to come into the viewport, if the top of an image is shown, it makes it visible.
It's kinda working, but if you check your console at http://.syndex.me check how often the event is being fired
Maybe i'm also being to fussy and this is ok? Please let me know your professional opinion. but ideally i'd like it to stop doing something i dont need anymore.
Some things I've tried that did not work:
stopPropagation
.die();
Some solutions via S.O. didnt work either eg In jQuery, is there any way to only bind a click once? or Using .one() with .live() jQuery
I'm pretty surprised as to why such an option isnt out there yet. Surely the .one() event is also needed for future elements too? #justsayin
Thanks.
Add a class to the element when the event happens, and only have the event happen on elements that don't have that class.
$("p:not(.nolive)").live(event,function(){
$(this).addClass("nolive");
dostuff();
});
Edit: Example from comments:
$("p").live(event,function(){
var $this = $(this);
if ($this.data("live")) {
return;
}
$this.data("live",true);
doStuff();
});
This one works (see fiddle):
jQuery(function($) {
$("p").live('customEvent', function(event, chkSomething) {
//this particular custom event works with live
if (chkSomething) {
doStuff();
// BUT only per element
// So almost like a .one(), but on an elemental basis, and .live()?
$(this).bind('customEvent', false);
}
});
function doStuff() {
window.alert('ran dostuff');
};
$('#content').append('<p>Here is a test</p>');
$('p').trigger('customEvent', {one: true});
$('p').trigger('customEvent', {one: true});
$('p').trigger('customEvent', {one: true});
});
This should also work for your needs, although it's not as pretty :)
$("p").live('customEvent', function (event, chkSomething){
//this particular custom event works with live
if(chkSomething && $(this).data('customEventRanAlready') != 1){
doStuff();
// BUT only per element
// So almost like a .one(), but on an elemental basis, and .live()?
$(this).data('customEventRanAlready', 1);
}
})
Like Kevin mentioned, you can accomplish this by manipulating the CSS selectors, but you actually don't have to use :not(). Here's an alternative method:
// Use an attribute selector like so. This will only select elements
// that have 'theImage' as their ONLY class. Adding another class to them
// will effectively disable the repeating calls from live()
$('div[class=theImage]').live('inview',function(event, visible, visiblePartX, visiblePartY) {
if (visiblePartY=="top") {
$(this).animate({ opacity: 1 });
$(this).addClass('nolive');
console.log("look just how many times this is firing")
}
});
I used the actual code from your site. Hope that was okay.

Loading the target of a link in a <DIV> via jQuery's .live event into the same <DIV>?

I call a certain div from another page with jquery to be loaded into a div on my main page like this:
<script type="text/javascript">
$("#scotland").load("http://www.example.com/scotland .gallery");
</script>
<div id="scotland"></div>
The div I call is a piece of code which is automatically generated by a CMS made simple module, by the way.
Now it comes to my problem: The .gallery div I call, looks, a little simplified, like this:
<div class="gallery">
<span><img src="http://www.example.com/scotlandimage1.jpg"></span>
<span class="imgnavi"><a href="link_to_next_page_with_one_image">Next image</href></span>
</div>
I want the "next image"-link to load the next page into the .gallery div (it is always a page with one image on it). But what it does, is, it opens the new page http://www.example.com/scotland only.
I tried to use jquerys .live event to load the linked page (that would be "scotlandimage2" and the navigation, as you can see in the upper part - not only the image!), but I must have done something wrong. I tried different ways, but never got it to work. This was my last try:
$(".imgnavi a").click(function() {
var myUrl = $(this).attr("href");
$(".gallery").load(myUrl);
return false;
});
I have to admit that I am very new to jquery... But does someone know what I did wrong (do I even follow the right handlers?)?
Thanks very much in advance!
Martin
Your first attempt is good, but you're missing the required-for-ajax call to live instead of click:
$('.imgnavi a').live('click', function(ev) {
// Stop regular handling of "click" in most non-IE browsers
ev.preventDefault();
ev.stopPropagation();
// Load the new content into the div (same code you had)
$('.gallery').load($(this).attr('href'));
// Stop regular handling of "click" in IE (and some others)
return false;
}
EDIT in response to the question: "What will happen with the old $('gallery') content?"
With the above code, the old content will be replaced with the response to the .load() request. If you want to, say, prepend the image instead, you can just wrap the .load() call in a call to the built-in jQuery $.prepend( content ) method, like so:
$('gallery').prepend($.load($(this).attr('href')));
The same works for appending.

Resources