Ajax auto refresh causing my jquery embed script to repeat endlessly - javascript

OK, my disclaimer, regarding script, I'm green as a cucumber.
I've recently set up jquery-oembed on my site (phpbb forum), it's a code which auto embeds media content from various sites like youtube, twitter, facebook etc...
It works great, except I'm having trouble integrating it into my chat box. The chat functions through an ajax code which auto refreshes in intervals. Depending on where I put my script, the embed will either show a link and not embed until you manually refresh the page....or....it will embed, but constantly repeat itself over and over every time the ajax refreshes. I've been playing around with this a lot, I try to avoid bothering you guys unless it's absolutely necessary.
Here's the oembed code, which works find on the posts in my site.
(function($) {
$(document).ready(function() {
$(".avatarMessage .postlink").oembed(null, {
embedMethod: "append",
startClosed: true,
maxWidth: 300,
});
});
})
The best I could find through searching was this snippet which I tried. If I change it to add:
(function($) {
$(document).ready(function() {
$(".avatarMessage .postlink").oembed(null, {
embedMethod: "append",
startClosed: true,
maxWidth: 300,
});
while (update.firstChild) {
update.removeChild(update.firstChild);
}
});
})
Then it won't keep repeating it, but it also won't allow for new url's to embed, so I can't use this one.
Is there something I could add for this which would limit the removeChild to just the content of that message, or perhaps another idea that I'm just completely not seeing (don't get frustrated with me, I'm trying, I just don't have much experience outside the basic html and css).
In case anyone is interested, here is the ajax code which fires the auto refresh.
https://raiderforums.com/mchat/mchat_ajax_mini.js
Thanks for putting up with me :)

This is happening because each time you call $(".avatarMessage .postlink").oembed(....) all matched elemenets will be compiled even if they are already compiled. To prevent that you can add a new-post class and remove it after the element is compiled/embeded:
(function($) {
$(document).ready(function() {
$(".avatarMessage .postlink.new-post").oembed(null, {
embedMethod: "append",
startClosed: true,
maxWidth: 300,
}).removeClass('new-post');
});
})
Thus, the elements will not be matched on the next oembed call.
Here is another alternative, it uses a flag instead:
(function($) {
$(document).ready(function() {
$(".avatarMessage .postlink").each(function(index, element) {
var $el = $(element);
//If already embedded just return
if ($el.data('oembedded')) return;
//set the flag
$el.data('oembedded', true);
$el.oembed(null, {
embedMethod: "append",
startClosed: true,
maxWidth: 300,
});
});
});
});
I hope this will help you.

Related

jquery/javascript to listen for a 3rd party plugin overlay to be closed

I'm currently using a 3rd party jquery plugin which when called from a page, pops up with an overlay, and some forms that are not part of my site.
I've been trying (with no joy so far) to be able to detect from my own sites jquery, when this overlay is closed. I'd like to simply jump to a certain part of the page.
I've tried writing jquery to listen for the final button of the 3rd party form being closed, by checking for it's class name being removed, with .remove .destroy and checking for it's existing with .length and some other methods. however, it seems that my on page jquery can't see anything about these elements at all, and therefor I can't do something fun when that dialogue ends.
Anyone got any ideas of how this could be achieved? Am I missing something obvious?
Cheers in advance!
I was able to get this working via the below javascript. Maybe there is a better way, but this seems to be working well
<script>
var bookingInterval;
$("#ViewingButton").click(function () {
setTimeout(function () {
bookingInterval = setInterval(function () {
if ($(".agent-ui-modal")[0]) {
// Do nothing if class exists
} else {
// Do something if class does not exist
window.location = ("#calculator");
stop();
}
}, 500);
}, 5000);
});
function stop() {
clearInterval(bookingInterval);
}
</script>

Auto-refresh content inside a div?

I know this question has been asked several times. And I have read all the threads without coming to a solution. I use Wordpress, together with a plugin, this plugin lets me add events to it. I use the "shortcode"/[slug] on a Wordpress page. This displays the events I have added. If I add or remove an event I need to manually refresh the page to see this.
My goal is to be able to see the new events (and removed) without refreshing the whole page.
If I check the page with chrome together with the source I find that a div id="vs" is what contains all the events.
I have made an addition to the plugin where I've created a javascript.
jQuery(document).ready( function($) {
var auto_refresh = setInterval(
function() {
$.ajax({
url: "https://example.com",
success: function( data ) {
$("#vs").html( $(data).find('div').html());
}
})
}, 5000); // refreshing after every 5000 milliseconds
})
What happens is that it is refreshed automatically. But it displays a lot of elements, and it is a duplicate of the content that was already there. And everything is offset too.
I really don't know what to try?
And also, the page which this is displayed on is a slider, both displaying the same slug, but it only "works" on the first slider.
Any ideas?
So it's a little hard to answer without seeing what all the dom looks like but it sounds like you are not replacing the content but rather just adding to it over and over again. As a result, slowly the width content is getting smaller and smaller which is why you get the indenting affect. My guess is you're using .html when you want to be using .replaceWith
http://api.jquery.com/replacewith/
var auto_refresh = setInterval(
function() {
$.ajax({
url: "https://example.com",
success: function( data ) {
$("#vs").replaceWith( $(data).find('div').html());
}
})
}, 5000); // refreshing after every 5000 milliseconds
If this doesn't work I think we need to see what your dom looks like.

