Jquery hover with .on() - javascript

Im trying to use hover with .on(), but all bits of code and answers i find do not work.
I need to use .on because its Ajax content.
A few ive tried:
$(document).on('mouseenter', '[rel=popup]', function() {
mouseMove = true;
width = 415;
$('#tool-tip').show();
var type = $(this).attr('data-type'),
id = $(this).attr('data-skillid');
console.log("TT-open");
ttAjax(type, id);
}).on('mouseleave', '[rel=popup]', function() {
mouseMove = false;
console.log("TT-close");
$('#tool-tip').hide();
$('#tt-cont').html("");
$('#tt-ajax').show();
});
$('[rel=popup]').on('hover',function(e) {
if(e.type == "mouseenter") {
mouseMove = true;
width = 415;
$('#tool-tip').show();
var type = $(this).attr('data-type'),
id = $(this).attr('data-skillid');
console.log("TT-open");
ttAjax(type, id);
}
else if (e.type == "mouseleave") {
mouseMove = false;
console.log("TT-close");
$('#tool-tip').hide();
$('#tt-cont').html("");
$('#tt-ajax').show();
}
});
$('[rel=popup]').on("hover", function(e) {
if (e.type === "mouseenter") { console.log("enter"); }
else if (e.type === "mouseleave") { console.log("leave"); }
});
$(document).on({
mouseenter: function () {
console.log("on");
},
mouseleave: function () {
console.log("off");
}
}, "[rel=popup]"); //pass the element as an argument to .on
The original non .on:
$('[rel=popup]').hover(function(){
mouseMove = true;
width = 415;
$('#tool-tip').show();
var type = $(this).attr('data-type'),
id = $(this).attr('data-skillid');
console.log("TT-open");
ttAjax(type, id);
},function () {
mouseMove = false;
console.log("TT-close");
$('#tool-tip').hide();
$('#tt-cont').html("");
$('#tt-ajax').show();
})
All the .on return "TypeError: $(...).on is not a function". I am using version 1.9.1.

The events you're looking for may be
$("#id").mouseover(function(){});
or
$("#id").mouseout(function(){});

There was an answer with:
$(document).on({
mouseenter: function () {
console.log("on");
},
mouseleave: function () {
console.log("off");
}
},"[rel=popup]");
This worked, and for some reason I have JQ 1.4 in a 1.9.1 named file that was causing the problem.

Related

Remove event listener not working with Javascript

I try to remove an event listener with Javascript, but it seems not working.
I need to pass the object event in the handler so this is why I'm using .bind().
My code :
if (sidebar) {
listItems.forEach(function(listItem) {
listItem.showSubmenu = showSubmenu;
listItem.addEventListener('click', listItem.showSubmenu.bind(this, subLists), true);
});
if (sidebarButton) {
sidebarButton.addEventListener('click', onClickOnButton.bind(this, sidebar));
}
}
if (sidebar.getAttribute('data-reduce') === 'true') {
listItems.forEach(function(listItem) {
listItem.removeEventListener('click', listItem.showSubmenu, true);
});
}
function showSubmenu(subLists, e) {
var target = e.currentTarget,
subList = target.querySelector('.sidebar__sublist');
if (subList) {
if (subList.style.display !== 'block') {
[...subLists].forEach(hideSubList);
$(subList).slideDown('slow', function() {
subList.style.display = 'block';
target.querySelector('.sidebar__list__item__link__arrow').textContent = 'keyboard_arrow_up';
});
} else {
$(subList).slideUp('slow', function() {
subList.style.display = 'none';
target.querySelector('.sidebar__list__item__link__arrow').textContent = 'keyboard_arrow_down';
});
}
}
}
Result : The event is not removed.
as #GACy20 said listItem.showSubmenu is not the same as listItem.showSubmenu.bind(this, subLists)
try doing it like this
listItem.showSubmenu = showSubmenu.bind(this, subLists);
listItem.addEventListener('click', listItem.showSubmenu, true);

Jquery drop not fired

