I've got a jQuery routine I need to convert to MooTools, but I can't get it to work. Here's my jQuery version:
$(".google-analytics-link").click(function () {
var href = $(this).attr("href");
pageTracker._link(href);
location.href = href;
return false;
});
Here's my MooTools translation:
$$(".google-analytics-link").addEvent("click", function () {
var href = this.get("href");
pageTracker._link(href);
location.href = href;
return false;
});
Doesn't seem to work though. I don't understand MooTools selectors. Any help, please?
You don't need to explicitly set the window's location when clicking the link already does it. Currently the code stops the native event, calls a method on the pageTracker object, then redirects to the location of the clicked link.
Google Analytics documentation for the _link method says that
This method works in conjunction with the _setDomainName() and _setAllowLinker() methods to enable cross-domain user tracking. The _link() method passes the cookies from this site to another via URL parameters (HTTP GET). It also changes the document.location and redirects the user to the new URL.
implying that you simply have to stop the click event, and call the _link method which will take care of the rest.
var analyticsLinks = document.getElements('.google-analytics-link');
analyticsLinks.addEvent('click', function(event) {
// stop the page from navigating away
event.stop();
var href = this.get('href');
// let the Analytics API do its work, and then redirect to this link
pageTracker._link(href);
});
$$(".google-analytics-link").each(function (e) {
e.addEvent("click", function () {
var href = this.get("href");
pageTracker._link(href);
location.href = href;
return false;
});
});
Related
I'm not quite sure if I'm not using this in the correct scope or what, but I have a script that basically captures a link click and causes the page to fade out before going to the linked page. However, if the link is a JavaScript onclick, the script fails.
Here's my code:
<script type="text/javascript">
pageObj = {
init: function(){
$("body").fadeTo("slow", 1);
},
redirectPage: function(redirect){
window.location = redirect;
},
linkLoad: function(location){
$("body").fadeOut(1000, this.redirectPage(location));
}
};
$(document).ready(function() {
pageObj.init();
$("a").click(function(e){
e.preventDefault();
if (this.attr('onclick') !== undefined) {
eval(this.attr('onclick').val());
} else {
var location = this.href;
pageObj.linkLoad(location);
}
});
});
</script>
As you can see, I'm trying to do a check to see if the link has the onclick attribute, and then call the onclick function if it exists. How can I achieve this?
Use: $(this).attr instead of this.attr
This forces it into the context of jQuery.
While Diodeus is correct that you need to wrap this in a jQuery collection before using attr() (it's a method of a jQuery collection, not of an HTMLElement), you can just as well skip attr().
$("a").click(function(e){
var location;
e.preventDefault();
if ($.isFunction(this.onclick)) {
this.onclick.call(this, e);
} else {
location = this.href;
pageObj.linkLoad(location);
}
});
Note that I used the property (when an HTML document loads, attributes are usually preloaded into properties, with on_______ attributes being preloaded as methods. Also note that I used this.onclick.call() rather than eval(), setting the correct this for onclick methods, and ensuring access to the event object as an argument.
i have this small piece of code
$("a").live("click",function(event) {
<% String lifeCare=LifeEventProperties.getInstance().getProperty("lifeCare");%>
var s="<%=lifeCare%>";
var href = $(this).attr('href');
if (href.indexOf(s) != -1) {
loadLifeCare(href) ;
event.preventDefault();
}
});
function loadLifeCare(href)
{
var wnd=window.open('/NASApp/benemain/LifeCareSite');
setTimeout(function() {
wnd.location.href = href;
}, 6000);
}
here in my jsp page i have checked for a particular word in url's using jquery and that word is like "something.com" which i am fetching from property file ,now if this something.com is found in the url which a user has clicked then i am calling a javascript function which then opens a new window with an internal site url which is taking care of user's session for that page which has this something.com and then i reload the page with "href" that user actually clicked .
the problem is its working good in all browser's other IE and my client loves IE,
IE is directly going to the link which bypassing loadLifeCare method and giving me this error on console
The value of the property 'loadLifeCare' is null or undefined, not a Function object
can any suggest something why it is happening ?is there anything in this code that IE don't understand ,i am getting a feeling that issue is with window.open() maybe but i am not sure and i don't even know any alternative if that's the case.
please help me and tell me if you need any clarification on anything..
Try this
fixed the deprecated live
used a better method to open windows (yours may very likely give access denied;
moved the function to before it is used and wrapped the click event handler in a a load handler
function loadLifeCare(href) {
var wnd=window.open('/NASApp/benemain/LifeCareSite',"lifeCareWin");
if (wnd) setTimeout(function() {
window.open(href,"lifeCareWin");
}, 6000);
}
$(function() {
$("a").on("click",function(event) {
<% String lifeCare=LifeEventProperties.getInstance().getProperty("lifeCare");%>
var s="<%=lifeCare%>";
var href = $(this).attr("href"); // this.href might be useful too
if (href.indexOf(s) != -1) {
loadLifeCare(href) ;
event.preventDefault();
}
});
});
I’ve made a one page site. When user clicks on the menu buttons, content is loaded with ajax.
It works fine.
In order to improve SEO and to allow user to copy / past URL of different content, i use
function show_content() {
// change URL in browser bar)
window.history.pushState("", "Content", "/content.php");
// ajax
$content.load("ajax/content.php?id="+id);
}
It works fine. URL changes and the browser doesn’t reload the page
However, when user clicks on back button in browser, the url changes and the content have to be loaded.
I've done this and it works :
window.onpopstate = function(event) {
if (document.location.pathname == '/4-content.php') {
show_content_1();
}
else if (document.location.pathname == '/1-content.php') {
show_content_2();
}
else if (document.location.pathname == '/6-content.php') {
show_content_();
}
};
Do you know if there is a way to improve this code ?
What I did was passing an object literal to pushState() on page load. This way you can always go back to your first created pushState. In my case I had to push twice before I could go back. Pushing a state on page load helped me out.
HTML5 allows you to use data-attributes so for your triggers you can use those to bind HTML data.
I use a try catch because I didn't had time to find a polyfill for older browsers. You might want to check Modernizr if this is needed in your case.
PAGELOAD
try {
window.history.pushState({
url: '',
id: this.content.data("id"), // html data-id
label: this.content.data("label") // html data-label
}, "just content or your label variable", window.location.href);
} catch (e) {
console.log(e);
}
EVENT HANDLERS
An object filled with default information
var obj = {
url: settings.assetsPath, // this came from php
lang: settings.language, // this came from php
historyData: {}
};
Bind the history.pushState() trigger. In my case a delegate since I have dynamic elements on the page.
// click a trigger -> push state
this.root.on("click", ".cssSelector", function (ev) {
var path = [],
urlChunk = document.location.pathname; // to follow your example
// some data-attributes you need? like id or label
// override obj.historyData
obj.historyData.id = $(ev.currentTarget).data("id");
// create a relative path for security reasons
path.push("..", obj.lang, label, urlChunk);
path = path.join("/");
// attempt to push a state
try {
window.history.pushState(obj.historyData, label, path);
this.back.fadeIn();
this.showContent(obj.historyData.id);
} catch (e) {
console.log(e);
}
});
Bind the history.back() event to a custom button, link or something.
I used .preventDefault() since my button is a link.
// click back arrow -> history
this.back.on("click", function (ev) {
ev.preventDefault();
window.history.back();
});
When history pops back -> check for a pushed state unless it was the first attempt
$(window).on("popstate", function (ev) {
var originalState = ev.originalEvent.state || obj.historyData;
if (!originalState) {
// no history, hide the back button or something
this.back.fadeOut();
return;
} else {
// do something
this.showContent(obj.historyData.id);
}
});
Using object literals as a parameter is handy to pass your id's. Then you can use one function showContent(id).
Wherever I've used this it's nothing more than a jQuery object/function, stored inside an IIFE.
Please note I put these scripts together from my implementation combined with some ideas from your initial request. So hopefully this gives you some new ideas ;)
i'm working with History.js and i'm trying to obtain an url as Google Plus urls.
(function(window, undefined){
var History = window.History; // Note: We are using a capital H instead of a lower h
if ( !History.enabled ) {
// History.js is disabled for this browser.
// This is because we can optionally choose to support HTML4 browsers or not.
return false;
}
History.Adapter.bind(window, 'statechange', function(){ // Note: We are using statechange instead of popstate
var State = History.getState(); // Note: We are using History.getState() instead of event.state
History.log(State.data, State.title, State.url);
console.log(State.data.page);
});
$('.item').live('click', function(e){
e.preventDefault();
var url = $(this).children(1).attr('href');
$(document).remove('#content');
$('#loaded').load('/controlpanel' + url + '.php #content');
History.pushState({page: url + '.php'}, "Prova Pagina", History.getRootUrl() + 'controlpanel' + url); // logs {state:1}, "State 1", "?state=1"
});
})(window);
this script works when I click on the link, but when I manually refresh the page, and I've already clicked on a link and the url becomes http://www.mysite.com/something/page, the browser gives me an 404 Error.
How can I solve it?
I would like to obtain something like: https://plus.google.com/explore
Even though JS allows you to not reload the whole page, the URL should still be accessible on the server side, so that someone accessing directly the link will see something (not to mention graceful degradation).
Also, you have to add a click handler on the anchor links, so that you can prevent the default action (going to the link) and use the pushState method to change the URL. Something like this:
document.body.onclick = function( e ) {
var evt = e || window.event,
target = evt.target || evt.srcElement // Get the target cross-browser
// If the element clicked is a link
if ( target.nodeName === 'A' ) {
// Use the History API to change the URL
History.pushState() // Use the library correctly
// Don't forget to return false so that the link doesn't make you reload the page
return false
}
}
This is definitely not production code (you should check for external links, not bind on the body, etc), but you get the idea.
I'm using the hash to load content dynamically. To make the back button work I am capturing hash changes. However sometimes I need to change the hash without triggering the hash changed function (eg, when the page was redirected server side and I need to update the hash once the content has returned.)
The best solution I have come up with is to unbind the hashchange event, make the change and then rebind it. However, as this happens asynchronously, I am finding that it rebinds too quickly and still catches the hash change.
My solution at the moment is very poor: Rebinding in a setTimeout. Does anyone have a better idea?
$(window).unbind( 'hashchange', hashChanged);
window.location.hash = "!" + url;
setTimeout(function(){
$(window).bind( 'hashchange', hashChanged);
}, 100);
Edit:
Amir Raminfar's suggestion prompted me to a solution that does not require a timeout.
I added a class variable
_ignoreHashChange = false;
When I want to change the hash silently I do this:
_ignoreHashChange = true;
window.location.hash = "!" + url;
and the hash changed event does this :
function hashChanged(event){
if(_ignoreHashChange === false){
url = window.location.hash.slice(2);
fetchContent(url);
}
_ignoreHashChange = false;
}
You could use history.replaceState and append the hash, to replace the current URI without triggering the hashchange event:
var newHash = 'test';
history.replaceState(null, null, document.location.pathname + '#' + newHash);
JSFiddle example
You can have a function like this:
function updateHash(newHash){
...
oldHash = newHash
}
then in your setTimeOut you need to do
function(){
if(oldHash != currenHash){
updateHash(currenHash);
}
}
So now you can call update hash manually and it won't be triggered by the event. You can also have more parameters in updateHash to do other things.
By the way, have you looked at the jquery history plugin? http://tkyk.github.com/jquery-history-plugin/