How to add dynamically items to a Magnific Popup gallery - javascript

I use Magnific Popup and Shuffle plugins on my page. I load new items as soon as the user reach the bottom of the page. What I want to do is to bind my new items to Magnific Popup after loading them.
I tried to follow this answer Dynamically add items to Magnific Popup gallery but it is not working for me.
Below the js code I use to do so.
First, once the page is loaded I use this code to setup MP
// gallery mode
$('.gallery-item').magnificPopup({
gallery: {
enabled: true
},
mainClass: 'mfp-fade',
fixedContentPos: false,
type: 'image'
});
Then, as soon as the user reach the bottom of the page if request the JSON file
$.getJSON( "list-dir.php")
.done(function( data ) {
var diff = Object.keys(data).length - $(".item").length;
var NUM_TO_LOAD = diff > 10 ? 10 : diff;
if(Object.keys(data).length > $(".item").length){
for(var i = 0 ; i<= 10; i++) {
var el = data[$(".item").length];
if (el === undefined) { break; }
var name = el.substring(0,el.indexOf("_") );
var $item = $('<div class="item shuffle-item filtered" data-groups="photo" data-groups="photo"><div class="item-img" style="background-image: url(\'img\/dresses\/' + el + '\' )"></div><div class="item-overlay"><h5>'+ name +'</h5></div></div>');
//Shuffle update
$('.portfolio').append($item);
$('.portfolio').shuffle('appended', $item);
// get instance (after popup was opened)
var mfp = $.magnificPopup.instance;
// modify the items array (push/remove/edit)
mfp.gallery.push({
src: $item
});
mfp.updateItemHTML();
}
}
});

Related

Infinite Scroll (JS) + iPhone - Images not loading

So I am using the Infinite Scroll script to prevent the user having to move on to the next page to view more products in Woocommerce. Everything works great except...
On iPhone (and iPad) the images that would technically be on the next page do not load at all once "Load More" initiates... so for example, if I have 1-8 products visible and I scroll down - the rest of the products appear, but only the images for the initial 1-8 products load, but the rest do not.
I have tried implementing bug fixes to no avail... just wondering if anyone else has encountered this and managed to find a fix?
<script>
var elem = document.querySelector('.shop-section');
var infScroll = new InfiniteScroll( elem, {
// options
path: '.woocommerce-pagination a.next',
append: '.products',
hideNav: '.woocommerce-pagination',
history: false,
status: '.page-load-status',
});
// iPhone Bug Fix
infScroll.on( 'append', function( response, path, items ) {
for ( var i=0; i < items.length; i++ ) {
reloadSrcsetImgs( item[i] );
}
});
function reloadSrcsetImgs( item ) {
var imgs = item.querySelectorAll('img[srcset]');
for ( var i=0; i < imgs.length; i++ ) {
var img = imgs[i];
img.outerHTML = img.outerHTML;
}
}
</script>
EDIT: I should also add that I noticed an error in the console as follows:
Uncaught ReferenceError: item is not defined
at InfiniteScroll.<anonymous> ((index):970)
at InfiniteScroll.proto.emitEvent (infinite-scroll.js?ver=1:254)
at InfiniteScroll.proto.dispatchEvent (infinite-scroll.js?ver=1:688)
at InfiniteScroll.<anonymous> (infinite-scroll.js?ver=1:1069)
at InfiniteScroll.proto.appendNextPage (infinite-scroll.js?ver=1:1076)
at InfiniteScroll.proto.onPageLoad (infinite-scroll.js?ver=1:1052)
at InfiniteScroll.<anonymous> (infinite-scroll.js?ver=1:1029)
at XMLHttpRequest.req.onload (infinite-scroll.js?ver=1:1249)

Can't get the highlight menu items on scroll jQuery script to work with WordPress Divi theme

