I need to implement deeplinking for my site as it's built heavily in AJAX. I understand the basic idea and have got deeplinking implemented for my top level nav. Problem is my site has multiple levels. A user can click on the top nav, which adds to the hash and then click on a secondary nav and a tertiary nav. I also need to add this secondary and tertiary nav click in to the hash...and then also be able to remove that item when the user clicks back on a primary nav item. I can't think of a way to do this...any ideas?
Oh and the code (jQuery) I'm using to achieve the hashing on the primary nav is:
updateHash : function(hash) {
var hashHistory = [];
location.hash = hash;
}
I' not quite sure what you are looking for. Maybe you should show some concrete examples. Until then how about something like this:
function updateHash(hashPath) {
if (hashPath.charAt(0) == "/") {
location.hash = "#" + hashPath;
return;
}
var currentHash = location.hash.split(/\//);
if (currentHash[0]) currentHash[0] = currentHash[0].substr(1); // Loose the #
var relHash = hashPath.split(/\//);
var part;
while (part = relHash.shift()) {
if (part == "..") {
currentHash.pop();
} else {
currentHash.push(part);
}
}
if (currentHash.length > 0)
location.hash = "#" + currentHash.join("/");
else
location.hash = "";
}
Examples:
updateHash("/topLevelItem");
alert(location.href); // "www.example.com/#/topLevelItem"
updateHash("secondLevelItem");
alert(location.href); // "www.example.com/#/topLevelItem/secondLevelItem"
updateHash("thirdLevelItem");
alert(location.href); // "www.example.com/#/topLevelItem/secondLevelItem/thirdLevelItem"
updateHash("../differentThirdLevelItem");
alert(location.href); // "www.example.com/#/topLevelItem/secondLevelItem/differentThirdLevelItem"
updateHash("../../differentSecondLevelItem");
alert(location.href); // "www.example.com/#/topLevelItem/differentSecondLevelItem"
updateHash("../anotherSecondLevelItem/anotherThirdLevelItem");
alert(location.href); // "www.example.com/#/topLevelItem/anotherSecondLevelItem/anotherThirdLevelItem"
updateHash("..");
alert(location.href); // "www.example.com/#/topLevelItem/anotherSecondLevelItem"
Related
I'm trying to create a tabbed area within my page. The tabs navigate hidden areas with out leaving the page. I also want to be able to link to an area with in the page. It's working except when you click the menu as well as revealing the hidden area it's rewriting the URL with only the tab extension and therefor breaking the link of the URL. So someone trying to share the link would not know the format..
I'm using this code https://css-tricks.com/examples/OrganicTabsReplaceState which I see no problem with.
You can see a live demo with my issue here: http://bit.ly/1IP1ST4
Clicking the tab is removing:
/products/eurorack-modules/waveform-modifiers/reactive-shaper/
And replacing it with ?tab=mytabname
It should be simply adding it. I'm struggling to work out why..?
If you inspect the source of the first link you provided, you will see that the tabs contain links like this:
Featured
That's an in-page link. You should use #'s for in page links. The reason the whole url is being replaced is because it's interpreting the href as a new url to go to. #'s look inside the current page.
This version of organictabs.jquery.js got it working in the end seemed to be an issue with the way it treated the URL.. Maybe this will help someone else.
// IIFE
(function($) {
// Define Plugin
$.organicTabs = function(el, options) {
// JavaScript native version of this
var base = this;
// jQuery version of this
base.$el = $(el);
// Navigation for current selector passed to plugin
base.$nav = base.$el.find(".nav");
// Returns the fragment identifier of the given URL
function getFragmentIdentifier(url) {
if(url && url.match && url.match(/#(.*)/)) {
return RegExp.$1;
}
}
// Remove the query string from the url
function noQueryString(url) {
if(url && url.match && url.match(/^([^\?]*)\??/)) {
return RegExp.$1;
}
}
// Runs once when plugin called
base.init = function() {
// Pull in arguments
base.options = $.extend({},$.organicTabs.defaultOptions, options);
// Accessible hiding fix (hmmm, re-look at this, screen readers still run JS)
$(".hide").css({
"position": "relative",
"top": 0,
"left": 0,
"display": "none"
});
// When navigation tab is clicked...
base.$nav.delegate("a", "click", function(e) {
// no hash links
e.preventDefault();
// Figure out current list via CSS class
var curList = getFragmentIdentifier(base.$el.find("a.current").attr("href")),
// List moving to
$newList = $(this),
// Figure out ID of new list
listID = getFragmentIdentifier($newList.attr("href")),
// Set outer wrapper height to (static) height of current inner list
$allListWrap = base.$el.find(".list-wrap"),
curListHeight = $allListWrap.height();
$allListWrap.height(curListHeight);
if ((listID != curList) && ( base.$el.find(":animated").length == 0)) {
// Fade out current list
base.$el.find("#"+curList).fadeOut(base.options.speed, function() {
// Fade in new list on callback
base.$el.find("#"+listID).fadeIn(base.options.speed);
// Adjust outer wrapper to fit new list snuggly
var newHeight = base.$el.find("#"+listID).height();
$allListWrap.animate({
height: newHeight
}, base.options.speed);
// Remove highlighting - Add to just-clicked tab
base.$el.find(".nav li a").removeClass("current");
$newList.addClass("current");
// Change window location to add URL params
if (window.history && history.pushState) {
// NOTE: doesn't take into account existing params
history.replaceState("", "", noQueryString(window.location.href) + "?" + base.options.param + "=" + listID);
}
});
}
});
var queryString = {};
window.location.href.replace(
new RegExp("([^?=&]+)(=([^&]*))?", "g"),
function($0, $1, $2, $3) { queryString[$1] = $3; }
);
if (queryString[base.options.param]) {
var tab = $("a[href='#" + queryString[base.options.param] + "']");
tab
.closest(".nav")
.find("a")
.removeClass("current")
.end()
.next(".list-wrap")
.find("ul")
.hide();
tab.addClass("current");
$("#" + queryString[base.options.param]).show();
};
};
base.init();
};
$.organicTabs.defaultOptions = {
"speed": 300,
"param": "tab"
};
$.fn.organicTabs = function(options) {
return this.each(function() {
(new $.organicTabs(this, options));
});
};
})(jQuery);
We have a website using an obsolete e-commerce CMS, really ties my hands behind my back because of it's lack of options and my beginner ability with JS and jQ.
On this site, we need to hide Prices and Add to Cart buttons if the user is not logged in. I have a script that has worked for me in the past that checks the users cookies. But after editing this script for the new site, it proves to not work.
I am probably messing up something very simple in the syntax, so if someone can take a quick look at my script and let me know where I am going wrong that would be great!
<script type="text/javascript">
function DisplayAuthorizedContent(name) {
var cookies=document.cookie;
var start = cookies.indexOf(name + "=");
var name = "";
var start1;
var end1;
var tmp;
var signed_in = -1;
if (start != -1) {
start = cookies.indexOf("=", start) +1;
var end = cookies.indexOf("|", start);
if (end != -1) {
signed_in = cookies.indexOf("|yes", start);
name = unescape(cookies.substring(start,end-1));
if (signed_in != -1) {
$('.loginFilter').show();
}
}
}
if (signed_in == -1) {
$('.loginFilter').empty();
$('.addMessage').each(function(){
$(this).append('Requires Wholesale Account to Purchase.<br><br><a href=\"#\" class=\"applyLink\">Apply Here<\/a>');
$(this).show();
});
}
}
DisplayAuthorizedContent("ss_reg_000778370");
</script>
The HTML
<div class="loginFilter addMessage">Add to Cart Example</div>
Sounds like the button might not be hidden on page load.
Guessing you'd need something like jQuery:
$('.loginFilter').hide();
you can hide the button with javascript (you'd have to add the id = 'button' to HTML)
document.getElementById('button').style.visibility = 'hidden';
here are some hide/show references:
http://www.w3schools.com/jquery/jquery_hide_show.asp
Hiding a button in Javascript
I'm trying to set up a website that loads pages through ajax calls replacing the current contents of with the ajax response. I'm putting a # and a page name at the end of my URLs so that people can book mark pages.
www.examplesite.com#home
www.examplesite.com#examples
www.examplesite.com#examples/example1
www.examplesite.com#examples/example2
I'm new to jQuery and to a lesser extent JavaScript but I'm trying to get a different page animation when I go to a page that is stored in a sub folder. fadeIn() works fine on both pages and pages in sub-folders however I can't get .slideDown() or .animate() to work at all. Here is an extract from my code:
<script>
//All pages are stored in a folder called 'pages' or a subfolder of 'pages'
$(document).ready(function(){
var myUrl = $(location).attr('href');
var noPage = myUrl.indexOf('#');
if(noPage == -1) {
location.hash = 'home';
}
window.onhashchange = function() {
pageChange();
}
function pageChange() {
var myUrl = $(location).attr('href');
var page = myUrl.substring(myUrl.indexOf('#') + 1, myUrl.length);
$.get('pages/' + page + '.html', function(pageHtml) {
if (page.indexOf('/') != -1) {
$('.main').hide().html(pageHtml).slideDown(400);
} else {
$('.main').hide().html(pageHtml).fadeIn(400);
}
});
};
pageChange();
});
</script>
If I'm approaching this from completely the wrong direction and that's why it's not working do feel free to point me in the correct direction by giving me an example of how it should work.
Got it!
I was using the css min-height property with a couple of my divs so that the page would expand automatically with the content if there was a lot on the page. If I remove the min-height property and replace it with a fixed height .slideDown() works fine.
Here are some links for more info if anyone else has the same issue:
http://www.only10types.com/2011/09/jquery-slidedown-doesnt-work-on.html
http://docs.jquery.com/Tutorials:Getting_Around_The_Minimum_Height_Glitch
I would take this...
if (page.indexOf('/') != -1) {
$('.main').hide().html(pageHtml).slideDown(400);
} else {
$('.main').hide().html(pageHtml).fadeIn(400);
}
And rearrange it to make sure your if statement is correct
if (page.indexOf('/') != -1) {
$('.main').hide().html(pageHtml).fadeIn(400);
} else {
$('.main').hide().html(pageHtml).slideDown(400);
}
If it now slides instead of fades, the if statement is corrupt
What about this ? Does this work ?
var main_div=$('.main');
main_div.hide();
$.get('pages/' + page + '.html', function(pageHtml) {
if (page.indexOf('/') != -1) {
main_div.html(pageHtml)
} else {
main_div.html(pageHtml)
}
});
main_div.slideDown(400);
maybe something in the CSS must be blocking it ? try disabling the CSS for the main class and try again ?
I would like to be able to automatically change links into affiliate links automatically on my MediaWiki installation. This would help to reduce the amount of time managing links in case the code needs to be changed in the future.
This is the setup of my GOG.com affiliate scheme: I need to append this key to the end of every GOG.com link: ?pp=708a77db476d737e54b8bf4663fc79b346d696d2
gog.com/en/gamecard/baldurs_gate_the_original_saga/?pp=708a77db476d737e54b8bf4663fc79b346d696d2
Is it possible for a piece of code, like Javascript, to intercept all links (like http://www.gog.com/en/gamecard/baldurs_gate_the_original_saga/) and append the affiliate code on the end, as in the above example?
I'm aware of this piece of Javascript code called Amazon Associate Link Localiser which does a similar thing. However, it only works for Amazon links, and it also localises links which is a feature I don't want.
Right way is to use LinkerMakeExternalLink mediawiki hook like that ( you can put it at bottom of your LocalSettings.php:
$wgHooks['LinkerMakeExternalLink'][] = 'ExampleExtension::exampleLinkerMakeExternalLink';
class ExampleExtension {
public static function exampleLinkerMakeExternalLink( &$url, &$text, &$link, &$attribs, $linktype ) {
if( strpos( $url, 'gog.com') !== false ) {
$url .= '?pp=708a77db476d737e54b8bf4663fc79b346d696d2';
}
return false;
}
}
Not sure how great it would be performance wise for hundreds of links.
// Plain Javascript
var links = document.getElementsByTagName('a');
for (var i = 0, max = links.length; i < max; i++) {
var _href = links[i].href;
if (_href.indexOf('gog.com') !== -1) {
links[i].href = _href + '?pp=708a77db476d737e54b8bf4663fc79b346d696d2';
}
}
DEMO
So you can also use jquery to bind any link click. This way you can do your link eval on the fly. This jsfiddle is a rough run through of what i think you're trying to accomplish. The alerts are just for your benefit and should be removed.
$("a").click(function() {
addAffiliate(this);
});
myCode = "?pp=708a77db476d737e54b8bf4663fc79b346d696d2";
myAmazonCode = "?tag=shihac-20"
function addAffiliate(link) {
alert("enterting script: " + link.href);
if ((link.href).indexOf("gog.com") > -1 && (link.href).indexOf(myCode) < 0) {
link.href = link.href + myCode;
}else if((link.href).indexOf("amazon.com") > -1 && (link.href).indexOf(myAmazonCode) < 0){
link.href = link.href + myAmazonCode;
}
alert(link.href);
return true;
}
http://jsfiddle.net/du47b/23/
UPDATE: added code and fully qualified paths
UPDATE: added 'else if' block for other codes. using 'else if' instead of just another if block will hopefully cut back on unnecessary processing.
I am using Jscrollpane and everything works great, except when I try to use it with an internal anchor.
It should work like the example on the official page.
But in my example it really destroys my site. The whole content is floating upwards and I can't figure it out myself.
Here is my page: http://kunden.kunstrasen.at/htmltriest/index.php?site=dieanreise&user_lang=de
and if the inner anchor is clicked: http://kunden.kunstrasen.at/htmltriest/index.php?site=dieanreise&user_lang=de#westautobahn
Anybody a clou whats going on here?
Thanks for your help.
jspane does not work with old style anchors
e.g.
<a name="anchor"></a>
instead you have to write
<a id="anchor"></a>
additionaly you have to enable
hijackInternalLinks: true;
in jScrollPane settings Object.
The hijackInternalLinks also captures links from outside the scrollpane, if you only need internal links you can add this code, like hijackInternalLinks it binds the click funktion on the a elements and calls the scrollToElement with the target:
\$(document).ready(function() {
panes = \$(".scroll");
//hijackInternalLinks: true;
panes.jScrollPane({
});
panes.each(function(i,obj){
var pane = \$(obj);
var api = pane.data('jsp');
var links = pane.find("a");
links.bind('click', function() {
var uriParts = this.href.split('#');
if (uriParts.length == 2) {
var target = '#' + uriParts[1];
try{
api.scrollToElement(target, true);
}catch(e){
alert(e);
}
return false;
}
});
});
});
but note you will always have to use the id attribute on a tags.
If you are using tinymce you can repair the code with this function
function myCustomCleanup(type, value) {
switch (type) {
case "get_from_editor_dom":
var as = value.getElementsByTagName("a");
for(var i=0; i< as.length;i++){
if (as[i].hasAttribute('name')){
var name = as[i].getAttribute('name');
as[i].setAttribute('id',name);
}
}
break;
}
return value;
}