Woocommerce functionality is inhibited after AJAX page transition - javascript

I have an ajax transition which is this:
function fadeTransition(href = window.location.href) {
$('.fader').css({
'position': 'fixed',
// 'height': h,
'height': '100vh',
'width': '0',
'left': '0',
'top': '0',
'color': 'black',
'background-color': 'black',
'z-index': '300'
}).animate({
'width': '100vw',
}, 400, function() {
$('.slider-transition').load(href + ' .slider-transition', function() {
// EXECUTES ON CALLBACK
// $('.slider-transition').children('.slider-transition').unwrap();
// h = $(document).height();
$('.fader').animate({
'left': '100vw'
}, 400, function() {
slideShowInit();
initParalax();
$('.woocommerce-product-gallery').each(function() {
$(this).wc_product_gallery();
});
$('.slider-transition').children('.slider-transition').unwrap();
// $('.slider-transition').parents('.slider-transition').unwrap();
});
});
});
}
It's a simple transition that loads the element from the next page into the element of the current page and by attaching all of the click events to the body as such:
$('body').on('click', '.main-menu li a, nav a, a.button, a.square, a.grow', function(event) {
event.preventDefault();
event.stopPropagation();
});
$("li").on("click", "a", function(event) {
var _href = $(this).attr("href");
history.pushState(null, null, _href);
fadeTransition(_href);
});
I've been able to circumnavigate the problem of click events being destroyed after the transition. The only problem that with the Woocommerce plugin in Wordpress, I can't possibly hope to traverse the entire assets folder of JS and replace
$('.a').on('click', function() {});
with
$('.body').on('click', 'a', function() {});
and attach all of the DOM events to the body like this and even then I'm only 70% sure this is the problem, does anyone know a way around this?

Remove an event handler with jQuery using off()
With jQuery to stop/remove existing "click" delegated event that interfere with your own custom click event, you could try to use off(), which is likely the contrary of on().
So with your code it should be:
jQuery(function($){
$(document.body).off('click', 'a');
$("li").on("click", "a", function(event) {
var _href = $(this).attr("href");
history.pushState(null, null, _href);
fadeTransition(_href);
});
});
It could solve your issue.

Related

Grabbing html of div that has been 'echoed' from AJAX call to PHP