I am buiding a one page WordPress website with Divi theme and I want the menu items to highlight while the page is scrolled up/down like here: http://codepen.io/ivanchi/pen/QEEeKd?editors=0010. The problem is that I can't get it to work on Wordpress. I equeued it using this code:
<?php
add_action( 'wp_enqueue_scripts', 'my_enqueue_assets', 16 );
wp_register_script( 'jqueryMinJs', 'http://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js' , '', '', true );
wp_enqueue_script( 'jqueryMinJs' );
wp_register_script( 'highlight-on-scroll', get_template_directory_uri().'/js/highlight_on_scroll.js', array('jquery'), false, true );
wp_enqueue_script( 'highlight-on-scroll' );
}
?>
and I included the jQUERY script in the /js/highlight_on_scroll.js directory:
var $jq = jQuery.noConflict(true);
(function($) {
$jq("div").css("border", "1px solid red");
$jq("#et-top-navigation a").addClass("green-navigation");
// Cache selectors
var lastId,
topMenu = $jq("#et-top-navigation"),
topMenuHeight = topMenu.outerHeight()+1,
// All list items
menuItems = topMenu.find("a"),
// Anchors corresponding to menu items
scrollItems = menuItems.map(function(){
var item = $jq($jq(this).attr("href"));
if (item.length) { return item; }
});
// Bind click handler to menu items
// so we can get a fancy scroll animation
menuItems.click(function(e){
var href = $jq(this).attr("href"),
offsetTop = href === "#" ? 0 : $jq(href).offset().top-topMenuHeight+1;
$jq('html, body').stop().animate({
scrollTop: offsetTop
}, 850);
e.preventDefault();
});
// Bind to scroll
$jq(window).scroll(function(){
// Get container scroll position
var fromTop = $jq(this).scrollTop()+topMenuHeight;
// Get id of current scroll item
var cur = scrollItems.map(function(){
if ($jq(this).offset().top < fromTop)
return this;
});
// Get the id of the current element
cur = cur[cur.length-1];
var id = cur && cur.length ? cur[0].id : "";
if (lastId !== id) {
lastId = id;
// Set/remove active class
menuItems
.parent().removeClass("mactive")
.end().filter("[href=#"+id+"]").parent().addClass("mactive");
}
});
}($jq));
I used
var $jq = jQuery.noConflict(true);
for preventing conflict and these two lines are working fine(I added them for testing purposes)
$jq("div").css("border", "1px solid red");
$jq("#et-top-navigation a").addClass("green-navigation");
but the rest of jQuery script does not.
What am I doing wrong?
The reason behind the jquery code not executing that your are using , as the delimiter , you should use ;
Check the plunker.
http://plnkr.co/edit/owvH2WPMJ10AQS3MkcHC
if you use ; then the second alert is displayed , but if you use , then code will not reach there.
topMenu = $jq("#et-top-navigation");
topMenuHeight = topMenu.outerHeight()+1;

Targeting tabs on page with direct URL link breaks URL on tab click

