We are using MDC menu component. I am looking for a way to not close the menu when clicked on the first item in the menu.
I tried applying a class to mdc-list-item and specifying cursor as auto, but it is not working.
.menu-do-not-close {
cursor: auto !important;
}
below is the example fiddle
https://jsfiddle.net/phani25485/Lt6q2gxa/2/
Could you provide some direction on how to achieve this.
You can stop the menu from closing after a specific item is selected by calling event.stopPropagation() on the mdc-list-item click event when the event target has a specific class assigned. You will need to add some additional code to handle the list item click event since this prevents the normal MDC menu click handling.
const menu = mdc.menu.MDCMenu.attachTo(document.querySelector('.mdc-menu'));
document.querySelector('.mdc-button').addEventListener('click', () => {
menu.open = !menu.open;
});
//Prevent menu close when option with 'prevent-menu-close' class clicked
for (const option of document.querySelectorAll('.mdc-list-item')) {
option.addEventListener('click', (event) => {
const prevent = event.currentTarget.classList.contains('prevent-menu-close');
if (prevent) {
event.stopPropagation();
// handle 'prevent-menu-close' list item click event
}
});
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Material Select</title>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700">
<link href="https://unpkg.com/material-components-web#latest/dist/material-components-web.min.css" rel="stylesheet">
<script src="https://unpkg.com/material-components-web#latest/dist/material-components-web.min.js"></script>
</head>
<body>
<div class="mdc-menu-surface--anchor">
<button class="mdc-button">
<span class="mdc-button__label">Open Menu</span>
</button>
<div class="mdc-menu mdc-menu-surface">
<ul class="mdc-list" role="menu" aria-hidden="true" aria-orientation="vertical" tabindex="-1">
<li class="mdc-list-item prevent-menu-close" role="menuitem">
<span class="mdc-list-item__text">Prevent Close</span>
</li>
<li class="mdc-list-item" role="menuitem">
<span class="mdc-list-item__text">Another Menu Item</span>
</li>
</ul>
</div>
</div>
</body>
</html>
Related
I am kinda new to website development, so I am asking for some help on the matter. I have the following snippet of html
<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://code.jquery.com/jquery-1.10.2.js"></script>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<!--CSS Styles -->
<link rel="stylesheet" href="../assets/css/styles.css"/>
</head>
<body>
<!--Navigation bar-->
<div id="nav-placeholder"></div>
<!--end of Navigation bar-->
</body>
<script src="../assets/js/navigation_bar.js" type="text/javascript", locator="about"></script>
</html>
It calls the navigation_bar.js script provided here
locator = document.currentScript.getAttribute('locator');
function changeActiveElement(element_id){
console.log("Called");
nav_element = document.getElementById("navigation");
for (i = 0; i < nav_element.length; i++) {
console.log(nav_element[i].id)
if(nav_element[i].id == element_id) document.getElementById(element_id).className = "active-nav-link";
else document.getElementById(element_id).className = "nav-link";
}
}
$(function()
{$("#nav-placeholder").load("/assets/html/nav.html", function(){
changeActiveElement(locator);
});}
);
whereas the nav.html file is here:
<nav>
<h1>Some name</h1>
<ul id="navigation" class="navigation">
<li><a id="about" href="/pages/about.html" class="nav-link">About</a></li>
<li><a id="compt" href="#compt" class="nav-link">Competences</a></li>
<li><a id="projects" href="#projects" class="nav-link">Projects</a></li>
<li><a id="contact" href="#contact" class="nav-link">Contact</a></li>
</ul>
<button class="burger-menu" id="burger-menu">
<ion-icon class="bars" name="menu-outline"></ion-icon>
</button>
</nav>
The scope of the snippet is to change the class of the a tags listed in the navigation element. The navigation bar is correctly loaded via $("#nav-placeholder").load("/assets/html/nav.html"), yet changeActiveElement function is never executed via the callback.
Can someone explain me this behaviour?
I tested your code and everything is working except that nav_element is not a list and therefore nav_element.length throws an error. You could use document.querySelectorAll("#navigation"); instead, which returns a node list of all selected elements. Although, I would not recommend doing a for loop on elements by id. Use classes to select the elements. Id is only for one element.
This question already has answers here:
Why is simple JavaScript code not running?
(3 answers)
Closed 1 year ago.
I'm trying to get a JS slider to work. I'm using Brackets as my code environment.
I have tried creating a local .js file and putting
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js">
<script type="text/javascript" src="my.js"></script>
line in <head>
I have also tried just putting only <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"> in <head> and then putting all of the script code within a <script> tag in <head>.
CodePen for that:
https://codepen.io/hiarooo/pen/zYNboJq
As you can see, the slider doesn't function properly.
However, I have noticed that if I simply put the code in the JS box of CodePen (I have commented it, but you can try uncommenting it to see what I mean) then the Slider functions perfectly.
What is wrong with the way I am doing things? I do not understand.
Thank you for any advice.
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Crypter | Upload01</title>`enter code here`
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=Poppins&display=swap" rel="stylesheet">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css2?family=DM+Sans:wght#700&display=swap" rel="stylesheet">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<!--<script type="text/javascript" src="my.js"></script>-->
</head>
<body>
<section class="section-slider">
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet">
<link href='https://fonts.googleapis.com/css?family=Anton' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Neucha' rel='stylesheet' type='text/css'>
<div id="wrapper">
<div id="slider-wrap">
<ul id="slider">
<li data-color="#1abc9c">
<div>
<h3>What is cat</h3>
<span>it is a cat</span>
</div>
<i></i>
</li>
<li data-color="#3498db">
<div>
<h3>Slide #2</h3>
<span>Sub-title #2</span>
</div>
<i class="fa fa-gears"></i>
</li>
<li data-color="#9b59b6">
<div>
<h3>Slide #3</h3>
<span>Sub-title #3</span>
</div>
<i class="fa fa-sliders"></i>
</li>
<li data-color="#34495e">
<div>
<h3>Slide #4</h3>
<span>Sub-title #4</span>
</div>
<i class="fa fa-code"></i>
</li>
<li data-color="#e74c3c">
<div>
<h3>Slide #5</h3>
<span>Sub-title #5</span>
</div>
<i class="fa fa-microphone-slash"></i>
</li>
</ul>
<!--controls-->
<div class="btns" id="next"><i class="fa fa-arrow-right"></i></div>
<div class="btns" id="previous"><i class="fa fa-arrow-left"></i></div>
<div id="counter"></div>
<div id="pagination-wrap">
<ul>
</ul>
</div>
<!--controls-->
</div>
</div>
</section>
<script>
//current position
var pos = 0;
//number of slides
var totalSlides = $('#slider-wrap ul li').length;
//get the slide width
var sliderWidth = $('#slider-wrap').width();
$(document).ready(function(){
/*****************
BUILD THE SLIDER
*****************/
//set width to be 'x' times the number of slides
$('#slider-wrap ul#slider').width(sliderWidth*totalSlides);
//next slide
$('#next').click(function(){
slideRight();
});
//previous slide
$('#previous').click(function(){
slideLeft();
});
/*************************
//*> OPTIONAL SETTINGS
************************/
//automatic slider
var autoSlider = setInterval(slideRight, 3000);
//for each slide
$.each($('#slider-wrap ul li'), function() {
//set its color
var c = $(this).attr("data-color");
$(this).css("background",c);
//create a pagination
var li = document.createElement('li');
$('#pagination-wrap ul').append(li);
});
//counter
countSlides();
//pagination
pagination();
//hide/show controls/btns when hover
//pause automatic slide when hover
$('#slider-wrap').hover(
function(){ $(this).addClass('active'); clearInterval(autoSlider); },
function(){ $(this).removeClass('active'); autoSlider = setInterval(slideRight, 3000); }
);
});//DOCUMENT READY
/***********
SLIDE LEFT
************/
function slideLeft(){
pos--;
if(pos==-1){ pos = totalSlides-1; }
$('#slider-wrap ul#slider').css('left', -(sliderWidth*pos));
//*> optional
countSlides();
pagination();
}
/************
SLIDE RIGHT
*************/
function slideRight(){
pos++;
if(pos==totalSlides){ pos = 0; }
$('#slider-wrap ul#slider').css('left', -(sliderWidth*pos));
//*> optional
countSlides();
pagination();
}
/************************
//*> OPTIONAL SETTINGS
************************/
function countSlides(){
$('#counter').html(pos+1 + ' / ' + totalSlides);
}
function pagination(){
$('#pagination-wrap ul li').removeClass('active');
$('#pagination-wrap ul li:eq('+pos+')').addClass('active');
}
</script>
</body>
Try putting this way it works fine,because If you have code in your JavaScript that alters HTML as soon as the JavaScript file loads, there won't actually be any HTML elements available for it to affect DOM yet, so it will seem as though the JavaScript code isn't working, and you may get errors.Thanks :)
I have the following code. Clicking on the existing list item shows the popover.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Test</title>
<script src="https://cdn.jsdelivr.net/npm/jquery#3.5.1/dist/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#4.5.0/dist/js/bootstrap.bundle.min.js"></script>
<script>
$(function () {
$('[data-toggle="popover"]').popover()
})
</script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#4.5.0/dist/css/bootstrap.min.css"/>
</head>
<body>
<div class="container">
<div class="card" style="width: 18rem;">
<div class="card-header">
Featured
</div>
<ul id="card-list" class="list-group list-group-flush">
<li id="card-item" class="list-group-item" data-toggle="popover" title="Rule Details" data-placement="top" data-html="true" data-content="<h3>Popover Content</h3>">Cras justo odio</li>
</ul>
</div></br>
<button id="test" type="button" class="btn btn-outline-dark btn-sm">Test</button>
</div>
</body>
</html>
The above code has a Test button to add items to the current list. I use the code below to define new items during which I set popover attributes. New list items can be added but clicking on them doesn't bring up popovers. Please help!
let listItem = document.createElement('li');
listItem.innerHTML = "Test";
listItem.className = "list-group-item";
listItem.setAttribute("data-toggle", "popover");
listItem.setAttribute("title", "Rule Details");
listItem.setAttribute("data-placement", "top");
listItem.setAttribute("data-html", "true");
listItem.setAttribute("data-content", "<strong>test Hello World</strong>");
document.getElementById("card-list").appendChild(listItem);
You have to initialize popover on the newly created elements. Since popover is a jQuery plugin convert your element to jQuery object and apply popoper before appending like:
let listItem = document.createElement('li');
listItem.innerHTML = "Test";
listItem.className = "list-group-item";
listItem.setAttribute("data-toggle", "popover");
listItem.setAttribute("title", "Rule Details");
listItem.setAttribute("data-placement", "top");
listItem.setAttribute("data-html", "true");
listItem.setAttribute("data-content", "<strong>test Hello World</strong>");
listItem = $(listItem);
listItem.popover();
$("#card-list").append(listItem);
I'm making a list of collapsible items that can make calls to itself to scroll to and expand other items on the fly. Shooting for this...
Before selecting the hyperlink.
After selecting.
How can I get the First collapsed item to expand when the link to it in the Third item's paragraph is selected?
What I got: If the example above had more collapsed items, then the code below would scroll the webpage to the desired collapsible item (half the solution).
<!DOCTYPE html>
<html>
<head>
<!--Import materialize.css-->
<link type="text/css" rel="stylesheet" href="css/materialize.min.css" media="screen,projection"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"/>
</head>
<body>
<div>
<ul class="collapsible" data-collapsible="accordion">
<li>
<div class="collapsible-header"><i class="mdi-navigation-chevron-right"></i><a name="987"/>First</a></div>
<div class="collapsible-body"><p>Hello StackOverflow! SO's da' bomb diggidy!</p></div>
</li>
<li>
<div class="collapsible-header"><i class="mdi-navigation-chevron-right"></i>Second</div>
<div class="collapsible-body"><p>Why is the person who invests your money called a broker?</p></div>
</li>
<li>
<div class="collapsible-header"><i class="mdi-navigation-chevron-right"></i>Third</div>
<div class="collapsible-body"><p>I'd like to open the First collapsible element in this list.</p></div>
</li>
</ul>
</div>
<!--Import jQuery before materialize.js-->
<script type="text/javascript" src="https://code.jquery.com/jquery-2.1.1.min.js"></script>
<script type="text/javascript" src="js/materialize.min.js"></script>
</body>
</html>
I would just trigger click event on first .collapsible-header item, with slightly changed html code for the anchor:
$('[data-click]').on('click', function (e) {
$( $(this).data('click') ).trigger('click');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.95.3/js/materialize.min.js"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.95.3/css/materialize.min.css" rel="stylesheet"/>
<div>
<ul class="collapsible" data-collapsible="accordion">
<li>
<div class="collapsible-header"><i class="mdi-navigation-chevron-right"></i>First</div>
<div class="collapsible-body">
<p>Hello StackOverflow! SO's da' bomb diggidy!</p>
</div>
</li>
<li>
<div class="collapsible-header"><i class="mdi-navigation-chevron-right"></i>Second</div>
<div class="collapsible-body">
<p>Why is the person who invests your money called a broker?</p>
</div>
</li>
<li>
<div class="collapsible-header"><i class="mdi-navigation-chevron-right"></i>Third</div>
<div class="collapsible-body">
<p>I'd like to open the First collapsible element in this list.</p>
</div>
</li>
</ul>
</div>
Same code is also on Fiddle.
If you wish to target n-th element, than you can use jQuery :eq() selector (zero based). For example, to target 3rd item you would use '.collapsible-header:eq(2)' selector.
If you care about the SEO (and you should), than your links should have correct href. In this case add unique IDs to .collapsible_header elements and use slightly different script to exploit it:
$('[data-click]').on('click', function (e) {
$( $(this).attr('href') ).trigger('click');
});
where the target item is:
<div id="about_stackoverflow" class="collapsible-header">
and the valid local link is:
open the First collapsible element
You can see it working on this Fiddle. (The last anchor may be anywhere on the same page)
Trying to understand how Javascript and HTML5 work. I have a nav and when you press Part One I'm trying to show Content 1, when you press Part Two..etc. I have tried a couple things, and I am clearly not understand the .next properly, but I can only get it to show the first element, but when I press Part Two, Content Two doesn't show. I guess I am visualizing it wrong, instead of .first(), .next made sense to me since I feel like that would just get the next element. Anyways, here's some code, thanks in advance.
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Assignment 6 | jQuery Usability </title>
<link rel="stylesheet" href="stylesheet.css">
<!-- This matches the CSS width to the device width, and prevents forced overview without disabling zooming -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- Helpful for older Blackberries -->
<meta name="HandheldFriendly" content="True">
<!-- Helpful for older IE mobile -->
<meta name="MobileOptimized" content="320">
<!-- Apple iOS-specific -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<!-- enforce CSS3 media queries in IE 8 and older -->
<!--[if lt IE 9]>
<script src="http://css3-mediaqueries-js.googlecode.com/svn/trunk/css3-mediaqueries.js"></script>
<![endif]-->
<!-- Note: this won't work when testing locally; you'll need to upload your files to a server to test it in IE -->
<!-- HTML5shiv, for IE 6, 7 and 8 -->
<!--[if lte IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js" type="text/javascript"></script>
<![endif]-->
<!-- jQuery -->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<script>
$(document).ready(function() {
$('ul').hide();
$('a.btnDown').click(function() {
$('nav>ul').fadeIn(200);
}); //closes a.btnDown
$('a.contentDown').click(function() {
$('body>aside>ul').first().fadeIn(200);
}); //closes contentDown
}); //closes .ready()
</script>
</head>
<body>
<nav>
<h1><a class="btnDown" href="#"> Main Menu </a></h1>
<ul>
<li><a class="contentDown" href="#"> Part One </a></li>
<li><a class="contentDown" href="#"> Part Two </a></li>
<li><a class="contentDown" href="#"> Part Three </a></li>
<li><a class="contentDown" href="#"> Student Notes 1 </a></li>
<li><a class="contentDown" href="#"> Student Notes 2 </a></li>
<li><a class="contentDown" href="#"> Student Notes 3</a></li>
</ul>
</nav>
<aside>
<ul>
<li> Content 1 </li>
</ul>
<ul>
<li> Content 2 </li>
</ul>
<ul>
<li> Content 3 </li>
</ul>
<ul>
<li> Content 4 </li>
</ul>
<ul>
<li> Content 5 </li>
</ul>
<ul>
<li> Content 6 </li>
</ul>
</aside>
<figure>
<!-- PUT TV IMAGE HERE -->
</figure>
</body>
</html>
With the given markup, the easiest solution is to work with the index of the elements as shown below
$(document).ready(function () {
$('ul').hide();
$('a.btnDown').click(function () {
$('nav>ul').fadeIn(200);
return false;
}); //closes a.btnDown
//all the content elements
var $suls = $('body>aside>ul');
var $as = $('a.contentDown').click(function () {
//hide visible content item
$suls.filter(':visible').hide();
//display the content item in the same position as the clicked contentDown
$suls.eq($as.index(this)).fadeIn(200);
}); //closes contentDown
}); //closes .ready()
Demo: Fiddle
You can use:
$('ul').hide();
$('a.btnDown').click(function () {
$('nav>ul').fadeIn(200);
});
$('a.contentDown').click(function () {
var idx = $(this).index('.contentDown');
$('body>aside>ul:eq(' + idx + ')').fadeIn(200).siblings('ul').hide();
});
Fiddle Demo