I am trying to load a dropdown menu from a server and then use jQuery to interact with that dropdown. Everything loads fine, but I can't interact with the menu items as they weren't part of the original HTML that was loaded, they were entered after AJAX got its response.
Here's the ajax code:
$(document).ready(function(){
//load dropdown menu using ajax
$.ajax({ url: "default/CallSupplierMongo",
context: document.body,
success: function (res) {
document.getElementById("dropdownItems").innerHTML = res;
}
});
});
The jQuery:
$(document).load(function() {
$('.dropdownItems > div').click(function () {
supplierCode = $(this).html();
$('.dropdownItems > div').css({
'background-color': 'white',
'color': '#888888'
});
$(this).css({
'background-color': '#888888',
'color': 'white'
});
$('.dropdownItems').slideUp('fast');
$('.dropdownButton').html(supplierCode);
$('.dropdownButton').css({
'border-bottom-right-radius': '5px',
'border-bottom-left-radius': '5px'
})
});
});
And the PHP:
function actionCallSupplierMongo() {
self::getSuppliers();
}
private static function echoSupplierCodes($supplierCodes) {
for ($i=0;$i<count($supplierCodes);++$i) {
echo '<div>'.$supplierCodes[$i].'</div>';
}
}
To explain the issue further: I want to click on the dropdown items and grab the HTML inside it. When I click, nothing is registered. I believe that's because jQuery checks to see if those <div>s exist before they are loaded and thus doesn't apply the .click function to them.
EDIT I've tried putting the AJAX call in $(document).load() but it still has no effect.
Problem:
When you initially load your page, your JS code attaches the events (such as click()) to the elements that are currently on the DOM, but when you load new elements to the DOM through AJAX, those new elements do not have any events binded to them. Thus the events in JS not working.
Solution:
You need to delegate the event handler.
Change this:
$('.dropdownItems > div').click(function () {
To this:
$(document).on('click', '.dropdownItems > div', function () {
Source: http://api.jquery.com/delegate/
The problem is that you're attaching click event handlers to items that don't exist yet.
You should use the jQuery's event delegation, e.g:
$('.dropdownItems').on('click', '> div', function () {
Note: If, for some reason, you don't want to use event delegation, and prefer to attach the events to the elements themselves, you must put the ready's code you have into a function, and instead of calling the function when the page is ready, you must call it anytime you modify the collection.
$('.dropdownItems > div').click(function () {
Replace this with
$(document).on('click', '.dropdownItems > div', function() {
The answer was to call the function on success of the response from the AJAX call.
$.ajax({ url: "default/CallSupplierMongo",
context: document.body,
success: function (res) {
document.getElementById("dropdownItems").innerHTML = res;
loadDropdownFunctions();
}
});
function loadDropdownFunctions() {
$('.dropdownItems > div').click(function () {
supplierCode = $(this).html();
$('.dropdownItems > div').css({
'background-color': 'white',
'color': '#888888'
});
$(this).css({
'background-color': '#888888',
'color': 'white'
});
$('.dropdownItems').slideUp('fast');
$('.dropdownButton').html(supplierCode);
$('.dropdownButton').css({
'border-bottom-right-radius': '5px',
'border-bottom-left-radius': '5px'
})
});

Callback complete function not working properly using transit js and jQuery.

So
I am trying to build some navigation using jquery transit
The opens/slide down navigation is working fine. It sets the child ul to display block and then runs the animation/transition.
The issue is occurring when closing the navigation item. The ul gets hidden immediately diespite being written inside the callback. I've also added a console log of 'animation ended' once the transition has finished and this is firing at the right time, so not sure why the ul is being hidden immediately.
The jquery/js looks like this:
var dropDown = (function(){
var mainNav = $('#mainNav');
var navA = mainNav.find('li a');
var navUL = mainNav.find('ul');
var iconAll = mainNav.find('i');
navUL.transition({
'max-height': '0px',
'height': '0px',
'overflow': 'hidden',
'display': 'none'
});
navA.on('click',function(){
var nextUL = $(this).next();
var icon = $(this).find('i');
var nextULHidden = nextUL.css('display') === 'none';
if(nextULHidden) {
nextUL.css('display','block').transition({
duration: 1000,
'height': 'auto',
'max-height': '1000px',
easing: 'ease-in'
});
$(this).addClass('active');
icon.removeClass('fa-chevron-down').addClass('fa-chevron-up');
console.log('hidden');
}else if(!nextULHidden){
nextUL.transition({
duration: 1000,
'height': '0px',
'max-height': '0px',
easing: 'ease-in',
complete: function(){
nextUL.css('display','none');
console.log('animation ended');
}
});
$(this).removeClass('active');
icon.removeClass('fa-chevron-up').addClass('fa-chevron-down');
console.log('visible');
}else{
console.log('some error');
}
return false;
});
}());
And I have a fiddle here that can be tinkered with: http://jsfiddle.net/lharby/o5w8ebu8/2/
I've tried various combinations of using css visibility, jquery show() and hide() functions, but each time the ul vanishes as the transition starts (on click effectively). And I've tested Chrome, Firefox and Safari just in case there were any anomalies.
I believe the callback is firing at the correct time (after 1000 milliseconds) the problem is that the transition animation isn't working.
Changing to 'height': 'auto' on the shrinking transition seems to achieve the effect you are after. Though I can't say I really know why.

Need to prevent mousehover over click in jquery

Hi have the following code:
$('img').on("mouseenter",function(){
//show overlay
});
$("#overlay").on("click",function(event) {
event.preventDefault();
//hide overlay
})
When i click on the overlay, it should close. But when i happen to be over an image it does not close.I receive both mouseclick and mouseenter events
How do i prevent this?
I am using jquery 1.10.2
When you are on image, it first goes in click event then mouseenter event. So, click event hides then mouseenter shows again. So, you can not hide layout when you are on the img. But, if you disable mouseenter event of img in a short duration, the problem will be solved in Chrome and FF.
As in jsfiddle change your js function as :
$(function() {
var docHeight = $(document).height();
$("body").append("<div id='overlay'></div>");
$("#overlay")
.height(docHeight)
.css({
'opacity' : 0.4,
'position': 'absolute',
'top': 0,
'left': 0,
'background-color': 'black',
'width': '100%',
'background-repeat':'no-repeat',
'background-attachment':'fixed',
'background-position':'center',
'z-index': 5000
}).on("click",function(e) {
hideOverlay();
unbindImgMouseEnter();
setTimeout(bindImgMouseEnter, 100);
}).hide();
bindImgMouseEnter();
});
function bindImgMouseEnter(){
$('img').on("mouseenter", showOverlay);
}
function unbindImgMouseEnter(){
$('img').off("mouseenter");
}
function showOverlay(){
$("#overlay").show();
console.log('showed');
}
function hideOverlay(){
$("#overlay").hide();
console.log('hidden');
}
Remove the mouseenter event, when you click the overlay.
$("#overlay").on("click",function(event) {
$('img').off("mouseenter"); // Remove the mouseenter event handler
event.preventDefault();
//hide overlay
});
Suggestion: better use .hover instead of mouseenter
$('img').on("hover",function(){
//show overlay
});
$("#overlay").on("click",function(event) {
$('img').off('hover');
event.preventDefault();
//hide overlay
})

Jquery, Codeigniter 2.1 - pagination issues

I am creating pagination using Codeigniter, and I want to add ajax functionality. JS is working when pagination link is clicked first time. When it is clicked for the second time JS doesn't work and pagination is working via PHP controller (this part is working without any problem). This is JS code:
var pag = $('#pagination a');
pag.on('click', function(e){
var pagination =
{
target : $(this).attr('href') + ' .mali_oglasi',
content : $('.mali_oglasi'),
container: $('.mali_oglasi_wrapper')
};
pagination.content.animate({'opacity':0, scrollTop: 0}, 400, function(){
pagination.container.load(pagination.target, function(){
pagination.content.animate({'opacity':1}, 400);
});
});
e.preventDefault();
});
Also scrollTop doesn't work. What am I doing wrong?
Probably that's because your DOM gets manipulated everytime, and hence the handler for the click event is lost.
try this way :
$('body').on('click', '#pagination a', function(e) {
var pagination =
{
target : $(this).attr('href') + ' .mali_oglasi',
content : $('.mali_oglasi'),
container: $('.mali_oglasi_wrapper')
};
pagination.content.animate({
'opacity':0,
scrollTop: 0
}, 400, function(){
pagination.container.load(pagination.target, function(){
pagination.content.animate({
'opacity':1
}, 400);
});
});
e.preventDefault();
});
this will ensure rebinding the click event on each DOM manipulation
try this bro..
maybe the element was not yet loaded...
var pag = $('#pagination a');
pag.on('click', 'a', function(e){
var pagination =
{
target : $(this).attr('href') + ' .mali_oglasi',
content : $('.mali_oglasi'),
container: $('.mali_oglasi_wrapper')
};
pagination.content.animate({'opacity':0, scrollTop: 0}, 400, function(){
pagination.container.load(pagination.target, function(){
pagination.content.animate({'opacity':1}, 400);
});
});
e.preventDefault();
});

Can't use nested anchor

Ok. I've got the following script:
$('#exhibitions .item.plain').toggle(
function() {
$(this).css({
'height': '302px',
'z-index': '10',
'background': '#3F94AB'
});
$(this).find('p.title').css('color', '#E6E6E6');
$container.isotope('reLayout');
},
function() {
$(this).css({
'height': "130px",
'z-index': '0',
'background': '#CCC'
});
$(this).find('p.title').css('color', '#353334');
$container.isotope('reLayout');
});
Whereas .item.plain is given to a div with nested anchor. And when I click it which is obvious )) toggle() is fired.
<div class="item plain">
<!-- some stuff -->
</div>
How do I fix this?
Thanks!
If I well understood you don't want to toggle the element .item.plain when you click over the link, so stop the propagation of the event in this way
$('#exhibitions .item.plain a').on('click', function(evt) {
evt.stopPropagation();
});

Categories