How to safely fire two open handlers jQuery - javascript

Some of my pages work, some of them don't. The ones that don't work are the ones with a custom event handler. All pages have the following jQuery code.
var speed = 750;
$(document).on("dialogopen", ".dialogClass", function() {
var parent = $(this).parent();
$(this).dialog("option", "width", $(window).width());
$(this).dialog("option", "height", $(window).height());
$(this).dialog("option", "position", [0,0]);
$(this).dialog("option", "draggable", "false");
parent.css("position","fixed");
parent.css("top","0px");
parent.css('left','-' + $(window).width() + 'px');
parent.animate({
left: 0
}, speed, "easeOutBounce");
});
$(document).on("dialogclose", ".dialogClass", function() {
if($('#dialog').is(':data(dialog)')){
$(this).dialog("destroy");
$(this).swipe("destroy");
$(this).swipe({
swipeLeft:function(event, direction, distance, duration, fingerCount) {
if(distance >= 200){
var dia = $(this);
$(this).parent().animate({
left : -$(window).width()
},speed, "easeInExpo", function(e) {
dia.dialog("close");
});
}
}
});
}
});
Some dialogs have custom open\close handlers such as (theDialog is of class dialogClass):
$("#theDialog").dialog({
width: 700,
height:675,
title:'Add Event',
resizable:false,
modal:true,
close: function(event,ui{
$("#theDialog").html('');
//Do other things
});
Is it proper jQuery to have two close handlers? Are these conflicting in any way shape or form? If so how can I have the custom event handler fire as well as the global class one.

Related

Add and drag new item by click

I want create an effect "taking stone from bowl". New div element ".stone" should creating under mouse cursor by clicking on specified div ".bowl". The stone should be straight draggable while the user click and press the mouse.
All I could write is adding new element that user can move by second click, but not by first:
$(".bowl").on('mousedown', function ( event ) {
var $stone = $('<div class="stone"></div>').css({
left: event.pageX - 25,
top: event.pageY - 25,
position: "absolute"
});
$(this).parent().append($stone);
$stone.draggable();
});
https://jsfiddle.net/rzab2h5u/
How I can do it right way?
This can be done by basically passing the event to the draggable after it's been created. Reference: https://forum.jquery.com/topic/trigger-draggable-on-mousedown
Working example: https://jsfiddle.net/Twisty/s3tfa3dr/
JavaScript
$(function() {
var bowl = $(".bowl");
bowl.droppable({
accept: ".stone",
greedy: true,
drop: function(event, ui) {
ui.draggable.detach();
}
});
bowl.on('mousedown', function(event) {
var $this = $(this);
var $stone = $('<div>', {
class: "stone",
id: "stone-" + ($(".stone").length + 1)
}).css({
left: event.pageX - 25,
top: event.pageY - 25,
position: "absolute"
}).appendTo($this.parent()).draggable({
start: function(ui, event) {
console.log("Drag Started");
}
});
$stone.trigger(event);
});
});
We basically re-trigger the same event on the new object.

Jquery on click show mouseleave hide sidebar

Hi i need some with the this script i manage to show the panel with the mouseclick but i wanted when my mouse leave the panel it will close it
this is the sample http://jsfiddle.net/jikey/w9s7pt25/
$(function(){
$('.slider-arrow').click(function(){
if($(this).hasClass('show'))
{
$( ".slider-arrow, .spanel" ).animate({
right: "+=182"
}, 700, function() {
// Animation complete.
});
$(this).html('<img src="images/sideclose.png" />').removeClass('show').addClass('hide');
}
else
{
$( ".slider-arrow, .spanel" ).animate({
right: "-=182"
}, 700, function() {
// Animation complete.
});
$(this).html('<img src="images/sideopen.png" />').removeClass('hide').addClass('show');
}
});
});
Here you need to write 2 methods.
jQuery click to display the section on clicking on the arrow and jQuery onmouseleave to hide the section on coming out of the section.
I suggest you to display the slideopen.png and slideclose.png files in the (background style) CSS with respect to the classes.
Method 1: on click
jQuery Code:
$('.slider-arrow').on("click", function(){
if($(this).hasClass('show')){
$( ".slider-arrow, .panel" ).animate({
right: "+=300"
}, 700, function() {
// Animation complete.
}); $(this).html('«').removeClass('show').addClass('hide');
}
});
Method 2: on mouse leave
jQuery Code:
$(".panel").on("mouseleave", function(){
if(!$('.slider-arrow.show').hasClass('show')) {
$( ".slider-arrow, .panel" ).animate({
right: "-=300"
}, 700, function() {
// Animation complete.
});
$(".slider-arrow").removeClass('hide').addClass('show');
}
});
Demo link: http://jsfiddle.net/w9s7pt25/7/
What you can do is add a seperate mouseout function as illustrated in this jsfiddle. The problem with your code was that the mouseover event only acts on .slider-arrow once, changes the class to hide and then expects another mouseover to read that it needs to be hidden.
$(function () {
$('.slider-arrow').mouseover(function () {
if ($(this).hasClass('show')) {
$(".slider-arrow, .panel").animate({
right: "+=300"
}, 700, function () {
// Animation complete.
});
$(this).html('«').removeClass('show').addClass('hide');
}
});
$('.panel').mouseout(function () {
if ($('.slider-arrow').hasClass('hide')) {
$(".slider-arrow, .panel").animate({
right: "-=300"
}, 700, function () {
// Animation complete.
});
$('.slider-arrow').html('»').removeClass('hide').addClass('show');
}
});
});
Hope it makes sense.
You can use mouseout or mouseleave. I guess you would add some elements in panel. So mouseout fires when the pointer moves out of child element as well, while mouseleave fires only when the pointer moves out of the bound element
$('.panel').mouseleave(function() {
if($('.slider-arrow').hasClass('hide')){
$( ".slider-arrow, .panel" ).animate({
right: "-=300"
}, 700);
$('.slider-arrow').html('&raquo').removeClass('hide').addClass('show');
}
});
You can attach the jquery .mouseleave() function on the panel and let it execute only when the panel is visible also add a class like 'visible' to keep state of the visibility of your panel like so: http://jsfiddle.net/gakuru/d2qnrm2x/
$('.panel').on('mouseleave',function(){
if($(this).hasClass('visible')){
$( ".slider-arrow, .panel" ).animate({
right: "-=300"
}, 700, function() {
// Animation complete.
});
$('.slider-arrow').html('»').removeClass('hide').addClass('show');
$('.panel').removeClass('visible');
}
});

How to make a hover function ALSO a click function using javascript

I have a tooltip that can be seen below, at the moment it reveals the tooltip only on hover, but I want it to reveal the tooltip when both hovering and clicking (for touch screen devices) could somebody please show me how?
My JSFiddle
My javascript code
<script type="text/javascript">
$(function(){
$("ul.thumb li").hover(function() {
$(this)
.css('z-index', '10')
.find('img').addClass("hover")
.stop()
.animate({
marginTop: '-150px',
marginLeft: '-150px',
top: '50%',
left: '50%',
width: '300px',
height: '300px',
padding: '20px'
}, 200, function() {
var $this = $(this),
h = $this.height();
$caption = $('<div class="caption">' + this.title + '</div>')
.css('top', h.toString() + 'px');
$this.after($caption);
});
}, function() {
$('.caption').remove();
$(this)
.css('z-index', '0')
.find('img').removeClass("hover")
.stop()
.animate({
marginTop: '0',
marginLeft: '0',
top: '0',
left: '0',
width: '200px',
height: '200px',
padding: '5px'
}, 400);
});
});
</script>
You can create a function, let's call it activate:
function activate(that) {
//Your code here
}
and then use it like this:
$("ul.thumb li").hover(function() {
activate($(this));
});
$("ul.thumb li").click(function() {
activate($(this));
});
Note, that activate will hold the commands you need to process in those events. Also, in activate, try to make sure that you are using that instead of this.
First, refactor and rename your hover in and out function:
function showTooltip(){
$(this)
.css('z-index', '10')
.find('img').addClass("hover")
.stop()
// etc...
}
function hideTooltip(){
$('.caption').remove();
$(this)
.css('z-index', '0')
.find('img').removeClass("hover")
.stop()
// etc...
}
Then instead of using the hover shorthand, use the mouseenter and mouseleave events to listen the hovering:
$("ul.thumb li")
.on('mouseenter', showTooltip)
.on('mouseleave', hideTooltip);
If you want to show the tooltip for touch events, just add the touchstart event to it: I guess you want to tap to both open and close the tooltip.
$("ul.thumb li")
.on('mouseenter touchstart', showTooltip)
.on('mouseleave touchstart', hideTooltip);
You can use jQuery .on() method to bind a handler to multiple events...
First of you need to name the two functions. Then you can use .on() as follows:
$("ul.thumb li").on('mouseover touchstart', show);
$("ul.thumb li").on('mouseleave touchend', hide);
Updated JSFiddle

javascript 'this' issue: programmatically hide jQuery spotlight

I'm trying to augment the (very nice) jQuery Spotlight plugin so that I can programmatically invoke the "hide" behavior.
I've moved the related code into a hide() function, and it works fine when invoked from within spotlight itself. But when I try to invoke it from outside of spotlight nothing happens. I've checked that spotlight.hide is in fact defined to type function, but invoking it seemingly does nothing.
(function($) {
$.fn.spotlight = function(options) {
var hide = function() {
alert('hiding...'); /* never gets invoked when called from outside spotlight */
if(settings.animate){
spotlight.animate({opacity: 0}, settings.speed, settings.easing, function(){
if(currentPos == 'static') element.css('position', 'static');
element.css('z-index', '1');
$(this).remove();
// Trigger the onHide callback
settings.onHide.call(this);
});
} else {
spotlight.css('opacity', '0');
if(currentPos == 'static') element.css('position', 'static');
element.css('z-index', '1');
$(this).remove();
// Trigger the onHide callback
settings.onHide.call(this);
}
};
// Default settings
settings = $.extend({}, {
opacity: .5,
speed: 400,
color: '#333',
animate: true,
easing: '',
exitEvent: 'click',
onShow: function(){},
onHide: function(){}
}, options);
// Do a compatibility check
if(!jQuery.support.opacity) return false;
if($('#spotlight').size() == 0){
// Add the overlay div
$('body').append('<div id="spotlight"></div>');
// Get our elements
var element = $(this);
var spotlight = $('#spotlight');
// Set the CSS styles
spotlight.css({
'position':'fixed',
'background':settings.color,
'opacity':'0',
'top':'0px',
'left':'0px',
'height':'100%',
'width':'100%',
'z-index':'9998'
});
// Set element CSS
var currentPos = element.css('position');
if(currentPos == 'static'){
element.css({'position':'relative', 'z-index':'9999'});
} else {
element.css('z-index', '9999');
}
// Fade in the spotlight
if(settings.animate){
spotlight.animate({opacity: settings.opacity}, settings.speed, settings.easing, function(){
// Trigger the onShow callback
settings.onShow.call(this);
});
} else {
spotlight.css('opacity', settings.opacity);
// Trigger the onShow callback
settings.onShow.call(this);
}
// Set up click to close
spotlight.live(settings.exitEvent, hide);
}
// Returns the jQuery object to allow for chainability.
return this;
};
})(jQuery);
I install it with:
var spotlight = $('#media-fragment').spotlight({
opacity: .5,
speed: 400,
color: '#333',
animate: false,
easing: '',
exitEvent: 'click',
onShow: function(){},
onHide: function(){}
});
And then to hide it I do:
spotlight.hide();
I'm pretty sure that there is a scope or this issue involved.
Update: full solution at https://gist.github.com/2910643.
Try changing:
var hide = function() {
to:
this.hide = function() {
var defines the scope of the function or variable within the parent scope, i.e. it's essentially protected. this on the otherhand will explicitly set it on the parent object, prototype, and make it publicly accessible.

jQuery Selectable Events

I have a jQuery plugin that drags and drops elements into different containers, I want to attach some events, for example when an element is over a container. These events used to work perfectly but then they stopped working. for Some reason the Selectable specific events are not fired, but when i bind a click for example it works.
Example:
//these are not working
$('#sortable2').bind("sortover", function(event, ui) {
alert("here");
});
$('#sortable2').bind('sortreceive', function() {
alert('User clicked on "sortable2."');
});
$('.droptrue').bind("sortout", function(event, ui) {
$(this).css("background", "transparent");
});
The related code is:
var selectedClass = 'ui-state-highlight',
clickDelay = 300, // click time (milliseconds)
lastClick, diffClick; // timestamps
$("ul.droptrue li")
// Script to deferentiate a click from a mousedown for drag event
.bind('mousedown mouseup', function(e){
if (e.type=="mousedown") {
lastClick = e.timeStamp; // get mousedown time
} else {
diffClick = e.timeStamp - lastClick;
if ( diffClick < clickDelay ) {
// add selected class to group draggable objects
$(this).toggleClass(selectedClass);
}
}
})
.draggable({
revertDuration: 10, // grouped items animate separately, so leave this number low
containment: '.multiSelect',
start: function(e, ui) {
ui.helper.addClass(selectedClass);
},
stop: function(e, ui) {
// reset group positions
$('.' + selectedClass).css({ top:0, left:0 });
},
drag: function(e, ui) {
// set selected group position to main dragged object
// this works because the position is relative to the starting position
$('.' + selectedClass).css({
top : ui.position.top,
left: ui.position.left
});
}
});
$("ul.droptrue")
.sortable()
.droppable({
drop: function(e, ui) {
$('.' + selectedClass)
.appendTo($(this))
.add(ui.draggable) // ui.draggable is appended by the script, so add it after
.removeClass(selectedClass)
.css({ top:0, left:0 });
}
});
$('#total').text(autoCompleteSourceArray.length);
$('#filter-count').text(autoCompleteSourceArray.length);
//Adding Filtering functionality for the lists
$("#filter").keyup(function () {
var filter = $(this).val(), count = 0;
$("ul.droptrue:first li").each(function () {
if ($(this).text().search(new RegExp(filter, "i")) < 0) {
$(this).addClass("hidden");
} else {
$(this).removeClass("hidden");
count++;
}
});
$("#filter-count").text(count);
});
// bind events in order to show or hide the message in the drop zones
$('ul[id^="sortable"]').live("sortover", function(event, ui) {
$(this).css("background", "#f7f6d7");
});
$('ul[id^="sortable"]').live("sortout", function(event, ui) {
$(this).css("background", "transparent");
});
Thanks a lot
If you have recently updated to jQuery 1.7+ you should notice that the live() method is deprecated.
As of jQuery 1.7, the .live() method is deprecated. Use .on() to
attach event handlers. Users of older versions of jQuery should use
.delegate() in preference to .live().

Categories

Resources