jQuery : load a plugin using on function - javascript

I'm using jQuery and Tooltipster (showing tooltips when going hover user names), which are working great except for one situation : when I first go hover a user name, it does not show up.
<div class="user">Firstname Lastname</div>
Here is my jQuery code :
$(document).ready(function() {
$(document).on('mouseover', '.user', function() {
// Tooltip for EC user
$('.evac_user').tooltipster({
animation : 'fade',
delay : 0,
content : 'Loading...',
functionBefore : function(origin, continueTooltip) {
continueTooltip();
// next, we want to check if our data has already been cached
if (origin.data('ajax') !== 'cached') {
$.ajax({
type : 'GET',
url : "/myfunction",
success : function(data) {
// update our tooltip content with our returned data and cache it
origin.tooltipster('update', data).data('ajax', 'cached');
}
});
}
}
});
});
});

$('.user').on('mouseover', function(){

Related

Writing and compiling a simple jQuery plugin

I am trying to compile a basic jQuery plugin which shows a div upon provided options when invoking:
select if a checkbox should be checked after X milliseconds or after X px on scroll,
if one of those two options are selected, set a delay value or scroll distance in px
otherwise do nothing
Example of desired options invoke:
$(document).ready( function() {
$('#testInput').testing({
myMethod : delay,
myValue : 2000
});
});
My current progress here: JSFiddle (it's not much as currently I'm still at a beginning of the learning curve)
After some fiddling i managed to get this working (kinda). Plugin seems to be working fine. Except there is some bug with the scroll function which i have to sort it out additionaly - it loops and changes checkbox states indefinitely instead just once.
Here is a working fiddle
And modified code:
(function($) {
$.fn.testing = function( options ) {
// Settings
var settings = $.extend({
delay : null,
delayTime : null,
scrolling : null,
scrollDist : null
}, options);
return this.each( function() {
var self = this;
// Timeout
setTimeout(function (){
$(self).prop('checked', settings.delay);
}, settings.delayTime);
// Scroll
if ($(window).scrollTop() > settings.scrollDist) {
$(this).prop('checked', settings.scrolling);
};
});
}
}(jQuery));
// Plugin invoke
$(window).on("load resize scroll",function(){
$('#testInput').testing({
delay : false,
delayTime : null,
scrolling : true,
scrollDist : 20,
});
});

jQuery Infinite Scroll's loading fires too early

I tried to implement jQuery Infinite Scroll. But the loading fires too early. At first, it fires even if I only scroll the page 1 pixel. And then it still fires far before I scroll the page to the bottom.
At first, I make an Ajax call to fill in the first page. Then I initialize Infinite Scroll. As following.
$.ajax({
url : 'data/page1.html',
cache : true,
dataType : 'html',
success : function(newElements) {
$('#container')
.append(newElements)
.infinitescroll({
// -- selector for: --
navSelector : '#pagenav', // the paged navigation
nextSelector : '#pagenav', // the NEXT link (to page 2)
itemSelector : '.item', // all items you'll retrieve
// --
loading : {
finishedMsg: 'No more items to load',
img: 'images/ajax-loading.gif'
}
});
}
});
I had simplified my files at here for demonstration purpose.
EDIT: Demonstration on Plunker.
After checking the source code, I found on line 423 that the loading has something to do with the position of navigation. Then I realized that I hid navigation by setting display: none; to it in my CSS that caused the script to be unable to calculate the position of navigation correctly. After removing display: none;, the problem has been fixed.
Thank everyone who tried to help me.
Try it like this
$(document).ready(function() {
$('#container').infinitescroll({
dataType: 'html',
appendCallback: false,
navSelector: '#pagenav', // selector for the paged navigation
nextSelector: '#pagenav', // selector for the NEXT link (to page 2)
itemSelector: '.item',
pixelsFromNavToBottom: 50
});
});
Plunker
Try this
$(document).ready(function() {
$.ajax({
url: "data/page1.html",
cache: true,
dataType: "html",
success: function(newElements) {
setTimeout((function() {
$("#container").append(newElements).infinitescroll({
navSelector: "#pagenav",
nextSelector: "#pagenav",
itemSelector: ".item",
loading: {
finishedMsg: "No more items to load",
img: "images/ajax-loading.gif"
}
});
}), 5000);
}
});
});
I had the same problem when I was looking for an infinite scroll plugin, so I ended up using Endless Scroll.
The good thing about this plugin is that you can define options, such as 'bottomPixels', as shown in the following example:
$(document).endlessScroll({
bottomPixels: 300,
fireDelay: 200,
callback: function() {
if ($('#table').length > 0 && !loadedAllEntries && !loadPending) {
loadEntries($('#table tbody tr').size());
}
},
ceaseFire: function() {
if (loadedAllEntries)
return 1;
if ($('#table').length === 0)
return 2;
}
});
I set loadPending to true in the beginning of every request so that only one request is active for every given moment. Hope this helps.

Wait for document mousedown to complete before element onclick can start

I have a panel that slides open on an element click called "details" and populates the panel via ajax depending on the data attribute value. I also have it setup that if you close outside that panel, it will close. If the panel is open and the user clicks on a different "details" element, I want the panel to close and open again populated with the data from the new data attribute.
Problem is that the codes checks if the panel is visible and won't load the ajax if it is. How can I change this so the click event knows the mousedown event is completed before it does it's thing?
// SLIDING PANEL
$(".details").on("click", function(e){
e.preventDefault();
var panel = $("#DetailsPanel");
var mkey = $(this).data("masterkey-id");
var _self = $(this);
// fetch data ONLY when panel is hidden...
// otherwise it fetches data when the panel is closing
if (!panel.is(':visible')) {
panel.load("/com/franchise/leads.cfc?method=getLeadDetails", { mkey: mkey }, function(response, status, xhr) {
// if the ajax source wasn't loaded properly
if (status !== "success") {
var msg = "<p>Sorry, but there was an error loading the document.</p>";
panel.html(msg);
};
// this is part of the .load() callback so it fills the panel BEFORE opening it
panel.toggle("slide", { direction: "right" }, "fast", function(){
_self.parent().parent().addClass("warning");
});
});
} else {
panel.toggle("slide", { direction: "right" }, "fast", function(){
_self.parent().parent().removeClass("warning");
});
};
return false;
});
$(document).on("mousedown", function(){
$("#DetailsPanel").hide("slide", { direction: "right" }, "fast", function(){
//_self.parent().parent().removeClass("warning");
});
});
// don't close panel when clicking inside it
$(document).on("mousedown","#DetailsPanel",function(e){e.stopPropagation();});
$(document).on("click", "#ClosePanel", function(){
$("#DetailsPanel").hide("slide", { direction: "right" }, "fast", function(){
$("#LeadsTable tr").removeClass("warning");
});
});
// END SLIDING PANEL
Setting a timeout worked for me in another context:
onclick="window.setTimeout( function(){ DO YOUR STUFF }, 2);"
This solves many problems of this type.
I'm not totally sure about this but if you use "mouseup" instead "click" could work as you expect. Try it and let me know if I'm wrong.
Ok, so I found this little nugget http://www.gmarwaha.com/blog/2009/06/09/jquery-waiting-for-multiple-animations-to-complete/ and it works pretty good. No issues so far.
Here is the new code
$(".details").on("click", function(e){
e.preventDefault();
var panel = $("#DetailsPanel");
var mkey = $(this).data("masterkey-id");
var _self = $(this);
// fetch data ONLY when panel is hidden...
// otherwise it fetches data when the panel is closing
var wait = setInterval(function() {
if( !$("#DetailsPanel").is(":animated") ) {
clearInterval(wait);
// This piece of code will be executed
// after DetailsPanel is complete.
if (!panel.is(':visible')) {
panel.load("/com/franchise/leads.cfc?method=getLeadDetails", { mkey: mkey }, function(response, status, xhr) {
// if the ajax source wasn't loaded properly
if (status !== "success") {
var msg = "<p>Sorry, but there was an error loading the document.</p>";
panel.html(msg);
};
// this is part of the .load() callback so it fills the panel BEFORE opening it
panel.toggle("slide", { direction: "right" }, "fast", function(){
_self.parent().parent().addClass("warning");
});
});
} else {
panel.toggle("slide", { direction: "right" }, "fast", function(){
_self.parent().parent().removeClass("warning");
});
};
}
}, 200);
return false;
});

How to run JavaScript after AJAX load?

I am using a vertical dropdown or accordion menu run by some js.
To keep the menu as it is and prevent it from snapping back to it's initial state when some content is loaded I am using a load function.
That seems to work:-)
But the actual content, an image slider, uses some js as well and when loaded via function the js doesn't trigger, because the entire site is not again.
How can I re-trigger the js for that content?
This is the load function:
$(document).ready(function() {
$('ul#menu2 li ul li a').click(function() {
var page = $(this).attr('href');
$('#content').load(page + '.php');
return false;
})
;});
This is the hookup for the slider
$(document).ready(function() {
// Using default configuration
$('#carousel').carouFredSel();
// Using custom configuration
$('#carousel').carouFredSel({
items : 1,
direction : "left",
responsive : false,
auto : {
play : false
},
scroll : {
items : 1,
easing : "swing", // "elastic", "swing"
duration : 500,
},
prev : {
button : "#p",
key : "left"
},
next : {
button : "#n",
key : "right"
},
});});
The js for the slider is called jquery.carouFredSel-6.2.1.js.
I guess this and the hookup need to be re-triggered to make the slider work
when only the content was loaded instead of the entire page.
Can anyone help me with this?
Call $('#carousel').carouFredSel(); from the callback function on the ajax request. Something like this.
$( "#result" ).load( "ajax/test.html", function() {
alert( "Load was performed." );
});
Perhaps
$(document).ready(function() {
$('ul#menu2 li ul li a').click(function(e) {
e.preventDefault(); // Prevents the browser from navigating to wherever the href was leading to
var page = $(this).attr('href');
$('#content').load(page + '.php', function() {
// Loads Carousel only after #content has fully loaded
$('#carousel').carouFredSel({
items : 1,
direction : "left",
responsive : false,
auto : {
play : false
},
scroll : {
items : 1,
easing : "swing", // "elastic", "swing"
duration : 500,
},
prev : {
button : "#p",
key : "left"
},
next : {
button : "#n",
key : "right"
},
});
});
return false;
});
});
They have a section in their documentation for inserting items into the carousel after it has been initialized:
http://docs.dev7studios.com/jquery-plugins/caroufredsel-advanced#insertitem
$(document).ready(function() {
$('ul#menu2 li ul li a').click(function() {
var page = $(this).attr('href');
$('#content').load(page + '.php', function(){
$('#carousel').carouFredSel({
'insertItem' : $('#content') // Or whatever you need to add
});
});
return false;
});
});

tumblr audio + Masonry with infinite scroll- other solutions posted have confused me [duplicate]

Here's a test page: http://masonry-test.tumblr.com/
I'm using jquery Masonry with infinite scroll on tumblr. All is fine except with audio players. They won't load on the second page and display this message instead [Flash 9 is required to listen to audio.].
Did a little research and found a solution. One here (this one too) and here's the js from the Mesh theme that does that successfully (line 35).
Problem is I don't know where and how to implement it in my code. Everything I tried either wasn't working or it left a small gap around the masonry blocks. My code:
$(document).ready(function () {
var $container = $('.row');
$container.imagesLoaded(function () {
$container.masonry({
itemSelector: '.post',
columnWidth: 1
});
});
$container.infinitescroll({
navSelector: '#page-nav',
nextSelector: '#page-nav a',
itemSelector: '.post',
loading: {
finishedMsg: "No more entries to load.",
img: "http://static.tumblr.com/7wtblbo/hsDlw78hw/transparent-box.png",
msgText: "Loading..."
},
debug: true,
bufferPx: 5000,
errorCallback: function () {
$('#infscr-loading').animate({
opacity: 0.8
}, 2000).fadeOut('normal');
}
},
function (newElements) {
//tried this but doesn't work
/* repair video players*/
$('.video').each(function(){
var audioID = $(this).attr("id");
var $videoPost = $(this);
$.ajax({
url: '/api/read/json?id=' + audioID,
dataType: 'jsonp',
timeout: 50000,
success: function(data){
$videoPost.append('\x3cdiv class=\x22video_player_label\x22\x3e' + data.posts[0]['video-player'] +'\x3c/div\x3e');
}
}
});
});
/* repair audio players*/
$('.audio').each(function(){
var audioID = $(this).attr("id");
var $audioPost = $(this);
$.ajax({
url: '/api/read/json?id=' + audioID,
dataType: 'jsonp',
timeout: 50000,
success: function(data){
$audioPost.append('\x3cdiv class=\x22audio_player\x22\x3e' + data.posts[0]['audio-player'] +'\x3c/div\x3e');
}
}
});
});
var $newElems = $(newElements).css({
opacity: 0
});
$newElems.imagesLoaded(function () {
$newElems.animate({
opacity: 1
});
$container.masonry('appended', $newElems, true);
});
});
$(window).resize(function () {
$('.row').masonry();
});
});
By default the API will return a white audio player.
you can change it by using the jQuery method to replace the flash player with a black or white player respectively.
.replace("audio_player.swf", "audio_player_black.swf")
or simply change the color itself
.replace("color=FFFFFF", "color=EA9D23");
Example:
$('.audio').each(function(){
var audioID = $(this).attr("id");
var $audioPost = $(this);
$.ajax({
url: '/api/read/json?id=' + audioID,
dataType: 'jsonp',
timeout: 50000,
success: function(data){
$audioPost.append('\x3cdiv class=\x22audio_player\x22\x3e' + data.posts[0]['audio-player'].replace("audio_player.swf","audio_player_black.swf") +'\x3c/div\x3e');
}
}
});
I had a lot of trouble with this and hope it helps someone out. I found the above information here Change Tumblr audio player color with Javascript.
I noticed a few things and this is what I advise you to try:
For that script to work, the elements with the class "audio" should each have an "id" attribute with the post ID. The HTML should look like that:
<div class="audio" id={PostID}>{AudioPlayerWhite}</div>
Tumblr will automatically fill the {PostID} part with the ID for each post. I suppose it works in the same manner for videos (haven't tried it with videos yet).
As for position, I did it like this:
function (newElements) {
....
$newElems.imagesLoaded(function () {
....
});
//audio repair goes here!
}
Here is a solution I came up with when I needed to implement the same functionality in the template I was creating.
In your HTML, include your AudioPlayer Tumblr tag between comments. This is to prevent loaded scripts from being called. Also add a class "unloaded" to keep track whether or not we've loaded the audio player for this post or not.
...
{block:AudioPlayer}
<div class="audio-player unloaded">
<!--{AudioPlayerBlack}-->
</div>
{/block:AudioPlayer}
...
If you look at the commented code after the page is loaded, you will notice an embed tag being passed to one of the Tumblr javascript functions. Since we commented it, it will not execute. Instead we will want to extract this string and replace the div contents with it.
Create a javascript function which will do this. This can be done with regular javascript, but to save time I will do it with jQuery since this is how I did it for my template:
function loadAudioPosts() {
// For each div with classes "audio-player" and "unloaded"
$(".audio-player.unloaded").each(function() {
// Extract the <embed> element from the commented {AudioPlayer...} tag.
var new_html = $(this).html().substring(
$(this).html().indexOf("<e"), // Start at "<e", for "<embed ..."
$(this).html().indexOf("d>")+2 // End at "d>", for "...</embed>"
);
// Replace the commented HTML with our new HTML
$(this).html(new_html);
// Remove the "unloaded" class, to avoid reprocessing
$(this).removeClass("unloaded");
});
}
Call loadAudioPosts() once on page load, then every time your infinite scrolling loads additional posts.

Categories

Resources