How to hide loader when there is no more page to be loaded

In this website that I am building https://vase.ai/blog/ , I am using a script of infinite scrolling to make several pages into one page for scrolling.
I would like to hide the loader(the spinning one) when there is no more page to be loaded. I figured that the following code might be able to help me to detect the error (Failed to load resource: the server responded with a status of 404 (Not Found)) and execute the hiding. However, it does not work. Am I missing something out?
window.addEventListener('error', function(e) {
$('loading').fadeOut()
}, true);
Code that I use to to load more :
//implementing infinite scrolling
$grid.infinitescroll({
// Pagination element that will be hidden
navSelector: '.pagination',
// Next page link
nextSelector: '.pagination a',
// Selector of items to retrieve
itemSelector: '.grid-blog',
},
// Function called once the elements are retrieved
function(new_elts) {
var elts = $(new_elts).css('opacity', 0);
elts.animate({opacity: 1});
$grid.packery('appended', elts);
$('.target-resize').textfill({
maxFontPixels: 36,
changeLineHeight:false
})
$grid.packery({
itemSelector: '.grid-blog',
gutter: 20,
})
});
It's difficult to answer your question without the code that make the http calls in order to load your content. But,
1) you may have an error, and still have contents to be loaded, in that case your loader will disappear even if contents are still loading.
2) You should have something that tel your site what you have to load.
an array of url, or anything, you can maybe use this to hide your loader when all contents has been loaded.
3) You should have somewhere a function that make httpcalls to get your content. This function should have a callback. In this callback, you should be able to catch an error, and then hide your loader.
I cannot give you more informations with the amount of code you show in your exemple.
edit : after looking at your code, you may try to do :
// Function called once the elements are retrieved
function(new_elts) {
if(!new_elts) {
$('loading').fadeOut();
return;
}
...
}
I don't think this is the right solution, your plugin should have a built-in function to stop calling new pages, but since I don't see the function that make the http call, or any array/iterator of URLs, it's difficult top help you.
you should check this demo to : https://codepen.io/desandro/pen/rwwoGe

Touchwipe integration - one-page-site script

