Some had this problem but I did not see any answer that fits mine.
Here is the html :
<div id="page">
......
<ul>
<li role="presentation">
<a id="selection"...... ></a>
</li>
<li role="presentation>
<a id="xxxx"></a>
</li>
<li role="presentation">
<a id="yyyyy"></a>
</li>
</ul>
.......
</div>
here is the javascript using Mootools (no choice) :
window.addEvent('domready', function() {
var myDivPage = document.id('page');
var as = myDivPage.getElements('li[role=presentation] a');
//as is an array of 3 elements
Array.each(as, function(element, index) {
if(element.id !== 'selection') {
element.addEvent("click", function(event) {
event.preventDefault();
event.stopPropagation();
alert("did you save?");
});
}
});
});
The event is indeed attached but when I click my link the alrt is displayed twice, as though the event occured twice. As you can see I stopped the propagation, so how could this happen ?
Thank you
The below if condition is inside a loop.
if(element.id !== 'selection')
The check is made for each element.id which is not equal to selection. So how many times, if condition is true? 2 One for id="xxxx" and other for id="yyyyy"
For click event to be triggered only once use
if(element.id === 'selection')
The code as displayed seems fine. Verify that your event handler isn't actually added twice (place an alert just before your Array.each loop)
$$('#page li[role=presentation] a:not(#selection)').addEvent("click",
function(event) { event.stop(); alert("Did you save?"); })
would be a more mootools-y way of doing this though.
Related
we have used one jquery library called as jesse which works fine
The thing is we have an li attributes and inside it we have used onclick event .. but somehow it stops working and we are unable to call onclick event .. Here is the fiddle for better understanding
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://www.jqueryscript.net/demo/Simple-jQuery-Plugin-For-Drag-Drop-Sorting-Of-Lists-jesse/jquery-jesse.js"></script>
<script type="text/javascript">
$(function(){
// removing image onclick close button
$("#list").on("click", ".close_product", function (event) {
console.log('inside onclick function');
});
$('#list').jesse({
onStop: function(position, prevPosition, item) {
console.log('inside list function');
if(position == 0){
item.addClass("drop-high").removeClass("drop-small");;
$( "#list" ).find( "li:nth-child(2)" ).removeClass("drop-high").addClass("drop-small");
}
if(prevPosition == 0){
item.addClass("drop-small").removeClass("drop-high");
$( "#list" ).find( "li:nth-child(1)" ).removeClass("drop-small").addClass("drop-high");
}
},
});
});
</script>
<ul class="jq-jesse" id="list">
<li class="drop-high"><div class="high"><div class="close close_product">X</div><img src="https://dab1nmslvvntp.cloudfront.net/wp-content/uploads/2016/04/1459870313PHP-logo.svg.png" width="20%"></div> </li>
<li class="drop-small"><div class="high"><div class="close close_product">X</div><img src="https://phpwomen.org/holdingpage/images/usergroups/phpne.png" width="20%"></div> </li>
<li class="drop-small"><div class="high"><div class="close close_product">X</div><img src="http://d3gnp09177mxuh.cloudfront.net/tech-page-images/php.png" width="20%"></div></li>
<li class="drop-small"><div class="high"><div class="close close_product">X</div><img src="http://unitedwebsoft.in/blog/wp-content/uploads/2013/07/advantage-of-php.jpg" width="20%"></div></li>
</ul>
As you can see above, i have onclick function, but its not working. How can i make it work ?
The library doesn't use drag events. It listens to mousedown and if fired it stops default execution with e.preventDefault(); and watches over $(document).on('mousemove') and .on('mouseup').
Therefore closing div can't hear any click event. You can slightly modify the library file to make it identify closing clicks.
Add specific setting, say, closingClass to the class (line 7)
var settings = $.extend({
closingClass: 'closing',
selector: 'li',
dragClass: '_isDragged',
placeholder: '<li class="jq-jesse__placeholder"></li>'
}, options);
Change listening of clicks at closing divs by adding the following 3 lines:
list.on('mousedown', settings.selector, function(e){
if($(e.target).hasClass(settings.closingClass)) {
return true;
}
That's it. Now you can't drag using a div having closingClass. You can add their own listeners.
Fiddle with fixed library code.
Using Bootstrap
<ul class="nav nav-pills nav-stacked col-sm-2 hidden" id="menu">
<li role="presentation" id="LiNewsFeed">News Feed</li>
<li role="presentation" id="LiStatusUpdate">Update Status</li>
<li role="presentation" id="LiWriteWall">Post On Wall</li>
<li role="presentation" id="LiNotifications">Notifications</li>
<li role="presentation" id="LiLogOut">Logout</li>
</ul>
In Javascript, I am disabling some of the <li> like the following:
$('#LiNewsFeed').addClass('disabled');
The Item in the List actually LOOKS disabled, when when I click on it, it actually calls the javascript function, therefore, what I need is to disable the <a href> not just the <li>
I tried adding this after $(document).ready:
$(".nav li.disabled a").click(function () {
return false;
});
But it's not really doing anything.
What I need is to disable the <a href> directly after disabling <li> in my Js code, and not to depend on a click event...
Seems like there is no way to disable an <a href>, so I need a way around it
Any help would be appreciated.
use below code. check working example JSFIDDLE
$(".nav li.disabled a").each(function(){
$(this).attr('href','javascript:void(0);');
});
As you are disabling LI in javascript (runtime), you should use .on to bind events on disabled links:
$(".nav").on('click', 'li.disabled a', function () {
return false;
});
I would check on every link click if the parent has the disabled class.
$('.nav li a').click(function () {
if($(this).parent('li').hasClass('disabled')) {
return false;
}
return true;
});
EDIT, following more info from OP I would suggest the following:
$('.nav li a').each(function() {
var $this = $(this);
// store reference of 'href' attr in case link is re-enabled
$this.data('href', $this.attr('href'));
if ($this.parent('li').hasClass('disabled')) {
// remove href attribute disabling click
$this.removeAttr('href');
} else {
// restore href
$this.attr('href', this.data('href'));
}
});
This code should be run after you add/remove the disabled class on li elements.
EDIT 2 - Rather than you calling functions from the href of <a> links, you could do something like the following:
var events = {
'#LiNewsFeed': 'GetNewsFeed',
'#LiStatusUpdate': 'StatusUpdate'
'#LiWriteWall': 'WriteOnWall',
'#LiNotifications': 'GetNotifications',
'#LiLogOut': 'LogOut'
};
for (var selector in events) {
if (events.hasOwnProperty(selector)) {
try {
$(selector).click(function () {
// assuming function is global
if (typeof window[events[selector]] === 'function') {
// call function
window[events[selector]]();
}
// this is needed if the a element still has a href attr
return false;
});
} catch (e) {
console.log('Invalid Selector');
}
}
}
This way you can control the calling of the function, and check whether it should be called without altering the element, perhaps stick an
if (!$(this).parent('li').hasClass('disabled')) {
...
}
around the function call.
can you convert the a into span?
(code not tested)
$(".nav li.disabled a").replaceWith(function() { return "<span>" + this.innerHTML + "</span>"; });
i have a little problem with my styled Selectfield. I used for this unordered list elemnts (UL / LI) and a H3.
The problem is to close the "Selectfield" by clicking anywhere on the page.
When i bind a click event to the "document", then don't open the SelectField with the current jQuery code.
I have hidden the UL Element by using CSS (display:none).
To open the Select Fields is not the problem. But only without the $(document).bind('click') [...] code.
I hope anyone have a resolution for my.
Thanks.
And here my HTML Code:
<div class="select_container">
<h3 class="reset">Select Items</h3>
<ul class="select_elements">
<li>Select Item 01</li>
<li>Select Item 02</li>
<li>Select Item 03</li>
</ul>
</div>
And here the jQuery Code:
$(document).ready(function(){
var selectFields = {
init: function(){
$('.select_container').on('click',function(){
$(this).find('ul.select_elements').toggle();
$(this).find('ul.select_elements').toggleClass('active');
});
$(document).bind('click',function(){
if( $('.select_elements').is(':visible')){
$('.select_elements.active').hide();
}
else if( $('.select_elements').is(':hidden')){
console.log('visible false ...');
}
});
}
};
$(selectFields.init);
});
You need to use .stopPropagation in $('.select_container').on('click') function to prevent triggiring $(document).on('click')
You need to use toggleClass in $(document).on('click') too
$('.select_container').on('click',function(e){
$(this).find('ul.select_elements').toggle();
$(this).find('ul.select_elements').toggleClass('active');
e.stopPropagation();
});
$(document).on('click',function(){
if( $('.select_elements').is(':visible')){
$('.active').hide();
$('.select_elements').toggleClass('active');
}
else {
console.log('visible false ...');
}
});
FIDDLE
In jquery and javascript an event bubbles up so you have to use e.stopPropagation() on your container click.
check theese pages linki1 or link2 and a possible solution to your problem could be
<script type="text/javascript">
$(document).ready(function(){
var selectFields = {
init: function(){
$(document).bind('click',function(e){
if( !$('ul').hasClass('active')){
$('ul').hide()
$(this).find('ul.select_elements').toggleClass('active');
}
});
$('.select_container').on('click',function(e){
e.stopPropagation()
if( $('ul').hasClass('active')){
$('ul').show()
}else{ $('ul').hide() }
$(this).find('ul.select_elements').toggleClass('active');
});
}
};
$(selectFields.init);
})
</script>
With stopPropagation prevent the event from bubbling and being caught by the document when you click on the list
in some cases you can also use stopImmediatePropagation, for understand differences between stopPropagation and stopImmediatePropagation check this post Post
The only drawback to similar code and to and Batu Zet code, is that If you want the items in the list can be clicked without disappearing, you have to add another stopPropagation on ul tag
Tis is the final Fiddle
HTML CODE:
<ul id="sortable1" class="connectedSortable ui-sortable">
<li class="ui-state-default" id="1">Name1</li>
<li class="ui-state-default" id="2">Name2</li>
<li class="ui-state-default" id="3">Name3</li>
<li class="ui-state-default" id="4">Name4</li>
<li class="ui-state-default" id="5">Name5</li>
JQUERY CODE:
$(function() {
$("#sortable1 li").each(function()
{
$(this).on("click",make($(this)));
});
function make($li)
{
alert("hello");
}
});
fiddle :
http://jsfiddle.net/gztRq/433/
when i run the fiddle , it will automatically displays the alert for five list items.
actually i have binded click event for list item so whenever the list is clicked it needs to call the function.
but why the above "make" function triggered five times before am clicking the list. after clicking the list item nothing happened. what is the problem ?
when i write the function code in-line everything works as expected.
Working code:
$("#sortable1 li").each(function()
{
$(this).on("click",function()
{
alert("hello");
});
});
what is the correct behavior ?
You call your function, don't add "(", ")". Just write name function (is reference). And this, is already define for the event function.
http://jsfiddle.net/gztRq/437/
$(function() {
$("#sortable1 li").each(function() {
$(this).click(make);
});
function make() {
alert("hello "+$(this).text());
}
});
Remove the $.each() loop completely and just use:
$('#sortable1').on('click', 'li', function() {
alert("Hello"); // Or make($(this)); if you still want that extra function
});
JSFiddle demo.
You should use:
$(this).on("click",function(){make($(this))});
Demo
Try this,
$("#sortable1 li").click(function(){
make($(this));
});
you can try:
$(document).on("click","sortable1 li",function(){
});
I'm trying to create a custom jquery cycle plugin which basically displays the contents of an <li> element upon click. The html is as follows:-
<ul class="ticker">
<li>Boo1</li>
<li>More boo1</li>
<li>Even more boo</li>
<a class="prev" href="#">previous</a>
<a class="next" href="#">next</a>
</ul>
so when the user clicks the next button, the next <li> shows and when he clicks the prev button, the previous <li> shows.
Achieving this has never been easy :( I'm still quite new to jquery so please pardon. Any help guys
I think this will solve your problem, you can see it working here http://jsfiddle.net/KvscH/
<ul class="ticker">
<li>Boo1</li>
<li>More boo1</li>
<li>Even more boo</li>
</ul>
<a class="prev" href="#">previous</a> -
<a class="next" href="#">next</a>
Js:
var ticker = $('ul.ticker');
ticker.children(':first').show().siblings().hide();
setInterval(function() {
ticker.find(':visible').fadeOut(function() {
$(this).appendTo(ticker);
ticker.children(':first').show();
});
},50000);
$('.next').live ('click', function () {
ticker.find(':visible').fadeOut(function() {
$(this).appendTo(ticker);
ticker.children(':first').show();
});
});
$('.prev').live ('click', function () {
ticker.find(':visible').fadeOut(function() {
ticker.find('li:last').insertBefore(ticker.find('li:first'));
ticker.children(':first').show();
});
});
Taking a wild stab in the dark:
DEMONSTRATION (I left previous button untouched, that's up to you)
The code (notice I left a section for you to complete):
var ticker = $('ul.ticker');
ticker.children(':first').show().siblings().hide();
startTicker();
$('.prev, .next').bind('click', function() {
if($(this).attr('class') == 'prev') {
clearInterval(myInterval);
/// for previous
/// do it
/// yourself
} else {
clearInterval(myInterval);
ticker.find(':visible').fadeOut(function() {
$(this).appendTo(ticker);
ticker.children(':first').show();
startTicker();
});
}
});
var myInterval;
function startTicker() {
myInterval = setInterval(function() {
ticker.find(':visible').fadeOut(function() {
$(this).appendTo(ticker);
ticker.children(':first').show();
});
},2000);
}
Okay, here is a potential solution for you, if I am understanding you correctly:
First off, setInterval is a "background function", in that it can run in the background while you run other functions. What you want to do first is move the stuff that you do inside of the setInterval method into its own function. Then, you will create a click event handler in which you call the that function. After that you can call setInterval and and it will run at the same time as you have your click-event listener running.
If you experience any issues with the interval being broken when your click-listener fires, you can also re-initialize your interval after calling the function in your click-listener.
Let me know if you need any further help/explanation.
Good Luck! :)
Take a look at this jsFiddle
HTML
<ul class="ticker">
<li>Boo1</li>
<li>More boo1</li>
<li>Even more boo</li>
</ul>
<a class="prev" href="#">previous</a>
<a class="next" href="#">next</a>
JS
var ticker = $('ul.ticker');
ticker.children(':first').show().siblings().hide();
function cycleFunc(direction) {
ticker.find(':visible').fadeOut(function() {
(direction == 'forward') ? $(this).appendTo(ticker) : $(this).prependTo(ticker);
ticker.children((direction == 'forward') ? ':first' : ':last').show();
})
}
var timer = setInterval(function() {
cycleFunc('forward');
}, 2000);
$('.next, .prev').click(function() {
clearInterval(timer)
var direction = ($(this).hasClass('next')) ? 'forward' : 'backward';
timer = setInterval(function() {
cycleFunc(direction);
}, 2000)
});
Removed the DOM manipulations just to keep track of the currently visible element.
I think they are unnecessary. My 2 cents.
Also made it like something someone would actually use.
HTML:
<div id='Test'>
<ul class="ticker">
<li>Boo1</li>
<li>More boo1</li>
<li>Even more boo</li>
</ul>
<a class="prev" href="#">previous</a>
<a class="next" href="#">next</a>
</div>
JS:
jQuery.fn.Custom_cycler = function(Options){
var Options = jQuery.extend({'Next': 'a.next', 'Previous': 'a.prev', 'List': 'ul.ticker'},Options||{});
var List = jQuery(Options.List, this);
var Index = 0;
var Size = List.children().size();
List.children().hide().first().show();
var Move = function(Event){
Event.preventDefault();
if(Event.data)
{
Index++;
}
else
{
Index--;
}
Index=(Index+Size)%Size;
jQuery(List.children().hide().get(Index)).show();
};
jQuery(Options.Next, this).bind('click', true, Move);
jQuery(Options.Previous, this).bind('click', false, Move);
return(this);
};
You use it like this:
jQuery('div#Test').Custom_cycler();
EDIT: Used the data parameter in the event handler to use only one function for both events which allowed me to use a closure for the Index/Size instead of jQuery(...).data.
Also removed some unnecessary variables from the closure.
And finally narrowed the context of the selection to avoid mistakenly manipulating external DOM tags when calling the function. It also executes faster because jQuery doesn't have to lookup the entire DOM.
Could be optimized further by calling hide() only on the previously shown element instead of all of them (easily infer-able from the value of Index).