Callback needed, don't know how - javascript

My problem is this. that i create a list of <li> in side <ul> element. when you click on one of thouse <li> elements, the others disappear. now when you click on [See all items], the previous list appears agen. But now when you click on the other element, nothing happens. That should be because the new element doesn't know what todo when you click it. we need a callback! But i don't get what should i write in to this callback function?!
My Code: http://jsfiddle.net/cRcNB/.
In JS section there is easying.js and quicksand.js befor. so scroll down(all the way) and you'll see my (Short)code. :)
I ll post my code here as asked:
$(document).ready(function(){
var $holder = $('ul.holder');
var $data = $holder.clone();
$('ul.holder li').click(
function(e){
$holder.quicksand($(this),{
duration: 800,
});
return false;
});
$('#all').click(
function(e){
$new = $data.find('li')
$holder.quicksand($new,{
duration: 800
}
);
return false;
});
})
HTML
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
</head>
<body>
<ul>
<li id='all'>[See all items]</li>
</ul>
<ul class='holder'>
<li data-id="1" data-type="a">heaven</li>
<li data-id="2"data-type="b">love</li>
</ul>
</body>
</html>
Quiksand1.3.js and Easing.js is required as well.

Try replacing
$('ul.holder li').click(
function(e){
$holder.quicksand($(this),{
duration: 800,
});
return false;
});
with:
$('ul.holder').on('click', 'li', function(e){
$holder.quicksand($(this),{
duration: 800,
});
return false;
});
This will bind the click handler to the <ul> which is always in the DOM. When you are removing the <li>'s you are also throwing away their click handlers. This could be the problem.

Here is a simpler version of the code:
Markup:
<ul>
<li id='all'>[See all items]</li>
</ul>
<ul class='holder'>
<li data-id="1" data-type="a">heaven</li>
<li data-id="2"data-type="b">Earth</li>
<li data-id="2"data-type="b">Dirt</li>
<li data-id="2"data-type="b">Peace</li>
<li data-id="2"data-type="b">More</li>
</ul>
jQuery:
$("#all").on("click",function(){
$(".holder li").show("slow");
});
$(".holder li").on("click",function(){
$(".holder li").not($(this)).hide("slow");
});
JSFiddle: http://jsfiddle.net/5ChVE/5/

Related

When the item is added, the drag event does not work

drag and drop eventim works but I can't run it with the buttons I added.
I know I should run as on click, but I didn't get any results.
Can you help? Thanks ...
https://codepen.io/celilsahin/pen/BqGvLm
<ul class="handles list">
<li class="red"><span>::</span></li>
<li class="purple"><span>::</span></li>
<li class="orange"><span>::</span></li>
<li class="yellow"><span>::</span></li>
<li class="blue"><span>::</span></li>
</ul>
<button>Add</button>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="jquery.sortable.js"></script>
<script>
$(function(){
$('.handles').sortable({
handle: 'span'
});
("button").click(function(){
$( ".handles" ).append($('<li class="red"><span>::</span></li>').hide().fadeIn(300));
});
});
</script>
You can get it adding $('.handles').sortable('refresh'); in code
$("button").click(function(){
$( ".handles" ).append($('::').hide().fadeIn(300));
$('.handles').sortable('refresh');
});

Need to click Each li Element without affecting parent

I have HTML Structure like
<ul>
<li><a></a>
<ul>
<li><a></a>
<ul>
<li><a></a>
<ul>
<li><a></a></li>
</ul>
</li>
</ul>
</li>
</ul>
I want to add 'active' class for relevant 'a' Element when corresponding li clicked.
$('#a').on('click', function(){
$('a', this).addClass('active');
});
<ul>
<li id="a"><a></a>
<ul>
<li id="b"><a></a>
<ul>
<li id="c"><a></a>
<ul>
<li id="d"><a></a></li>
</ul>
</li>
</ul>
</li>
</ul>
Use children() method, since you only want to select the direct child
$('li').click(function(){
$(this).children('a').addClass('active')
})
or use > to select direct child
$('li').click(function(){
$('>a', this).addClass('active')
})
A delegate click handler would most likely solve your problem best.
$('ul.master').on('click', 'li', function (evt) {
evt.stopPropagation();
// I added this line to remove active class from all other a tags
$(this).parents('ul.master').find('a').removeClass('active');
$(this).children('a').addClass('active');
});
See this jsfiddle
You could work on the <a> tag directly to capture the click for changing the active class. If you need to work directly with the <li> You can attach another handler.
$('a').click(function(evt){
$(this).addClass('active');
});
$('li').click(clickHandler);
You mean something like this?
$('li').on('click', function(){
$('a', this).addClass('active');
});
just target the li a directly:
$('li a').on('click', function(){
$(this).addClass('active')
});
$('li').on('click', function(){
$(this).closest('a').addClass('active');
});
Get first child using :first (if you have only one anchor per li) the use addclass method to assign class
I fixed your HTML:
<ul>
<li>
<a>A</a>
<ul>
<li>
<a>B</a>
<ul>
<li>
<a>C</a>
<ul>
<li>
<a>D</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
jQuery + JS code:
<script src="https://code.jquery.com/jquery-3.0.0.min.js"></script>
<script type="text/javascript">
$('a').click(function(){
$(this).parent('li').addClass('active')
})</script>
$(document).on('click', 'a', function(){
if($(this).parent('li').length) {
$(this).parent('li').addClass('active');
}
});