I have been spending most of the day troubleshooting and searching for an answer to my question regarding TouchWipe (http://www.netcu.de/jquery-touchwipe-iphone-ipad-library) integration on this custom one-page-site script (http://www.joerg-niemann.de/blog/up-down-left-right-scrolling-single-page-website/) based on Parallax, which was exactly what I was searching for for my latest project.
The script itself does everything I want it to, beautiful transitions and keyboard control straight out of the box, but I can't for the life of me, get the hang of how to integrate TouchWipe.
The idea is, that visiting iOS user should be able to wipe/swipe/slide between the pages with their finger with the same ease, as clicking the navigation arrows, or using a keyboard currently does.
My problem is failing at trying to call the same functions for TouchWipe gestures as clicking the arrows, or using the keyboard. The on-click function calling part of the script looks as follows:
function setRight(page, text) {
$("#rightText").text(text);
$("#rightControl").show().unbind('click').click(function () {
parallax[page].right();
});
rightKey = function () {
parallax[page].right();
};
}
I'm by no means a JavaScript developer, and since I haven't been able to find a decent answer anywhere (shame on me for using a custom script without a FAQ) on how to integrate touch with this lovely script, I'm reaching out to you.
I've tried numerous different variations of calling the necessary functions on wipe/swipe/touch, but all have failed to function. I can't for the life of me figure out why this isn't working:
<script>
$(document).ready(function(){
$('body').touchwipe({
wipeLeft: function(){ parallax[page].left(); },
wipeRight: function(){ parallax[page].right(); },
wipeUp: function(){ parallax[page].top(); },
wipeDown: function(){ parallax[page].bottom(); }
})
})
</script>
I hope I've made myself clear, otherwise feel free to take a jab at me, and I will supply further information if requested. I'm sure there is a simple explanation to why it isn't functioning the way I'd like it to, but I just can't seem to figure it out.
I finally figured out how to implement the TouchWipe script with Parallax.js.
Here's the answer for anyone experiencing the issue as myself in the future:
<script>
$(document).ready(function(){
$('#index').touchwipe({
wipeLeft: function(){ $(".control").hide(); parallax.right.right(); },
wipeRight: function(){ $(".control").hide(); parallax.left.left(); },
wipeUp: function(){ $(".control").hide(); parallax.top.top(); },
preventDefaultEvents: true
});
$('#right').touchwipe({
wipeRight: function(){ $(".control").hide(); parallax.index.left(); },
preventDefaultEvents: true
})
$('#left').touchwipe({
wipeLeft: function(){ $(".control").hide(); parallax.index.right(); },
preventDefaultEvents: true
})
$('#top').touchwipe({
wipeDown: function(){ $(".control").hide(); parallax.index.bottom(); },
preventDefaultEvents: true
})
});
</script>
Turns out I had to call each function seperatly, why, I do not know, but for some reason it wouldn't accept calling both functions in the combined function.
So first, call the functions that hide the controls like so (seperate by semicolon, so you can add another function):
$(".control").hide();
Then you have to call the transition and page change like so (the last ID (parallax.xxxx.ID is used to call from which side you want the new page to slide in from - as I was using TouchWipe to set up the site as a webapp, I would of course slide the page in from the opposite site: wipeUp triggers parallax.top, wipeLeft triggers parallax.right etc.):
parallax.index.bottom();
Here is the new, improved and kickass jsfiddle:
http://jsfiddle.net/Q96uH/2/
Code on my fellow stackers!

Action-dependant Javascript/Jquery - how to activate a command only AFTER another script has finished?

I'm working on my website and I decided it would be to my advantage to use 'designed' scroll bars instead of the ones browsers come with. I was lucky enough to come across this script http://www.hesido.com/web.php?page=customscrollbar which basically does exactly what I need.
The only problem I've got is that I am trying to apply the custom scrollbars to some divs which are initially hidden and then toggle via a link div between hide/show.
As the programming page (http://www.hesido.com/flexcroll/flexcroll-programming.htm) explains, sometimes the scrollbar needs to be updated and/or manually applied, because being in hidden divs they do not load when the page opens.
I've checked my CSS and my HTML and the code works fine if the div is not hidden, so I am 100% that this has to do with the way I am hiding my divs.
The basic format for that is
$(document).ready(function() {
$('#iddiv').hide();});
$(document).ready(function() {
$('#id').click(function() {
$('#iddiv').animate({
height: 'toggle'
}, 2000
);
});});
So I hide it initially, and then toggle it via a button.
Now, in this logic - the manual application of fleXenv.fleXcrollMain("your-div-id"); should be somewhere above the last line of script (the one containing }); ).
This, however, either makes the div unscrollable or messes up the rest of my Javascript (scrollTo functions stop working, etc...)
My question is, as a bit of a noobie JS user - WHERE do I need to place that piece of code that manually activates the custom scrollbar in my code AFTER the toggle is activate and WHAT is the structure?
By which I mean, does fleXenv.fleXcrollMain("your-div-id"); stand on its own, does it need its own separate function, does it get a $ before it?
Loads of thanks to anyone who can help me with this! Final bit stopping me from launching my website.
UPDATE!
HERE is the CSS/HTML and code for an example of what I am trying to achieve; because one of the files in the script needs to be downloaded to work, I think the only way is to copy and paste all the bits in a new HTML document.
The jQuery .animate() function accepts more arguments. One of them is a function that gets called when the animation completes.
function activateScrollbar () {
fleXenv.fleXcrollMain('iddiv');
}
$('#iddiv').animate({
height: 'toggle'
},
2000,
activateScrollbar
);
You can also use an anonymous function, like this:
$('#iddiv').animate({
height: 'toggle'
},
2000,
function () {
fleXenv.fleXcrollMain('iddiv');
}
);
Most functions in jQuery that include an animation, (like .hide() or .fadeOut()), allow you to pass a function that gets called when the animation completes. Most of these jQuery functions allow you to pass these extra arguments in a configuration object which can be more readable:
$('#iddiv').animate({
height: 'toggle'
},
{
duration: 2000,
complete: function () {
fleXenv.fleXcrollMain('iddiv');
}
}
);
See the .animate() documentation for more details.
Here's a full example with the click behavior included:
$('#myButton').click(function () {
$('#iddiv').animate({
height: 'toggle'
},
{
duration: 2000,
complete: function () {
fleXenv.fleXcrollMain('iddiv');
}
}
);
});
Try this:
$(document).ready(function() {
$('#id').click(function() {
$('#iddiv').animate({
height: 'toggle'
}, 2000,
function(){
fleXenv.fleXcrollMain( $(this).attr('id') );
}
);
});
That function is callback executed after animate function is complete.

Categories