Working with DOM after AJAX call - javascript

I have this function:
$('body').on('click', '.kategorija_izbor ul a, .mali_oglas a[role=pretraga]', function(e){
var mgl_wrapper = $('.mali_oglasi_wrapper'),
mgl = $(".mali_oglasi"),
mgl_space = $(this).attr('href').replace(/\s+/g, '-').toLowerCase();
link = mgl_space + ' .mali_oglasi';
mgl.animate({'opacity' : 0}, 400, function(){
mgl_wrapper.load(link, function(){
mgl.animate({'opacity' : 1}, 400);
});
});
e.preventDefault();
});
It is working, but I would like to know is there another way to do it. It seems to me that this way is time consuming and resource inefficient. Every time page is clicked script is going through DOM and search for specific elements. Is there a way to store .kategorija_izbor ul a and .mali_oglas a[role=pretraga] (they are bout loaded via load function )?
EDIT I
.kategorija_izbor ul a and .mali_oglas a[role=pretraga] are children of mgl_wrapper *( $('.mali_oglasi_wrapper')), and they are dynamically created every time they are clicked.

If the elements are only being loaded into mgl, just restrict the click handler's scope so jQuery doesn't have to search through the entire body:
var $mgl_wrapper = $('.mali_oglasi_wrapper');
var $mgl = $('.mali_oglasi');
$mgl.on('click', '.kategorija_izbor ul a, .mali_oglas a[role=pretraga]', function(e) {
var mgl_space = this.href.replace(/\s+/g, '-').toLowerCase();
$mgl.animate({'opacity' : 0}, 400, function() {
$mgl_wrapper.load(mgl_space + ' .mali_oglasi', function() {
$mgl.animate({'opacity' : 1}, 400);
});
});
e.preventDefault();
});

Related

How to create a slideshow with drag drop clones

I want to create a page where the user can choose the images that will be shown in a slideshow. I am attempting to use mootools drag and drop and would like to use lightgallery.js.
How can I pass an array of dropped images into the dynamicEL?
Is there a way to load the images using the id/class of #cart.item?
Any help is greatly appreciated. And apologies in advance for being new at coding.
Here is a codepen that only seems to be slightly working http://codepen.io/ssab/pen/QGyKVO
$(function() {
jQuery('#dynamic').on('click', function() {
var selected_image = [];
jQuery( "#cart.item img" ).each(function() {
var item1 = {
src: $(this).find('img').attr('src'),
thumb: $(this).find('img').attr('data-thumb'),
subHtml: '<h4></h4>'
};
selected_image.push(item1);
});
jQuery(this).lightGallery({
dynamic: true,
dynamicEl: selected_image
})
});
});
var drop = $('cart');
var dropFx = drop.effect('background-color', {wait: false}); // wait is needed so that to toggle the effect,
$$('.item').each(function(item){
item.addEvent('mousedown', function(e) {
e = new Event(e).stop();
var clone = this.clone()
.setStyles(this.getCoordinates()) // this returns an object with left/top/bottom/right, so its perfect
.setStyles({'opacity': 0.7, 'position': 'absolute'})
.addEvent('emptydrop', function() {
this.remove();
drop.removeEvents();
}).inject(document.body);
drop.addEvents({
'drop': function() {
drop.removeEvents();
clone.remove();
item.clone().inject(drop);
dropFx.start('7389AE').chain(dropFx.start.pass('ffffff', dropFx));
},
'over': function() {
dropFx.start('98B5C1');
},
'leave': function() {
dropFx.start('ffffff');
}
});
var drag = clone.makeDraggable({
droppables: [drop]
}); // this returns the dragged element
drag.start(e); // start the event manual
});
});
You can launch light box in two ways.
when dropping item you can populate array for dynamicEl, or
when dynamic button clicked create array of elements.
Here option 2 implemented:
http://codepen.io/imranweb7/pen/zorRLG?editors=1111
The logic behind this implementations as per as the html you copied to dropped area.
Please let me know for any explanations.

Jquery onclick function not being called