I'm trying to create a tabbed area within my page. The tabs navigate hidden areas with out leaving the page. I also want to be able to link to an area with in the page. It's working except when you click the menu as well as revealing the hidden area it's rewriting the URL with only the tab extension and therefor breaking the link of the URL. So someone trying to share the link would not know the format..
I'm using this code https://css-tricks.com/examples/OrganicTabsReplaceState which I see no problem with.
You can see a live demo with my issue here: http://bit.ly/1IP1ST4
Clicking the tab is removing:
/products/eurorack-modules/waveform-modifiers/reactive-shaper/
And replacing it with ?tab=mytabname
It should be simply adding it. I'm struggling to work out why..?
If you inspect the source of the first link you provided, you will see that the tabs contain links like this:
Featured
That's an in-page link. You should use #'s for in page links. The reason the whole url is being replaced is because it's interpreting the href as a new url to go to. #'s look inside the current page.
This version of organictabs.jquery.js got it working in the end seemed to be an issue with the way it treated the URL.. Maybe this will help someone else.
// IIFE
(function($) {
// Define Plugin
$.organicTabs = function(el, options) {
// JavaScript native version of this
var base = this;
// jQuery version of this
base.$el = $(el);
// Navigation for current selector passed to plugin
base.$nav = base.$el.find(".nav");
// Returns the fragment identifier of the given URL
function getFragmentIdentifier(url) {
if(url && url.match && url.match(/#(.*)/)) {
return RegExp.$1;
}
}
// Remove the query string from the url
function noQueryString(url) {
if(url && url.match && url.match(/^([^\?]*)\??/)) {
return RegExp.$1;
}
}
// Runs once when plugin called
base.init = function() {
// Pull in arguments
base.options = $.extend({},$.organicTabs.defaultOptions, options);
// Accessible hiding fix (hmmm, re-look at this, screen readers still run JS)
$(".hide").css({
"position": "relative",
"top": 0,
"left": 0,
"display": "none"
});
// When navigation tab is clicked...
base.$nav.delegate("a", "click", function(e) {
// no hash links
e.preventDefault();
// Figure out current list via CSS class
var curList = getFragmentIdentifier(base.$el.find("a.current").attr("href")),
// List moving to
$newList = $(this),
// Figure out ID of new list
listID = getFragmentIdentifier($newList.attr("href")),
// Set outer wrapper height to (static) height of current inner list
$allListWrap = base.$el.find(".list-wrap"),
curListHeight = $allListWrap.height();
$allListWrap.height(curListHeight);
if ((listID != curList) && ( base.$el.find(":animated").length == 0)) {
// Fade out current list
base.$el.find("#"+curList).fadeOut(base.options.speed, function() {
// Fade in new list on callback
base.$el.find("#"+listID).fadeIn(base.options.speed);
// Adjust outer wrapper to fit new list snuggly
var newHeight = base.$el.find("#"+listID).height();
$allListWrap.animate({
height: newHeight
}, base.options.speed);
// Remove highlighting - Add to just-clicked tab
base.$el.find(".nav li a").removeClass("current");
$newList.addClass("current");
// Change window location to add URL params
if (window.history && history.pushState) {
// NOTE: doesn't take into account existing params
history.replaceState("", "", noQueryString(window.location.href) + "?" + base.options.param + "=" + listID);
}
});
}
});
var queryString = {};
window.location.href.replace(
new RegExp("([^?=&]+)(=([^&]*))?", "g"),
function($0, $1, $2, $3) { queryString[$1] = $3; }
);
if (queryString[base.options.param]) {
var tab = $("a[href='#" + queryString[base.options.param] + "']");
tab
.closest(".nav")
.find("a")
.removeClass("current")
.end()
.next(".list-wrap")
.find("ul")
.hide();
tab.addClass("current");
$("#" + queryString[base.options.param]).show();
};
};
base.init();
};
$.organicTabs.defaultOptions = {
"speed": 300,
"param": "tab"
};
$.fn.organicTabs = function(options) {
return this.each(function() {
(new $.organicTabs(this, options));
});
};
})(jQuery);

Load blocking jQuery animate

I have built a gallery viewer with a preload function.
The preload function is as follows:
$.preloadFullImages = function() {
// Create array of images
var set = [];
$('.slide-item img').each(function() {
var img = $(this).data('src');
var id = $(this).parent().attr('id');
$(this).remove();
set.push([img,id]);
});
// Set current image
var current = 0;
var iterate = function() {
var current_src = set[current][0];
var current_id = set[current][1];
var temp = '<img src="'+current_src+'" />';
var target = '#'+current_id;
var targetImg = '#'+current_id+' img';
// Load 'temp' image
$(temp).bind('load', function() {
// Show image
$(target).append(temp);
$(targetImg).show();
$(this).remove();
});
if ( ++current < set.length ) iterate();
};
iterate();
};
On load of the page, images are loaded sequentially.
The problem is until all the images are loaded, the animation between images (prev and next arrows) is stunted and doesn't work correctly. I want the gallery viewer to transition smoothly between slides (images) even if not all images are loaded.
You can see a live demo here: http://www.davidclapp.net/portfolio
The issue is especially apparent on the iPhone (safari).
Is there a way to ensure the animation is smooth even whilst images are still loading?
Edit: I am using this plugin for CSS3 transitions - http://ricostacruz.com/jquery.transit/
$.preloadFullImages = function(callback) {
...
if ( ++current < set.length ) iterate();
else if(callback) callback(); //check if callback exists, then call it.
};
iterate();
};
These two lines being the important part.
$.preloadFullImages = function(callback) {
if ( ++current < set.length ) iterate();
else callback();
make a function to call the beginning of your animation, pass it to "preloadFullImages"

jQuery looks/works good in Firefox but not IE (Internet Explorer)

I have jCarousel 0.2.8 working with jQuery 1.7.1 and jQuery UI 1.8.11 in my Drupal 7 module perfectly in Firefox. However, the carousels are not working properly in Internet Explorer 7, 8, 9 and 10. What can I do to get them to load properly in both browsers? Screenshots of what it looks like in FF and IE are attached. Below is my JavaScript/jQuery code. Note that since it is a Drupal site, jQuery() is used instead of $().
You can test the issue described at my website:
[demo link removed]
Any help getting this fixed in IE would be very much appreciated! Thanks!!
Firefox and IE screenshots
function select_avatar(image, button) {
image.input.prop('checked', true);
jQuery('#layer_'+image.id).css({ backgroundImage: "url("+image.url+")" });
var src = button.attr("src");
button.parent().parent().find("li img").each(
function(index) {
if(jQuery(this).attr("src") == src)
jQuery(this).addClass("avatar_select");
else
jQuery(this).removeClass("avatar_select");
}
);
}
function unselect_avatar(image, button) {
image.input.prop('checked', false);
//select empty
jQuery('#default_input_'+image.id).prop('checked', true);
jQuery('#layer_'+image.id).css({ backgroundImage: "none" });
var src = button.attr("src");
button.parent().parent().find("li img").each(
function(index) {
if(jQuery(this).attr("src") == src)
jQuery(this).removeClass("avatar_select");
}
);
}
function mycarousel_itemVisibleInCallback(carousel, item, i, state, evt) {
// carousel.data is empty on page load
var data = carousel.data;
// True on page load
if(!data) {
// cid is name of carousel, user_avatar_select_X
var cid = carousel.list.attr('id').substring(9);
var data = new Array();
// For each img element in ID user_avatar_select_X
jQuery('#'+cid+' img').each(
// Provide index # for each iteration of loop
function(index) {
// Sets input to the input element nearby the img element
// Note: Parent element is a label element
var input = jQuery(this).parent().siblings('input');
// Sets url to the src of the img element
var url = jQuery(this).attr('src');
// If the img is selected, apply the img to ID layer_user_avatar_select_X
// (which is on the picture)
if(input.is(':checked')) {
jQuery('#layer_'+cid).css({ backgroundImage: "url("+url+")" });
}
// Adds variables to the data array
data.push({id: cid, input: input, image: jQuery(this), url: url});
});
// Stores data array in carousel
carousel.data = data;
// Adds html to ID user-edit
// Adds input with ID default_input_user_avatar_select_X
// and name select_avatar_X
jQuery('#user-edit').append('<div class="form-item" style="display:none"><label class="option"><input class="form-radio user_avatar_select" id="default_input_'+cid+'" type="radio" value="none" name="select_avatar_'+cid.substring(cid.lastIndexOf("_") + 1)+'"/></label></div>');
}
var idx = carousel.index(i, data.length);
var image = data[idx - 1];
var img = image.image.clone();
if(image.input.is(':checked'))
img.addClass("avatar_select");
carousel.add(i, img);
img.hover(
function(){jQuery(this).addClass("avatar_hover");},
function(){jQuery(this).removeClass("avatar_hover");}
);
img.click(
function () {
if(image.input.is(':checked'))
unselect_avatar(image, jQuery(this));
else
select_avatar(image, jQuery(this));
}
);
};
function mycarousel_itemVisibleOutCallback(carousel, item, i, state, evt) {
carousel.remove(i);
};
function mycarousel_init(list) {
// list parameter is ID user_avatar_select_X radio buttons and images
// If list isn't valid, bail out
if(!list.attr('id'))
return;
// Add layer to picture for each list (ccrresponding to the choices for avatars)
jQuery(".picture").append('<div class="avatar_layer" id="layer_'+list.attr('id')+'"></div>');
// Adds UL carousel_X with Tango Skin to each list
list.append('<ul id="carousel_'+list.attr('id')+'" class="jcarousel-skin-tango"></ul>');
// Creates carousel for each list
jQuery('#carousel_'+list.attr('id')).jcarousel({
scroll: 3,
visible: 3,
wrap: 'circular',
//itemLoadCallback: itemLoadCallbackFunction,
itemVisibleInCallback: {onBeforeAnimation: mycarousel_itemVisibleInCallback},
itemVisibleOutCallback: {onAfterAnimation: mycarousel_itemVisibleOutCallback}
});
}
jQuery(document).ready(function () {
// Hide original ID user_avatar_select_X radio buttons and images
// since we want them to be in carousels instead
jQuery('div.user_avatar_select').parent().hide();
for(var i=0;i<10;i++) {
// Create a carousel based on ID user_avatar_select_X
mycarousel_init(jQuery('#user_avatars_select_'+i));
}
// Hide the picture with ID current, since the user may want to build a new avatar
jQuery(".picture #current").css({display: "none"});
// Show the default avatar, so the user can build a new avatar
// Selected layers for the current avatar will be added on top
jQuery(".picture").css({"position": "relative", "width": "200px", "height": "199px", "background-image": "url(/sites/default/files/default_avatar.gif)"});
});
In CSS I set a specific height and width for the images in the carousel and that fixed it. They had height: auto but that wasn't good enough for IE I guess.

Categories