I need to fire the drop part so that when user drop a file it uploads. But in my code drop not firing.
Please give me the corrected version of this code. This is really very important for my project. This code is taken from another stackoverflow post. And I have edited the drop part at the code given below.
User's answer will be appreciated.
$.fn.dndhover = function(options) {
return this.each(function() {
var self = $(this);
var collection = $();
self.on('dragenter', function(event) {
if (collection.length === 0) {
self.trigger('dndHoverStart');
}
collection = collection.add(event.target);
});
self.on('dragleave', function(event) {
/*
* Firefox 3.6 fires the dragleave event on the previous element
* before firing dragenter on the next one so we introduce a delay
*/
setTimeout(function() {
collection = collection.not(event.target);
if (collection.length === 0) {
self.trigger('dndHoverEnd');
}
}, 1);
});
self.on('drop', function(event) {
alert(event);
self.trigger('dndHoverDrop');
});
});
};
$('.uploadDiv').dndhover().on({
'dndHoverStart': function(event) {
if(!$(".selectFile").hasClass("hide")){
$(".selectFile").addClass("hide");
}
if($(".dropFile").hasClass("hide")){
$(".dropFile").removeClass("hide");
}
event.stopPropagation();
event.preventDefault();
return false;
},
'dndHoverEnd': function(event) {
if($(".selectFile").hasClass("hide")){
$(".selectFile").removeClass("hide");
}
if(!$(".dropFile").hasClass("hide")){
$(".dropFile").addClass("hide");
}
event.stopPropagation();
event.preventDefault();
return false;
},
'dndHoverDrop': function(event) {
alert('dropped');
if(!$(".selectFile").hasClass("hide")){
$(".selectFile").addClass("hide");
}
if(!$(".dropFile").hasClass("hide")){
$(".dropFile").addClass("hide");
}
event.preventDefault();
event.stopPropagation();
return false;
}
});
New Code:
$.fn.dndhover = function(options) {
return this.each(function() {
var self = $(this);
var collection = $();
self.on('dragenter', function(event) {
if (collection.length === 0) {
self.trigger('dndDragEnter');
}
collection = collection.add(event.target);
});
self.on('dragleave', function(event) {
/*
* Firefox 3.6 fires the dragleave event on the previous element
* before firing dragenter on the next one so we introduce a delay
*/
setTimeout(function() {
collection = collection.not(event.target);
if (collection.length === 0) {
self.trigger('dndDragLeave');
}
}, 1);
});
self.on('dragover', function(event) {
setTimeout(function() {
collection = collection.not(event.target);
if (collection.length === 0) {
self.trigger('dndDragOver');
}
}, 1);
});
self.on('drop,dragdrop', function(event) {
self.trigger('dndDragDrop');
});
});
};
$('.uploadDiv').dndhover().on({
'dndDragEnter': function(event) {
if(!$(".selectFile").hasClass("hide")){
$(".selectFile").addClass("hide");
}
if($(".dropFile").hasClass("hide")){
$(".dropFile").removeClass("hide");
}
event.stopPropagation();
},
'dndDragLeave': function(event) {
if($(".selectFile").hasClass("hide")){
$(".selectFile").removeClass("hide");
}
if(!$(".dropFile").hasClass("hide")){
$(".dropFile").addClass("hide");
}
},
'dndDragDrop': function(event) {
alert('dropped');
if(!$(".selectFile").hasClass("hide")){
$(".selectFile").addClass("hide");
}
if(!$(".dropFile").hasClass("hide")){
$(".dropFile").addClass("hide");
}
alert(event);
event.preventDefault();
},
'dndDragOver': function(event) {
if(!$(".selectFile").hasClass("hide")){
$(".selectFile").addClass("hide");
}
if($(".dropFile").hasClass("hide")){
$(".dropFile").removeClass("hide");
}
event.preventDefault();
}
});

How to run a child event only once

I want to do mouseleave only once after focus triggered. How?
I try several options like off,preventDefault,stopPropagation, return false; but none have worked.
Thank you in advance.
addEvent(date, 'focus', function () {
console.log("focuz" + this.innerHTML);
document.designMode = 'on';
addEvent(swap_date, 'mouseleave', function (e) {
console.log("mouseleave" + this.innerHTML);
//document.designMode = 'on';
$(this).off(e);
e.preventDefault();
e.stopPropagation();
return false;
});
});
fixed in mouseenter event to trigger the check with stop var.
Once mouseleave happends, the stop is on.
addEvent(swap_date, 'mouseenter', function () {
stop = false;
});
addEvent(swap_date, 'focus', function () {
document.designMode = 'on';
if (this.innerHTML != "") {
$(document).ready(function () {
$('.swapDate').bind('mouseleave', function (event) {
if (!stop && this.innerHTML != "")
checkDate(this.innerHTML);
stop = true;
$('.swapDate').unbind('mouseleave');
});
});
}
});