I have this function in my global.js file, code below:
$("a.dialog-page").click(function(event) {
event.preventDefault();
$this = $(this);
var URL = $(this).attr('href');
var dialogbox = document.getElementById('dialog');
var dialogOptions = {
width: 500,
height: 200,
modal: true,
close: function(event, ui){
$('#dialog').empty();
}
};
if(dialogbox==null) {
$this.after("<div id=\"dialog\"></div>");
}
jQuery('#dialog').load(URL + " #content").dialog(dialogOptions);
});
I have dynamically generated HTML with the following markup:
<div id="dynamic-id">
<a class="dialog-page" href="/test/test.php">Link to test</a>
</div>
Here is the click trigger for that link coming from my local.js file:
$('#dynamic-id').on('click', 'a.dialog-page', function(event){
event.preventDefault;
});
The problem is when clicking on the link, it is not calling ("a.dialog-page").click event which would load up my modal window.
How can I address this?
Thanks
Cheers
Since #dynamic-id is also generated dynamically, you need to use other static parent like body:
$('body').on('click', 'a.dialog-page', function(event){
event.preventDefault;
});
Element #dynamic-id is also generated dynamically.
So when you are binding the element the element #dynamic-id doesnot exist in DOM while you are binding the event to it .
TO fix this you can use as follows
$(document).on('click', 'a.dialog-page', function(event){
alert("Link clicked");
event.preventDefault;
});
Try this -
$('#dynamic-id').on('click', 'a.dialog-page', function(event){
event.preventDefault;
$this = $(this);
var URL = $(this).attr('href');
var dialogbox = document.getElementById('dialog');
var dialogOptions = {
width: 500,
height: 200,
modal: true,
close: function(event, ui){
$('#dialog').empty();
}
};
if(dialogbox==null) {
$this.after("<div id=\"dialog\"></div>");
}
jQuery('#dialog').load(URL + " #content").dialog(dialogOptions);
});
Reason for not working -
$("a.dialog-page").click(function(event) {
and
$('#dynamic-id').on('click', 'a.dialog-page', function(event){
are basically the same. so when you are executing the second line you are overriding the previous onclick event. You can use any one of them and you should be just fine. Here is the fiddle.. http://jsfiddle.net/KytV8/
You just need to target an element that exists on pageload and use the on() function
$('#container').on('click', '.element', function(){ });
The way you were originally trying to do it, the click listener doesn't get set since when it's applied, it can't find the element it's trying to listen to.
To me it looks like you are defining the click event statically, which will never be triggered by the A tag since it's not being attached to the dynamic content, then defining and attaching a new click after the dynamic data is loaded that only stops the event. I would change it to this, as also alluded to by Pointy's comment:
<div id="dynamic-id">
<a class="dialog-page" href="/test/test.php">Link to test</a>
</div>
$('#dynamic-id').on('click', 'a.dialog-page', function(event){
event.preventDefault();
$this = $(this);
var URL = $(this).attr('href');
var dialogbox = document.getElementById('dialog');
var dialogOptions = {
width: 500,
height: 200,
modal: true,
close: function(event, ui){
$('#dialog').empty();
}
};
if(dialogbox==null) {
$this.after("<div id=\"dialog\"></div>");
}
jQuery('#dialog').load(URL + " #content").dialog(dialogOptions);
});

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();
});

jQuery delegate not working

My script:
(function($){
$.fn.megaswitcher = function(settings) {
return this.each(function() {
var $i = $(this),
current,
childs = $i.find('.selection li').length; // returns desired number
$i.find('.selection li').delegate('.active', 'dblclick', function(e){
e.preventDefault();
current = $i.find('.selection li').index(this);
alert('triggered # ' + current); // doesn't even execute
var _delay = $(this).attr('name') > 0 ? (parseInt($(this).attr('name')) * 1000) : 5000;
$(this).delay(_delay).show(0, function(){
if((current + 1) < childs){ // if not last
$(this).removeClass('active').next().addClass('active').show(0, function(){
$i.find('.image img').addClass('tempp');
$(this).find('img').clone().hide().addClass('temp').appendTo($i.find('.image')).fadeIn(400, function(){
$i.find('.image img.tempp').remove();
});
}).trigger('dblclick');
}else{
$(this).removeClass('active');
$i.find('.selection li:first').addClass('active').show(0, function(){
$i.find('.image img').addClass('tempp');
$(this).find('img').clone().hide().addClass('temp').appendTo($i.find('.image')).fadeIn(400, function(){
$i.find('.image img.tempp').remove();
});
}).trigger('dblclick');
}
});
});
$i.find('.selection li.active').trigger('dblclick');
});
};
})(jQuery);
Gotta admit, that, that's a huge mess over there, but I have no idea why that delegate is not working...
Any ideas?
P.S. I have a different plugin based on this same technique with dblclick, that works flawlessly, except, it doesn't do item selection with find();, and I have a feeling that it's the thing that's causing the problem, but I don't know with that to replace it.
Thanks in advance!
You have to call delegate on the parent of the items that you want to attach the event.
Instead of:
$i.find('.selection li').delegate('.active' ...
you should do
$i.find('.selection').delegate('li.active'

Scrolling and .addClass(); issues

I am working on a "one page" website with a fixed navigation and about 5 different pages inside the one document.
UPDATED WORKING LINK
http://www.coco-works.com/Archive/ LIVE VERSION
I'm having trouble with the active class addition. When you click Keep in Touch or Home, the class is not applied. As you can see from the live version, it's not function properly.
The page works something like this;
And here is the JavaScript;
$(document).ready(function() {
$('body').click(function(event) {
if (event.target.nodeName.toLowerCase() == 'a') {
var op = $(event.target);
var id = op.attr('href');
if (id.indexOf('#') == 0) {
$.scrollTo(id, 1000, {
offset: {
top: 75
},
axis: 'y',
onAfter: function() {
window.location.hash = id.split('#')[1];
}
});
}
return false;
}
});
$.fn.waypoint.defaults.offset = 75;
$('.section h1.page_name').waypoint(function() {
var id = this.id;
var op = $('#navigation a[href = "#' + id + '"]');
if (op.length) {
$("#navigation a").removeClass("active");
op.addClass('active');
}
});
});
I'm not a strong programmer. I've tried to edit it as best as I can and I'm just stuck. Any insight to fixing this would highly be appreciated.
Still looking for an answer, below couldn't fix the problem.
I'm not sure what the waypoints plugin was doing, but I've refactored your code and it is working for me. Note that I took out the call to .waypoints, and changed your $('body').click() handler to be a more specific handler on the navigation link elements. This handler will scroll to each element and then will perform the removal and addition of the class correctly when the scrolling is done:
$(document).ready(function()
{
function highlightNav(navElement){
$("#navigation a").removeClass('active');
navElement.addClass('active');
}
$('#navigation a').click(function(event){
var nav = $(this);
var id = nav.attr('href');
$.scrollTo(id, 1000, {
offset: { top: -75 },
axis: 'y',
onAfter: function(){
highlightNav(nav);
}
});
return false;
});
$(window).scroll(function(){
if($(this).scrollTop() == 0){
highlightNav($("#navigation a[href*='home']"));
}
});
$.fn.waypoint.defaults.offset = 75;
$('.section h1.page_name').waypoint(function() {
var id = this.id;
var op = $('#navigation a[href = "#' + id + '"]');
if (op.length) {
highlightNav(op);
}
});
// Fancybox
$("a.zoom").fancybox({
'overlayShow' : false,
'transitionIn' : 'elastic',
'transitionOut' : 'elastic'
});
$("a.outside_shade").fancybox({
'titlePosition' : 'outside',
'overlayColor' : '#000',
'overlayOpacity' : 0.9
});
$("a.inside_white").fancybox({
'titlePosition' : 'inside'
});
$("a.inside_shade").fancybox({
'titlePosition' : 'over'
});
// validation
$("form").validate();
// nivo slider
$('#slider').nivoSlider();
});
In the html I added a default active class to the first link:
<div id="navigation">
<ul>
<li>Home</li>
<li>Portfolio</li>
<li>Who Are We?</li>
<li>Our Services</li>
<li>Features</li>
<li>Keep in Touch</li>
</ul>
</div>
Also I noticed on the page you have your css defined before the reset.css is called in. That's usually bad practice you might want to make sure reset.css is always the very first css file pulled in. It doesn't appear to have affected the page much but sometimes you'll get weird results doing that.
I made a jsfiddle of the results here: http://jsfiddle.net/RNsFw/2/
the waypoints plugin isn't needed anymore I think. I didn't change the fancybox or validation stuff because i'm not sure what those are doing and it wasn't really part of your issue.
I tested it in firefox and Chrome. Let me know if you have questions :)
http://jsfiddle.net/vCgy8/9/
This removes the dependency on scrollTo, and the waypoints plugin.
$('body').click(function(event)
{
if(event.target.nodeName.toLowerCase() == 'a')
{
var op = $(event.target);
var id = op.attr('href');
if(id.indexOf('#') == 0)
{
destination = $(id).offset().top;
$("html:not(:animated),body:not(:animated)").animate({ scrollTop: destination}, 1000, function() {
var hash = id.split('#')[1];
window.location.hash = hash;
});
}
return false;
}
});
$(window).scroll(function (event){
makeActive();
});
function makeActive(){
var y = $(this).scrollTop();
if(y!==0){
$('.page_name').each(function(){
var curPos = parseInt($(this).offset().top - y);
if(curPos <= 0){
var op = $('#navigation a[href = "#'+$(this).attr('id')+'"]');
$("#navigation a").removeClass("active");
op.addClass('active');
}
});
}else{
$("#navigation a").removeClass("active");
$("#navigation a:first").addClass('active');
}
}
makeActive();
This may be completely unrelated, but I had a similar problem yesterday - where, in the callback of an event handler, jQuery operations weren't being performed in that scope but if you threw the code into something like:
setTimeout(function() {
$(selector).addClass('foo');
}, 0);
it would work - similar to how $.animate() functions (ish) if you call $(selector).stop().animate() without the queue param being false, eg:
$(selector).stop();
$(selector).animate({ foo }, { no queue:false here });
// ^ fail
$(selector).stop();
setTimeout(function() {
$(selector).animate({ foo }, { no queue:false here either });
}, 0);
// ^ success
The problem, completely unrelated to the above example though similar in behavior/functional hack, turned out to be the method of binding - in my case I had been using $.bind() - but then I refactored this to use $.delegate() ($.live() would work also) and it functioned as expected.
Again, not sure if this related, but figured I'd pass that along just in case. Unsure if it's a bug or just me not properly understanding some of the subtler parts of jQuery.
The problem is not in your js code, but in your css/page layout.
Or maybe the problem is that you are using the waypoint plugin and you might not want to for this particular page. (As you will see you also have trouble hitting the "Home" waypoint again once you have left it, because of the offset you use.)
The thing is, the waypoint plugin won't trigger until the target element you are scrolling to is in the very top of the browser window, with respect to the offset that is. "Keep in touch" will never get to the top unless your browser window is small enough that the "keep in touch" section takes up the entire browser window (minus the offset).
You can see it visualized here:

Categories