I am using anchor links (on my main menu) to scroll to a tab module and open the correct tab.
I have some code that works well but with one issue.
If there is an anchor link inside the tab then the code will no longer scroll to that tab (although it does open).
Test site here. First 2 tabs have no anchor link inside and work fine. Last 3 tabs have anchor links and have lost their scroll.
Can anyone see any red flags or issues in the code that might be causing this behaviour?
Thanks
<script type="text/javascript">
(function($) {
$( document ).ready(function() {
$('.et_mobile_menu li a').click(function(){
$('.et_slide_in_menu_container .mobile_menu_bar').trigger('click');
console.log('done');
});
});
})(jQuery);
function _setTab(){
// get current hash value
var curHash = window.location.hash.substr(1);
// only continue if hash provided and scoped to member tabs
if( !curHash || !curHash.match('my-tabs') ){ return false; }
// split and int val tab num
curHash = parseInt(curHash.split('|')[1]);
// ignore if tab is current state
if( curHash === window._tabSelected ){ return false; }
// set current tab to window
window._tabSelected = curHash;
// add click event to tab selected
switch(curHash){
case 0:
case 1:
case 2:
case 3:
case 4:
jQuery('#my-tabs .et_pb_tab_'+curHash+' a').trigger('click');
break;
default:
return false;
break;
}
// scroll to tabs container
_scrollToTabs();
}
// scroll to member tabs container with 50px offset
function _scrollToTabs(){
var oTabs = jQuery('#my-tabs');
if( oTabs.length > 0 ){
jQuery('html,body').animate({
scrollTop: (oTabs.offset().top - 50)
}, 1000);
}
return false;
}
// set falsey state for tab selected on load
window._tabSelected = false;
// attach to window load because the tabs functions are initialized later in document
jQuery(window).on('load', function(){
// check for initial hash state
_setTab();
// add hash change window listener
jQuery(window).on('hashchange', function(){
_setTab()
});
// void submenu when we are in member section
var curPath = window.location.pathname;
if( curPath.match('midtown') ){
// only change hash and do not reload page
jQuery('#menu-item-665 ul li a').on('click', function(e){
e.stopImmediatePropagation();
window.location.hash = jQuery(this).prop('hash');
return false;
});
}
});
Found the issue. Was not correctly calling the right div container in the click event;
// add click event to tab selected
switch(curHash){
case 0:
jQuery('#my-tabs .et_pb_tabs_controls .et_pb_tab_'+curHash+' a').click();
break;
case 1:
jQuery('#my-tabs .et_pb_tabs_controls .et_pb_tab_'+curHash+' a').click();
break;
case 2:
jQuery('#my-tabs .et_pb_tabs_controls .et_pb_tab_'+curHash+' a').click();
break;
case 3:
jQuery('#my-tabs .et_pb_tabs_controls .et_pb_tab_'+curHash+' a').click();
break;
case 4:
jQuery('#my-tabs .et_pb_tabs_controls .et_pb_tab_'+curHash+' a').click();
break;
default:
return false;
break;
}
Related
I am trying to get anchor links to open up tabs on a specific page.
Solutions like the one found on https://jonathanbossenger.com/using-anchor-links-to-open-accordions-and-tabs-in-divi/ only work when the anchor link is on the same page as the tabs.
I found a different thread on Stack that addressed this issue, but it had the finalized solution ironed out in a chat I don't have access to (Wordpress Divi Theme - Anchor link opens tab toggle).
I can see on their website that they were able to get it to work (https://www.elkodowntown.org/our-members/#member-tabs|3).
How can I access the site code of Elko Downtown to find the final version of the JavaScript below that got it to work?
jQuery(function($) {
$('.menu-item-179 a').on('click', function(event){
tabScroll('.et_pb_tab_0');
return false;
});
$('.menu-item-180 a').on('click', function(event){
tabScroll('.et_pb_tab_1');
return false;
});
$('.menu-item-181 a').on('click', function(event){
tabScroll('.et_pb_tab_2');
return false;
});
$('.menu-item-182 a').on('click', function(event){
tabScroll('.et_pb_tab_3');
return false;
});
$('.menu-item-183 a').on('click', function(event){
tabScroll('.et_pb_tab_4');
return false;
});
function tabscroll(target) {
$("html, body").animate({ scrollTop: $('#member-tabs').offset().top }, 1000);
setTimeout($('#member-tabs' + target + ' a').click(), 2000 );
}
$(function hash() {
var hash = window.location.hash.replace('#', "");
if (hash == '#shop') { tabscroll('.et_pb_tab_1'); }
if (hash == '#service') { tabscroll('.et_pb_tab_0'); }
if (hash == '#eat-drink') { tabscroll('.et_pb_tab_2'); }
if (hash == '#arts-entertainment') { tabscroll('.et_pb_tab_3'); }
if (hash == '#stay') { tabscroll('.et_pb_tab_4'); }
});
});
Every line of javascript transmitted over the web is visible by inspecting the browser. If all you're looking to do is see what they're finalized code is look below.
However, if you're using WP and trying to do things using JS/JQuery I strongly urge you to learn how to do the functions outside of WP first and understand what's going on, the code you take from will not always match your page structure/elements and you'll always wonder why things don't work.
Here's the code that's doing it for them:
function _setTab(){
// get current hash value
var curHash = window.location.hash.substr(1);
// only continue if hash provided and scoped to member tabs
if( !curHash || !curHash.match('member-tabs') ){ return false; }
// split and int val tab num
curHash = parseInt(curHash.split('|')[1]);
// ignore if tab is current state
if( curHash === window._tabSelected ){ return false; }
// set current tab to window
window._tabSelected = curHash;
// add click event to tab selected
switch(curHash){
case 0:
case 1:
case 2:
case 3:
case 4:
jQuery('#member-tabs .et_pb_tab_'+curHash+' a').click();
break;
default:
return false;
break;
}
// scroll to tabs container
_scrollToTabs();
}
// scroll to member tabs container with 50px offset
function _scrollToTabs(){
var oTabs = jQuery('#member-tabs');
if( oTabs.length > 0 ){
jQuery('html,body').animate({
scrollTop: (oTabs.offset().top - 50)
}, 1000);
}
return false;
}
// set falsey state for tab selected on load
window._tabSelected = false;
// we need to attach to window load because the tabs functions are initialized later in document
jQuery(window).on('load', function(){
// check for initial hash state
_setTab();
// add hash change window listener
jQuery(window).on('hashchange', function(){
_setTab()
});
// void submenu when we are in member section
var curPath = window.location.pathname;
if( curPath.match('our-members') ){
// only change hash and do not reload page
jQuery('#menu-item-98 ul li a').on('click', function(e){
e.stopImmediatePropagation();
window.location.hash = jQuery(this).prop('hash');
return false;
});
}
});
I have a simple navigation bar which I intend to use above all keyboard accessible navigation. The navigation bar is meant to work like so:
Using the Tab key, you should be able to navigate through each
navigation category and its elements.
Using Right* and **Left keys, you can navigate through the navigation categories only.
Using Down key allows you to also open a navigation category.
Using ESC key closes (hides) the currently visible navigation category.
Here is the jsFiddle I developed.
To keep things simple, please focus on the JavaScript code, as the HTML code cannot change due to requirement reasons outside my control. I believe that the issue lies in how Firefox/IE is handling the focus events differently than in Chrome.
$(document).ready(function(){
var utilitymenu = new menuBar("#utility-nav"),
navInner = new menuBar("#nav-inner"),
mainHeader = $(".main-header");
// Adding tabindex to all clickable anchor links
mainHeader.find("a").each(function(i, elem){
$(elem).attr("tabindex", i+1);
});
});
function menuBar(id){
var linksBlock = id + " > li",
linksBlockSelector = " > li",
submenuHeader = linksBlock + " > a",
submenu = linksBlock + " div[class*='sub-menu']",
submenuSelector = "div[class*='sub-menu']",
textBlock = submenu + " > ul",
textBlockSelector = submenuSelector + " > ul",
submenuElem = textBlock + " > li a",
keepMenuClosed = false;
// Adding ARIA attributes to the different sections of the navigation menus
$(linksBlock).attr({
"role": "navigation",
"aria-haspopup": "true",
"aria-labelledby": "menu-title",
"aria-describedby": "menu-description"
});
$(submenuHeader).attr({
"aria-haspopup": "true",
"id": "menu-title"
});
$(submenuHeader).each(function(i, elem){
$(elem).attr("aria-label", $(elem).text().trim());
});
$(submenu).attr({
"tabindex": "-1",
"id": "menu-description"
});
$(textBlock).attr({
"aria-expanded": "false",
"aria-hidden": "true"
});
// Hides visible menus when clicking outside the menu area
$(document).click(function(event) {
if(!$(event.target).closest().length){
$(submenu + ":visible").hide().find(textBlock).attr("aria-expanded", "false");
$(submenu + ":visible").hide().find(textBlock).attr("aria-hidden", "true");
}
});
// Drop Down Menu event handler (not inner elements)
$(linksBlock)
.focus(function(){
if($(this).find(submenuSelector).is(":hidden") && !keepMenuClosed){
$(this).find(submenuSelector).toggle();
$(this).find(textBlockSelector).attr("aria-expanded", "true");
$(this).find(textBlockSelector).attr("aria-hidden", "false");
keepDropdownClosed = false;
}
else if($(this).find(submenuSelector).is(":visible")){
$(this).find(submenuSelector).toggle();
$(this).find(textBlockSelector).attr("aria-expanded", "false");
$(this).find(textBlockSelector).attr("aria-hidden", "true");
}
})
.mouseover(function(){
$(this).find(submenuSelector).show();
$(this).find(textBlockSelector).attr("aria-expanded", "true");
$(this).siblings().find(submenuSelector).hide();
$(this).siblings().find(textBlockSelector).attr("aria-expanded", "false");
$(this).find(textBlockSelector).attr("aria-hidden", "true");
})
.mouseout(function(){
$(this).find(submenuSelector).hide();
$(this).find(textBlockSelector).attr("aria-expanded", "false");
$(this).find(textBlockSelector).attr("aria-hidden", "true");
})
.keydown(function(event){
switch(event.keyCode){
//tab key
case 9:
keepMenuClosed = true;
if($(this).find(submenuSelector).is(":visible")){
$(this).find(submenuSelector).toggle();
$(this).find(textBlockSelector).attr("aria-expanded", "false");
$(this).find(textBlockSelector).attr("aria-hidden", "true");
}
else if($(this).find(submenuSelector).is(":hidden")){
$(this).find(submenuSelector).toggle();
$(this).find(textBlockSelector).attr("aria-expanded", "true");
$(this).find(textBlockSelector).attr("aria-hidden", "false");
}
break;
// esc key
case 27:
if($(this).find(submenuSelector).is(":visible")){
$(this).find(submenuSelector).toggle();
$(this).find(textBlockSelector).attr("aria-expanded", "false");
$(this).find(textBlockSelector).attr("aria-hidden", "true");
$(this).closest(linksBlock).focus();
}
break;
// key left
case 37:
if($(this).find(submenuSelector).is(":hidden")){
$(this).prev().find(" > a").focus();
keepMenuClosed = true;
}
break;
// key right
case 39:
if($(this).find(submenuSelector).is(":hidden")){
$(this).next().find(" > a").focus();
keepMenuClosed = true;
}
break;
// key up/down
case 38, 40:
event.preventDefault();
$(this).find(submenuSelector).show();
break;
}
});
// Sub Menu Elements keyboard handler
$(submenuElem)
.keydown(function(event){
switch(event.keyCode){
// tab key
case 9:
$(this).parent().next().find("a").focus();
break;
// esc key
case 27:
if($(this).closest(submenuSelector).is(":visible")){
$(this).closest("div").siblings("a ").focus();
}
break;
// key up
case 38:
event.preventDefault();
$(this).parent().prev().find("a").focus();
break;
// key down
case 40:
event.preventDefault();
$(this).parent().next().find("a").focus();
break;
}
});
}
TLDR
All I want to do is understand why the navigation works only in Chrome, but not in IE and Firefox. What am I doing wrong/not doing at all here? I have been looking around at known issues with IE/FF focus, preventDefault but to no avail. I do not think my ARIA code is causing the problem, but I am ready to explore all suggestions!
EDIT
After #Adam's suggestion, I added the following code to show the issues I have on Firefox/IE:
$(this).keydown(function(e){
if(e.keyCode === 9){
alert($(':focus').toArray());
}
});
It showed the root of the issues. I am currently working to modify my code to better differentiate how I listen to my keyboard strokes; as well as to show better listen to when my elements are focused on.
When you hide an element, it losts the focus
When you press the tab key over a submenuElem the event is also intercepted by linksBlock
For that specific reason, when you use the following line
$(this).parent().next().find("a").focus();
it fires the focus() event and then executes the toggle which will hide the submenu. Here the focus is lost.
$(linksBlock)
.focus(function(){
[...]
else if($(this).find(submenuSelector).is(":visible")){
$(this).find(submenuSelector).toggle();
And then after that, a second event is fired to the main blocks which will show the hidden element without focus set:
$(linksBlock)
.keydown(function(event){
[...]
else if($(this).find(submenuSelector).is(":hidden")){
$(this).find(submenuSelector).toggle();
I have a following code (Code Snippet 01) to open a link. Note that I can't modify href can only use window.open or any jquery method to open the link.
For that I have used following code
$('#element').mousedown(function(event) {
switch (event.which) {
case 1:
alert('Left Mouse button pressed.');
break;
case 2:
alert('Middle Mouse button pressed.');
break;
case 3:
alert('Right Mouse button pressed.');
break;
default:
alert('You have a strange Mouse!');
}
});
From here
It works for right click and middle but on the left click instead of opening context menu it directly opens the link. Is there any way we can handle that? It open the context menu and and clicking on new tab or new window open our link?
Code Snippet 01
var $pdflink = jQuery.noConflict();
$pdflink(document).ready(function(){
$pdflink(".PRLink").click(function(e){
e.preventDefault();
var pdf = $pdflink(this).parents(".getpdflink").find(".pdflinkforlink").attr("href");
var html = $pdflink(this).parents(".getpdflink").find(".htmllink").attr("href");
if(pdf) {
window.open (
pdf, '_blank'
);
//$pdflink(this).find(".PRLink").attr("href", pdf);
} else {
window.open (
html, '_blank'
);
//$pdflink(this).find(".PRLink").attr("href", html);
}
});
This is the code I'm using as this moment for the fade out effect on all links with the class "link"
$('.link').click(function() {
event.preventDefault();
newLocation = this.href;
$('body').fadeOut(700, newpage);
});
The problem is that the middle click and/or open in a new tab doesn't work. Is there a way I can change this code so that my users both can right-click and/or middle click on these links?
to detect which from what click the event is comming, you can use that code:
$(document).mousedown(function(e){
switch(e.which)
{
case 1:
//left Click
break;
case 2:
event.preventDefault();
newLocation = this.href;
$('body').fadeOut(700, newpage);
break;
case 3:
//right Click
break;
}
return true;// to allow the browser to know that we handled it.
});
$('.link').click(function(e) {
var clicked = e.which;
// 1 = left click, 3 = right click
if (clicked !== 1 || clicked !== 3) {
e.preventDefault();
newLocation = this.href;
$('body').fadeOut(700, newpage);
}
});
when I hit "enter" to choose an item from the jquery-autocomplete results, the form submits. Why this happens....
i should get the data in the text field and on second enter the form should submit...
please suggest where to change in autocomplete.js
Thanks in advance
try this:
Find the keydown event on the li, in the autocomplete.js file and then place this line at the end of the keydown`s event handler (it may have some switch statement, you are interested about the 13[ enter key code]),:
return false;
ex:
.keydown(function(e) {
// track last key pressed
lastKeyPressCode = e.keyCode;
switch(e.keyCode) {
case 38: // up
e.preventDefault();
moveSelect(-1);
break;
case 40: // down
e.preventDefault();
moveSelect(1);
break;
case 9: // tab
case 13: // return
if( selectCurrent() ){
// make sure to blur off the current field
$input.get(0).blur();
e.preventDefault();
return false; // ADD THIS !
}
break;
default:
active = -1;
if (timeout) clearTimeout(timeout);
timeout = setTimeout(function(){onChange();}, options.delay);
break;
}
})
this will stop the event to further propagate and submit the form.