How can I stop JS triggering when scrolling on touch devices

At the moment we are using the below script to create a lightweight lightbox for a wordpress site, which works perfectly on desktop, but the overlay is being triggered when just scrolling on a touch device if you scroll with your finger on one of the images, is there anyway to stop this happening?
<script>
var WHLightbox = {
settings: {
overlay: $('.portfolio-tile--overlay'),
imageCell: $('.cell-image, .portfolio-tile--image')
},
data: {
images: []
},
init: function() {
this.events();
this.buildImageData();
},
events: function() {
var self = this;
this.settings.imageCell.on('click touchend', function(e) {
e.preventDefault();
e.stopPropagation();
// set up the overlay
self._positionOverlay();
self._openOverlay();
self._preventScrolling();
// create the image slide
self._createImageSlide($(this));
});
this.settings.overlay.on('click touchend', function(e) {
e.preventDefault();
e.stopPropagation();
self._closeOverlay();
});
$('.portfolio-tile--overlay--controls--prev, .portfolio-tile--overlay--controls--next').on('click touchend', function(e) {
e.preventDefault();
e.stopPropagation();
});
$('.portfolio-tile--overlay--controls--prev').on('click touchend', function(e) {
e.preventDefault();
e.stopPropagation();
self.showPrev();
});
$('.portfolio-tile--overlay--controls--next').on('click touchend', function(e) {
e.preventDefault();
e.stopPropagation();
self.showNext();
});
},
// public functions
showPrev: function() {
var index = this.currentImageIndex();
if(index === 0) {
index = this.data.images.length;
}
this._createImageSlide(false, index-1);
},
showNext: function() {
var index = this.currentImageIndex();
if(index === this.data.images.length-1) {
// set to -1 because it adds 1 in the _createImageSlide call
index = -1;
}
this._createImageSlide(false, index+1);
},
currentImageIndex: function() {
if(this.settings.overlay.hasClass('open')) {
var imageUrl = $('.portfolio-tile--main-image').attr('src');
for(var i=0; i<this.data.images.length; i++) {
if(this.data.images[i].imageUrl === imageUrl) {
return i;
}
}
} else {
return false;
}
},
// image data
buildImageData: function() {
var self = this,
i = 0;
this.settings.imageCell.each(function() {
self.data.images[i] = {
imageUrl: self._getImagePath($(this))
}
i++;
});
},
// slide
_createImageSlide: function($el, index) {
var imagePath;
if(!$el) {
imagePath = this.data.images[index].imageUrl;
} else {
imagePath = this._getImagePath($el);
}
this.settings.overlay.find('.portfolio-tile--main-image').attr('src', imagePath);
},
_getImagePath: function($el) {
var imagePath,
spanEl = $el.find('span.js-cell-image-background'),
imgEl = $el.find('img.cell-image__image');
if(spanEl.length) {
imagePath = spanEl.css('backgroundImage');
imagePath = imagePath.replace('url(', '').replace(')', '');
} else if(imgEl.length) {
imagePath = imgEl.attr('src');
}
return imagePath;
},
// overlay
_positionOverlay: function() {
this.settings.overlay.css({
// position the overlay to current scroll position
top: $(window).scrollTop()
});
},
_openOverlay: function() {
this.settings.overlay.addClass('open');
},
_preventScrolling: function() {
$('html, body').addClass('no-scroll');
},
_reInitScrolling: function() {
$('html, body').removeClass('no-scroll');
},
_closeOverlay: function() {
this.settings.overlay.removeClass('open');
this._reInitScrolling();
}
};
WHLightbox.init();
</script>
You could use a library such as Modernizr to detect touch take a look at the answer to this question on detecting touch What's the best way to detect a 'touch screen' device using JavaScript?
With Modernizr only:
if (Modernizr.touch) {
alert('Touch Screen');
} else {
alert('No Touch Screen');
}
or with the use of jQuery & Modernizr you can do something like:
if($('html').hasClass('touch') === false) {
//run your code here
}
Thank you for your reply aharen, I managed to get it working by just changing touchend to tap and it seems to be working as intended now.

jQuery search toggle