Updating class of list item - jQuery

Pretty simple problem but it's been bugging me for almost an hour now. Basically, I want to update list classes onClick, then remove the class again when another item is clicked.
<nav>
<div class="menu-main-menu-container">
<ul id="menu-main-menu" class="menu">
<li class="current-menu-item">
<a class="scroll" href="#top"><span>Home</span></a>
</li>
<li class="">
<a class="scroll" href="#featured_work_anchor"><span>Featured Work</span></a>
</li>
<li class="">
<a class="scroll" href="#about_contact_anchor"><span>About/Contact</span></a>
</li>
</ul>
</div>
</nav>
jQuery
$(document).ready(function() {
$('#menu-main-menu li').on('click', changeClass);
});
function changeClass() {
$('#menu-main-menu li').removeClass('current-menu-item');
$(this).addClass('current-menu-item');
}
JSFiddle, ready to go. I appreciate any help. Perhaps I'm approaching the problem wrong or maybe missing something silly ?
The only problem I could see is the removeClass() function, either don't pass any argument so that all the classes in the li are removed or pass the class names to be removed.
function changeClass() {
$('#menu-main-menu li').removeClass('current-menu-item');
$(this).addClass('current-menu-item');
}
Demo: Fiddle(Also in the fiddle you forgot to include jQuery)
You need to pass the element that is being set as current:
$(document).ready(function() {
$('#menu-main-menu li').on('click', function(){
changeClass($(this));
});
});
function changeClass(element) {
$('#menu-main-menu li').removeClass('current-menu-item');
element.addClass('current-menu-item');
}
updated fiddle: http://jsfiddle.net/mw5sgcLn/4/

Cannot add click events to list items

This is my first foray into using Javascript with HTML. I'm trying to add click events to the list items in an ordered list, but something about the way I'm doing it isn't working. Can somebody shed some light on this for me?
I create a function in my head that should delegate all click events on the list items of a specified list to a given function, and in that given function I try to raise a simple alert with the text of the list item. Eventually I want to do more, but I'm just trying to get the simple click events to work first.
<html>
<head>
<script type="text/javascript">
// Attach an event handler to the 'topfriends' list to handle click events.
function attachEventHandlerToList() {
document.getElementById("#top4list").delegate("li", "click", function(clickEvent) {
alert(this.innerHTML());
});
}
</script>
</head>
<body>
<div id="topfriends">
<h3>Top 4 Most Friendable Friends</h3>
<ol id="top4list" onload="attachEventHandlerToList()">
<li>Brady</li>
<li>Graham</li>
<li>Josh</li>
<li>Sean</li>
</ol>
</div>
</body>
Let's do something like this
<ul id="parent-list">
<li id="a">Item A</li>
<li id="b">Item B</li>
<li id="c">Item C</li>
<li id="d">Item D</li>
<li id="e">Item E</li>
<li id="f">Item F</li>
</ul>
Now write the javascript for this
<script type="text/javascript">
// locate your element and add the Click Event Listener
document.getElementById("parent-list").addEventListener("click",function(e) {
// e.target is our targetted element.
// try doing console.log(e.target.nodeName), it will result LI
if(e.target && e.target.nodeName == "LI") {
console.log(e.target.id + " was clicked");
}
});
</script>
Please refer to this write-up on Javascript Event Delegates
http://davidwalsh.name/event-delegate
Also, below link is the fiddle that I created
http://jsfiddle.net/REtHT/
hope this helps !
delegate() is a deprecated jQuery method, and no such method exists in plain JS.
To attach an event handler in JS you'd use addEventListener, and for older versions of IE you'll need attachEvent as well, that's why it's a little tricky with cross browser event handlers.
onclick, onmouseenter etc. will work in all browsers, but it's consider a better practice to use addEventListener / attachEvent.
Also, you have to run the script after the elements are added to the DOM, otherwise they are not available. The usual way is to insert the script after the elements, or use a DOM ready event handler.
<html>
<head>
<title>test</title>
</head>
<body>
<div id="topfriends">
<h3>Top 4 Most Friendable Friends</h3>
<ol id="top4list">
<li>Brady</li>
<li>Graham</li>
<li>Josh</li>
<li>Sean</li>
</ol>
</div>
<script type="text/javascript">
var lis = document.getElementById("top4list").getElementsByTagName('li');
for (var i=0; i<lis.length; i++) {
lis[i].addEventListener('click', doStuff, false);
}
function doStuff() {
alert( this.innerHTML );
}
</script>
</body>
FIDDLE
Try this. It will work with child Node and Parent Node also.
var visitorList = document.getElementById("visitor");
visitorList.addEventListener("click", function (e) {
var visitorId;
if (e.target && e.target.nodeName == "LI") {
visitorId = e.target.id;
console.log(e.target.id);
}
if(e.target && e.target.nodeName == "H1") {
visitorId = e.srcElement.parentElement.id;
console.log(e.srcElement.parentElement.id);
}
//console.log(visitorId);
});
<ul id="visitor">
<li id="a" style="background: #CCCCCC; padding: 10px;"><h1 style="background: #437ba9;">Visitor A</h1></li>
<li id="b"><h1>Visitor B</h1></li>
<li id="c"><h1>Visitor C</h1></li>
<li id="d"><h1>Visitor D</h1></li>
<li id="e"><h1>Visitor E</h1></li>
<li id="f"><h1>Visitor F</h1></li>
</ul>
You can also do it by using querySelectorAll
<ul class="stuffList">
<li>Stuff 1</li>
<li>Stuff 2</li>
<li>Stuff 3</li>
<li>Stuff 4</li>
<li>Stuff 5</li>
</ul>
<script type="text/javascript">
document.querySelectorAll('ul.stuffList li').forEach((item) => {
item.addEventListener('click', (e) => {
console.log(e.target)
})
});
</script>
Hello why not doing it easier by replacing onLoad directy by onClick
<script type="text/javascript">
function olClicked(){
alert(this.innerHTML());
}
</script>
<ol id="top4list" onClick="olClicked()">

