I'm trying to navigate between list items with the following structure using keyboard arrow keys - help appreciated
I rather not paste my own code here as it has a lot of attributes that is not have anything to do with the problem. I could possibly add a class on each selected item?
<div class="card-columns">
<div class="card">
<div class="card-body">
<ul class="card-list">
<a href="#">
<li>Card Item1</li>
</a>
<a href="#">
<li>Card Item2</li>
</a>
<a href="#">
<li>Card Item3</li>
</a>
</ul>
</div>
</div>
<div class="card">
<div class="card-body">
<ul class="card-list">
<a href="#">
<li>Card Item3</li>
</a>
<a href="#">
<li>Card Item4</li>
</a>
<a href="#">
<li>Card Item5</li>
</a>
</ul>
</div>
</div>
</div>
Place all the li elements into a collection and set up a tracking variable.
Then set up a keydown event handler for the document that alters the tracker variable based on which key was pressed and apply styling to the element that has an index in its collect that matches the tracking variable.
See comments inline below for details:
// Get all the <li> elements into a collection
var listItems = document.querySelectorAll(".card-list li");
// Set up a counter to keep track of which <li> is selected
var currentLI = 0;
// Initialize first li as the selected (focused) one:
listItems[currentLI].classList.add("highlight");
// Set up a key event handler for the document
document.addEventListener("keydown", function(event){
// Check for up/down key presses
switch(event.keyCode){
case 38: // Up arrow
// Remove the highlighting from the previous element
listItems[currentLI].classList.remove("highlight");
currentLI = currentLI > 0 ? --currentLI : 0; // Decrease the counter
listItems[currentLI].classList.add("highlight"); // Highlight the new element
break;
case 40: // Down arrow
// Remove the highlighting from the previous element
listItems[currentLI].classList.remove("highlight");
currentLI = currentLI < listItems.length-1 ? ++currentLI : listItems.length-1; // Increase counter
listItems[currentLI].classList.add("highlight"); // Highlight the new element
break;
}
});
.highlight { background-color:#ff0; }
<div class="card-columns">
<div class="card">
<div class="card-body">
<ul class="card-list">
<a href="#">
<li>Card Item1</li>
</a>
<a href="#">
<li>Card Item2</li>
</a>
<a href="#">
<li>Card Item3</li>
</a>
</ul>
</div>
</div>
<div class="card">
<div class="card-body">
<ul class="card-list">
<a href="#">
<li>Card Item3</li>
</a>
<a href="#">
<li>Card Item4</li>
</a>
<a href="#">
<li>Card Item5</li>
</a>
</ul>
</div>
</div>
</div>
Your question is quite vague, without seeing what you have done I can only recommend that you should look into the use of Javascript and the onkeypress() event handler.
You can get a list of your <a> tags by giving them all a class, lets call it "cardATags".
var aList = document.querySelectorAll(".cardATags");
We will start the page at an index of 0.
var index = 0;
and set them to the currently focused item with something like
aList[index].focus();
Now in your onkeypress() event handler you can increment the index and set the next focused item.
Good luck.
A bit of clarification, add classes to your code like so:
<div class="card-columns">
<div class="card">
<div class="card-body">
<ul class="card-list">
<a class="cardATags" href="#">
<li>Card Item1</li>
</a>
<a class="cardATags" href="#">
<li>Card Item2</li>
</a>
<a class="cardATags" href="#">
<li>Card Item3</li>
</a>
</ul>
</div>
</div>
<div class="card">
<div class="card-body">
<ul class="card-list">
<a class="cardATags" href="#">
<li>Card Item3</li>
</a>
<a class="cardATags" href="#">
<li>Card Item4</li>
</a>
<a class="cardATags" href="#">
<li>Card Item5</li>
</a>
</ul>
</div>
</div>
</div>
$('li').eq(0).addClass('active')
$('.cardATags').eq(0).focus();
$(document).keydown(function(e) {
var li_count=$('li').length;
var curent_active=0;
var each_counter=0;
$('li').each(function(){
if( $(this).hasClass('active')){
curent_active=each_counter;
}
each_counter++;
});
if(e.keyCode == 37) { // left
curent_active-=1;
}else if(e.keyCode == 39) { // right
curent_active+=1;
}if(e.keyCode == 38) { // top
curent_active-=1;
}if(e.keyCode == 40) { // bott
curent_active+=1;
}
if(curent_active==li_count){
curent_active=0;
}
$('li').removeClass('active');
$('li').eq(curent_active).addClass('active');
});
.active{
background-color:gray;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Press UP or DOWN or LEFT or RIGHT arrows...
<div class="card-columns">
<div class="card">
<div class="card-body">
<ul class="card-list">
<a href="#">
<li>Card Item1</li>
</a>
<a href="#">
<li>Card Item2</li>
</a>
<a href="#">
<li>Card Item3</li>
</a>
</ul>
</div>
</div>
<div class="card">
<div class="card-body">
<ul class="card-list">
<a href="#">
<li>Card Item3</li>
</a>
<a href="#">
<li>Card Item4</li>
</a>
<a href="#">
<li>Card Item5</li>
</a>
</ul>
</div>
</div>
</div>
This may not be what you are looking for, but someone else may find my solution helpful. Given the following list:
<ul class="dropdown-menu" id="my_ul" >
<li tabindex="0"> Project 1 </li>
<li tabindex="0"> Project 2 </li>
<li tabindex="0"> Project 3 </li>
</ul>
There were 2 things I needed to do to get this working:
add tabindex="0" to each of the <li> - this allows the list element to be focusable (and thus allowing you to use the arrow keys to navigate)
I used jQuery on a down arrow event to move the focus on to the first <a> tag of the first <li> of the wrapper <ul> e.g. jQuery("#my_ul > li > a").first().focus(); (where my_ul is the id of the wrapper <ul>). In my case, unlike yours, I put the <a> tags inside the <li> - not sure if that makes a difference, but thought it worth mentioning.
Related
This question already has answers here:
JavaScript: How to get parent element by selector?
(11 answers)
Closed 1 year ago.
I tried to make a code to remove a li from ul but I would like to be more specific.
I would like to find exact anchor link before removing it along with the li it contains.
In the example below, I want to remove only Another link.
My code so far looks like:
<ul class="working-list">
<li class="work color1">
<a href="?c=Some link 1">
<span class="title">
link 1</span>
</a>
</li>
<li class="work color1">
<a href="?c=someLink2"><span class="title">
Some link 2</span>
</a>
</li>
<li class="work color1">
<a href="?c=anotherLink"><span class="title">
Another link</span>
</a>
</li>
<li class="work color1">
<a href="?c=SmallLink"><span class="title">
Small link</span>
</a>
</li>
</ul>
And the script so far:
let pickEl = document.querySelectorAll('.working-list li');
// let pickA = document.querySelector('a[href=\'?c=anotherLink\']');
console.log(pickEl);
pickEl[3].remove();
What would be the best approach?
You can try using Attribute selectors selector:
let pickEl = document.querySelector('.working-list li a[href="?c=anotherLink"]');
console.log(pickEl);
//remove the parent li
pickEl.closest('li').remove();
<ul class="working-list">
<li class="work color1">
<a href="?c=Some link 1">
<span class="title">link 1</span>
</a>
</li>
<li class="work color1">
<a href="?c=someLink2">
<span class="title">Some link 2</span>
</a>
</li>
<li class="work color1">
<a href="?c=anotherLink">
<span class="title">Another link</span>
</a>
</li>
<li class="work color1">
<a href="?c=SmallLink">
<span class="title">Small link</span>
</a>
</li>
</ul>
You can forEach the pickEl then see textContent like:
let pickEl = document.querySelectorAll('.working-list li');
const deleteText = 'Another link';
pickEl.forEach(el =>{
const a = el.querySelector('a');
if(a.textContent.trim() === deleteText){
el.remove();
}
});
<ul class="working-list">
<li class="work color1">
<a href="?c=Some link 1">
<span class="title">
link 1</span>
</a>
</li>
<li class="work color1">
<a href="?c=someLink2"><span class="title">
Some link 2</span>
</a>
</li>
<li class="work color1">
<a href="?c=anotherLink"><span class="title">
Another link</span>
</a>
</li>
<li class="work color1">
<a href="?c=SmallLink"><span class="title">
Small link</span>
</a>
</li>
</ul>
How can I prevent anchor (<a>) tag from doing nothing if li has ul according to the following code:
<aside class="sidebar">
<div id="leftside-navigation" class="nano">
<ul class="nano-content">
<li>
<a href="index.html">
<span>Home</span>
</a>
</li>
<li class="sub-menu">
<a href="javascript:void(0);">
<span>Categories</span>
<i class="arrow fa fa-angle-right pull-right"></i>
</a>
<ul>
<li>
<a href="index.html">
<span>Home</span>
</a>
</li>
<li>
<a href="index.html">
<span>Lifestyles</span>
</a>
</li>
<li>
<a href="index.html">
<span>Technology</span>
</a>
</li>
</ul>
</li>
</ul>
</div>
I've tried to put javascript:void(0) - it works but I wanted to make it with if else statement or any other way.
I wanted to do that is:
if li.submenu has ul li.has-submenu a prevent default
You can write a selector for a that's a child of an li that has a submenu.
$("li:has(ul) > a").click(function(e) {
e.preventDefault();
});
Another approach would be to not include the <a> tag in general. Just write the the text "Categories" within the <li class="sub-menu> and it will display in menu as normal.
Example:
<li class="sub-menu">
<span>Categories</span>
<i class="arrow fa fa-angle-right pull-right"></i>
<ul>
<li>......
Although you would need to add CSS if you want the cursor to change or if you want the text to be underlined for your <span> etc...
You can also try this.
$("li").find("ul > a").click(function(e) {
e.preventDefault();
});
I have the following HTML:
<div class="pagination pagination-centered">
<ul>
<li class="active">
<a class="page" data-page="1" href="javascript:void(0)">
1 </a>
</li>
<li >
<a class="page" data-page="2" href="javascript:void(0)">
2 </a>
</li>
<li >
<a class="page" data-page="3" href="javascript:void(0)">
3 </a>
</li>
<li >
<a class="page" data-page="4" href="javascript:void(0)">
4 </a>
</li>
<li >
<a class="page" data-page="5" href="javascript:void(0)">
5 </a>
</li>
<li >
<a class="page" data-page="6" href="javascript:void(0)">
6 </a>
</li>
<li >
<a class="page" data-page="7" href="javascript:void(0)">
7 </a>
</li>
<li >
<a class="page" data-page="8" href="javascript:void(0)">
8 </a>
</li>
<li class="threeDots">
<a class="page" data-page="..." href="javascript:void(0)">
... </a>
</li>
<li >
<a class="page" data-page="20" href="javascript:void(0)">
20 </a>
</li>
</ul>
</div>
When I click in this buttons I go to something like this www.example.com/something?page=X (x = number of the button)
I use this:
Document doc = Jsoup.connect("www.example.com/something?page=5").get();
But I get always the first page HTML.
How I can "click" or extract information about this pages? I don't know so much about PHP but I think this page use it to change pages.
Edit:
I'm not using javascript. I'm using a java project that extract information from page using html.
It seems you need to dynamically set the page URL argument. If you use jQuery you should be able to have a click event like this:
Document doc = Jsoup.connect("www.example.com/something?page=" + $(this).data('page')).get();
Only a single digit gets changed for every link, you can use for loop with a variable denoting your page number as follows:
for (int i = 1; i <= 8; i++) {
Document doc = Jsoup.connect("www.example.com/something?page=" + i).get();
/* Your code for each page*/
}
This question already has an answer here:
Wrong target when pressing html button with html tags in it
(1 answer)
Closed 4 years ago.
So I have my html like so:
<ul id="page-nav">
<li class="text-muted menu-title">Navigation</li>
<li>
<a href="#" class="waves-effect active">
<img src="img/archive.svg" alt="archive"><span class="menu-spans"> Dashboard </span>
</a>
</li>
<li>
<a href="#" class="waves-effect">
<img src="img/speech-bubble.svg" alt="speech"><span class="menu-spans"> Chat </span>
</a>
</li>
<li>
<a href="#" class="waves-effect">
<img src="img/gains.svg" alt="speech"><span class="menu-spans"> Gains </span>
</a>
</li>
</ul>
When a user clicks on any of the element within the li, I would like to add a class to the li.
How can this be done in pure JavaScript?
My initial thought was the following:
document.getElementById("page-nav").addEventListener(
"click", i => {
// debug purposes
console.log(this.parentNode);
}
);
But it dont work.
you can do that using currentTarget in js .I'm added the snippet below(here I'm added the class .red to corresponding li when click on the sub items)
var k = document.getElementsByClassName("item");
for(i = 0 ;i < k.length; i++)
{
k[i].addEventListener("click",function(event){
var el = event.currentTarget;
var value = el.id;
document.getElementById(value).classList.add ("red");
});
}
.red{
background:red;
}
<ul id="page-nav">
<li class="text-muted menu-title">Navigation</li>
<li class="item" id="one">
<a href="#" class="waves-effect active">
<img src="img/archive.svg" alt="archive"><span class="menu-spans"> Dashboard </span>
</a>
</li>
<li class="item" id="two">
<a href="#" class="waves-effect">
<img src="img/speech-bubble.svg" alt="speech"><span class="menu-spans"> Chat </span>
</a>
</li>
<li class="item" id="three">
<a href="#" class="waves-effect">
<img src="img/gains.svg" alt="speech"><span class="menu-spans"> Gains </span>
</a>
</li>
</ul>
I'm trying to create a breadcrumb for my web application.
I have the following navigation menu within my .JSP file:
<nav class="nav">
<ul class="wrap">
<li class="menu-nav--home"><span class="icon-home"></span></li>
<ul>
<li>Business</li>
<li>Search</li>
<li>Search Deatils</li>
<li>Change Records</li>
<li>Remove</li>
<li>Order Deatils</li>
<li>Checkout</li>
</ul>
</li>
</ul>
</nav>
..And i have attempted to create a breadcrumb using HTML5 Microdata as per below:
<div class="breadcrumb">
<div class="wrap">
<ol class="menu menu--hor">
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
<a href="/home" itemprop="url">
<span itemprop="title">Home</span>
</a>
</li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
<a href="/business" itemprop="url">
<span itemprop="title">Business</span>
</a>
</li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
<a href="/search" itemprop="url">
<span itemprop="title">Search</span>
</a>
</li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
<a href="/details" itemprop="url">
<span itemprop="title">Details</span>
</a>
</li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
<a href="/update" itemprop="url">
<span itemprop="title">Update</span>
</a>
</li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
<a href="/delete" itemprop="url">
<span itemprop="title">Delete</span>
</a>
</li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
<a href="/order" itemprop="url">
<span itemprop="title">New Order</span>
</a>
</li>
<li itemscope itemtype="http://data-vocabulary.org/Breadcrumb">
<a href="/checkout" itemprop="url">
<span itemprop="title">Checkout</span>
</a>
</li>
</ol>
</div>
</div>
My issue is, all items on the breadcrumb are being displayed, when, i only want the current location to be displayed.
Current display:
Home Business Search Details Update Delete New Order Checkout
Preferred Display (when on Checkout page, for example)
Home > Checkout
Any help is appreciated.
Thanks
UPDATE - 24/07/13
So, after a bit of Googling, it was clear some JS was missing, here is a first attempt.
// Bread crumb script /////////////
var path = "";
var href = document.location.href;
var s = href.split("/");
for (var i=2;i<(s.length-1);i++) {
path+=""+s[i]+" / ";
}
i=s.length-1;
path+=""+s[i]+"";
var url = window.location.protocol + "//" + path;
document.writeln(url);
Which does appear to retrieve the current page/site.. however, does not place it below my Nav menu but rather in a new page that seems to crash my site.
Do it need some form of .append on a new DIV ?