on my website I have a div .toggle-search that if you click on it it expands to .search-expand where a search form is. This is the code in jQuery
/* Toggle header search
/* ------------------------------------ */
$('.toggle-search').click(function(){
$('.toggle-search').toggleClass('active');
$('.search-expand').fadeToggle(250);
setTimeout(function(){
$('.search-expand input').focus();
}, 300);
});
Now the only way to close the .search-expand is to click once again on the .toggle-search. But I want to change that it closes if you click anywhere else on the site. For an easier example I have the Hueman theme, and I'm talking about the top right corner search option. http://demo.alxmedia.se/hueman/
Thanks!
Add the event on all elements except the search area.
$('body *:not(".search-expand")').click(function(){
$('.toggle-search').removeClass('active');
$('.search-expand').fadeOut(250);
});
or another way,
$('body').click(function(e){
if(e.target.className.indexOf('search-expand') < 0){
$('.toggle-search').removeClass('active');
$('.search-expand').fadeOut(250);
}
});
var isSearchFieldOpen = false;
var $toggleSearch = $('.toggle-search');
var $searchExpand = $('.search-expand');
function toggleSearch() {
// Reverse state
isSearchFieldOpen = !isSearchFieldOpen;
$toggleSearch.toggleClass('active');
// You can use callback function instead of using setTimeout
$searchExpand.fadeToggle(250, function() {
if (isSearchFieldOpen) {
$searchExpand.find('input').focus();
}
});
}
$toggleSearch.on('click', function(e) {
e.stopPropagation();
toggleSearch();
});
$(document.body).on('click', function(e) {
if (isSearchFieldOpen) {
var target = e.target;
// Checking if user clicks outside .search-expand
if (!$searchExpand.is(target) && !$searchExpand.has(target).length) {
toggleSearch();
}
}
});
I have a second search on the site with the same code as before only
with div .toggle-serach2 and .expand-search2, how can i make your code
so it wont overlap. just changing the name to $('toggle-search2')
doesn't cut it
in that case, I would suggest you convert your code into a plugin:
(function($, document) {
var bodyHandlerAttached = false;
var openedForms = [];
var instances = {};
var defaults = {
activeClass: 'active'
};
function ToggleSearch(elem, options) {
this.options = $.extend({}, defaults, options);
this.$elem = $(elem);
this.$btn = $(options.toggleBtn);
this.isOpen = false;
this.id = generateId();
this.bindEvents();
instances[this.id] = this;
if (!bodyHandlerAttached) {
handleOutsideClick();
bodyHandlerAttached = true;
}
}
ToggleSearch.prototype = {
bindEvents: function() {
this.$btn.on('click', $.proxy(toggleHandler, this));
},
open: function() {
if (this.isOpen) { return; }
var _this = this;
this.$btn.addClass(this.options.activeClass);
this.$elem.fadeIn(250, function() {
_this.$elem.find('input').focus();
});
openedForms.push(this.id);
this.isOpen = true;
},
close: function(instantly) {
if (!this.isOpen) { return; }
this.$btn.removeClass(this.options.activeClass);
if (instantly) {
this.$elem.hide();
} else {
this.$elem.fadeOut(250);
}
openedForms.splice(openedForms.indexOf(this.id), 1);
this.isOpen = false;
},
toggle: function() {
if (this.isOpen) {
this.close();
} else {
this.open();
}
}
};
var toggleHandler = function(ev) {
ev.stopPropagation();
this.toggle();
};
var handleOutsideClick = function(e) {
$(document.body).on('click', function(e) {
if (openedForms.length) {
var target = e.target;
var instance;
for (var id in instances) {
instance = instances[id];
if (!instance.$elem.is(target) && !instance.$elem.has(target).length) {
instance.close(true);
}
}
}
});
};
function generateId() {
return Math.random().toString(36).substr(2, 8);
}
$.fn.toggleSearch = function(options) {
return this.each(function() {
if (!$.data(this, 'toggleSearch')) {
$.data(this, 'toggleSearch', new ToggleSearch(this, options));
}
});
};
})(window.jQuery, document);
And then use it like this:
$('.search-expand').toggleSearch({
toggleBtn: '.toggle-search'
});
$('.search-expand2').toggleSearch({
toggleBtn: '.toggle-search2'
});
JSFiddle example
You could add a click handler to the main window that removes the active class:
$(window).click(function(){
$('.toggle-search').removeClass('active');
}
and then prevent the class removal when you click inside of your toggle-search elem
$('.toggle-search').click(function(e){
e.stopPropagation();
// remainder of click code here
)};
Try to add body click listener
$('body').click(function(e){
if ($(e.target).is('.toggle-search')) return;
$('.toggle-search').removeClass('active');
$('.search-expand').fadeOut(250);
});

Categories