jQuery .show & .hide not working

I am currently working on building a small menu that will change divs based upon which one it clicked. So if one is clicked it will show the div associated with it and hide the others, ect. But I cannot get it to work, nor can I figure out why. Any help would be appreciated. Thanks.
Below is my code. I've clipped out the content as there was a lot of it.
<script type="text/javascript">
$('.mopHeader').click(function() {
$('#raid-progress-mop').show();
$('#raid-progress-cata').hide();
$('#raid-progress-wotlk').hide();
$('#raid-progress-tbc').hide();
$('#raid-progress-vanilla').hide();
});
$('.cataHeader').click(function() {
$('#raid-progress-mop').hide();
$('#raid-progress-cata').show();
$('#raid-progress-wotlk').hide();
$('#raid-progress-tbc').hide();
$('#raid-progress-vanilla').hide();
});
$('.wotlkHeader').click(function() {
$('#raid-progress-mop').hide();
$('#raid-progress-cata').hide();
$('#raid-progress-wotlk').show();
$('#raid-progress-tbc').hide();
$('#raid-progress-vanilla').hide();
});
$('.tbcHeader').click(function() {
$('#raid-progress-mop').hide();
$('#raid-progress-cata').hide();
$('#raid-progress-wotlk').hide();
$('#raid-progress-tbc').show();
$('#raid-progress-vanilla').hide();
});
$('.vanillaHeader').click(function() {
$('#raid-progress-mop').hide();
$('#raid-progress-cata').hide();
$('#raid-progress-wotlk').hide();
$('#raid-progress-tbc').hide();
$('#raid-progress-vanilla').show();
});
</script>
<span class="h4">Raid Progress <span class="mopHeader">MoP</span> <span class="cataHeader">Cata</span> <span class="wotlkHeader">WotLK</span> <span class="tbcHeader">TBC</span> <span class="vanillaHeader">WoW</span></span>
<div id="raid-progress-mop">
<ul id="raid-mop">
<li>Content A</li>
</ul>
</div>
<div id="raid-progress-cata">
<ul id="raid-cata">
<li>Content B</li>
</ul>
</div>
<div id="raid-progress-wotlk">
<ul id="raid-wotlk">
<li>Content C</li>
</ul>
</div>
<div id="raid-progress-tbc">
<ul id="raid-tbc">
<li>Content D</li>
</ul>
</div>
<div id="raid-progress-vanilla">
<ul id="raid-vanilla">
<li>Content E</li>
</ul>
</div>
Wrap your code in:
$(function(){ ... });
...which is the short form of:
$(document).ready(function(){ ... });
Cheers
You need to put the script underneath your markup. Either that, or put it inside document.ready callback:
$(document).ready(function() {
// code here
});
The problem is that when the script appears above the markup, it will execute before the HTML is loaded, and so the browser won't yet know about raid-progress-mop, etc.
How about doing that a little more dynamically inside a ready() function :
<script type="text/javascript">
$(function() {
$('[class$="Header"]').on('click', function() {
var myClass = $(this).attr('class').replace('Header', '');
$('[id^="raid-progress"]').hide();
$('#raid-progress-' + myClass).show();
});
});
</script>
jsBin demo
Wrap your code into a ready finction and this code I wrote is all you need:
$(function(){
$('span[class$="Header"]').click(function(){
var classNameSpecific = $(this).attr('class').split('Header')[0];
$('div[id^="raid-progress-"]').hide();
$('#raid-progress-'+classNameSpecific).show();
});
});
Explanation:
$('span[class$="Header"]') = target any span element which class ends with Header
Now just attach a click handler to all that spans.
Than, to hide all your div elements do:
$('div[id^="raid-progress-"]').hide(); = will hide any div which id starts with raid-progress-
and than you just need to target the div that contains the magic word:
$('#raid-progress-'+classNameSpecific).show();
$('.mopHeader') isn't defined yet. wrap your script with $(function(){...})

Categories