Trying to refresh div inside Iframe - javascript

I have a section of my site im working on where i have a certain div, the div "comments" needs to be checked for blank comments being posted and remove them, it works fine the first time but after the div is refreshed it stops working. I'm trying to get this script to reload every second along with the div so the results stay consistent. Here are my 2 scripts:
<script type="text/javascript">
function doRefresh(){
$("#comments").load("comment.txt");
}
$(function() {
setInterval(doRefresh, 1000);
});
</script>
<script>
setTimeout(refreshData, 1000);
function parent()
{ $(".comment_name:empty").parent().hide()};
refreshData();
</script>

For future reference you should have a look into websockets. This will enable you to have data refresh as it is entered from one browser to another and will always keep it up to date without refreshing.
Here is a reference for you to get started. https://developer.mozilla.org/en-US/docs/Web/API/WebSocket
It is a starting point and will help you a lot in future for dynamic content on multiple end points.

Related

Jquery can't seem to target contents of modal

I wish to append some content within form within a modal and so have created:
$('.simple_form').append("<p><a href='google.com'>Apply now</a></p>");
However, this does not appear to work -the HTML above deosnt not append, not do I see any errors in the console.
I can do other stuff on the page - append the text anywhere else, just not to part of the modal.
The site is using the Near Me platform, an example site of which is here: https://desksnear.me/
I am just trying to affect the modal that appears when you click Log In at the top right.
Would anyone know why this isn't working and what I could do to get back on track?
I think the modal gets created anew every time you click the Log In button. So the .simple_form changes get overwritten before they can be seen.
There isn't an ideal solution to this problem if you can't tap into an event that occurs when the modal is opened and all the content in it has been initialized. I would suggest using an interval to repeatedly check if the modal is visible (for some capped amount of time, in case something fails), and then insert your HTML code at that point.
$('.nav-link.header-second').click(function() {
var token = setInterval(function(modal) {
if (modal.hasClass('visible')) {
$('.simple_form').append("<p><a href='google.com'>Apply now</a></p>")
clearInterval(token)
}
}, 10, $('.modal-content'))
// set a limit on the interval in case of failure
setTimeout(clearInterval, 2000, token)
})
Wrap it in document ready, the element must be there when the code executes(assuming you already have the element with class .simple_form as hidden)
$(document).ready(function(){
$('.simple_form').append("<p><a href='google.com'>Apply now</a></p>");
});

Clicking a link does not refresh the content

I've been looking at how to automate actions on a webpage with PhantomJS, however I'm having issues manipulating the page to do what I want it to.
I'm using this as test site. I've managed to get Phantom to open the webpage and scrape the random sentence from the #result span. But now what I want to do is get another sentence without re-launching the script. I don't want to close and re-open the page as Phantom takes ages to launch the webkit and load the page. So I thought I could get another sentence by getting Phantom to click on the 'Refresh' button below the sentence box. Here's what I have at the moment:
var page = require('webpage').create();
console.log("connecting...");
page.open("http://watchout4snakes.com/wo4snakes/Random/RandomSentence", function(){
console.log('connected');
var content = page.content;
var phrase = page.evaluate(function() {
return document.getElementById("result").innerHTML;
});
console.log(phrase);
page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
page.evaluate(function() {
$("frmSentence").click();
});
});
var content = page.content;
var phrase = page.evaluate(function() {
return document.getElementById("result").innerHTML;
});
console.log(phrase);
phantom.exit();
});
As you can see I'm trying to click the refresh button by using a .click() function, but this isn't working for me as I still get the same sentence as beforehand. Given the HTML for the button:
<form action="/wo4snakes/Random/NewRandomSentence" id="frmSentence" method="post" novalidate="novalidate">
<p><input type="submit" value="Refresh"></p>
</form>
I'm not sure what I should be referencing in the script to be clicked on? I'm trying the form ID 'frmSentence' but that isn't working. I'm wondering if .click() is the right way to go about this, is there some way for Phantom to submit the form that the button is linked to? Or maybe I can run the associated script on the page that gets the sentence? I'm a bit lost on this one so I don't really know which method I should go with?
You have a problem with your control flow. page.includeJs is an asynchronous function. If you have some other statements page.includeJs, they are likely executed before the script is loaded and the callback is executed. It means in your case that you've read the sentence 2 times before you even trigger a click.
If you want to do this multiple times, I suggest to use recursion since you cannot write this synchronously. Also, since you want this to be fast, you cannot use a static setTimeout with a timeout of 1 second, because sometimes the request may be faster (you lose time) and sometimes slower (your script breaks). You should use waitFor from the examples.
Instead of loading jQuery every time, you can move page.includeJs up and include everything else in its callback. If you only need to click an element or if jQuery click doesn't work (yes, that happens from time to time), you should use PhantomJS; click an element.
web scraping is about sending require information to a web server and get the result. It is not about behaving like a user clicking button or entering search criteria.
All you need to do in this example is send a POST request to http://watchout4snakes.com/wo4snakes/Random/NewRandomSentence. The result is just text in page.content, it does not even need to evaluate. So to get more than one sentence you just need to do a loop of page.open

History object back button with iframes

I'm having problems with history object and iframes in javascript/html5. I wrote a simple project to describe my problem:
http://dktest.evermight.com/
It's a page with an iframe and a next button. Every time you click next, it loads a new page with an incrementing counter. However, clicking the browser back button doesn't do what I want it to do. Let me explain the problem by breaking this post up into the following sections:
What I'd like to achieve
Undesired results in current project
Post all my code
1. What I'd like to achieve
I want the user to:
Open a new window and go to http://dktest.evermight.com/
Click next page and see a redbox fade in, and to see the url http://dktest.evermight.com/count.html?count=0 appear in both the iframe AND the browser's address bar
Click next page again and see http://dktest.evermight.com/count.html?count=1 in the iframe and browser's address bar
Click browser's back button ONCE and see http://dktest.evermight.com/count.html?count=0 in both the iframe and the browser's address bar
Click browser's back button ONCE and see http://dktest.evermight.com/ in the browser's address bar AND see the red box fade out
2. Undesired results in current project
With my code at http://dktest.evermight.com/, it's currently not performing steps 4 and steps 5 correctly. When I perform step 4, the iframe shows http://dktest.evermight.com/count.html?count=0 but the browser address bar shows http://dktest.evermight.com/count.html?count=1. I have to press the browser's back button again to make the browser address bar show http://dktest.evermight.com/count.html?count=0. When I perform step 5, the red box fades out which is great, but the address bar is still showing http://dktest.evermight.com/count.html?count=0. I have to press back again to make the address bar show http://dktest.evermight.com/.
3. Post all my code
My code is pretty straight forward. You can view source on http://dktest.evermight.com/. I will also post here for convenience.
index.html
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script type="text/javascript">
var count=0;
function clicknext()
{
$('#container').fadeIn();
$('#iframe').attr('src','count.html?count='+count.toString());
$('html title').html(count);
history.pushState({blahblah:'whatgoeshere?'},'i dont know what goes here either','http://dktest.evermight.com/count.html?count='+count);
count++;
}
function hideContainer()
{
$('#container').fadeOut();
var closeurl = 'close.html';
if($('#iframe').attr('src') != closeurl )
$('#iframe').attr('src', closeurl);
}
$(document).ready(function(){
hideContainer();
});
</script>
</head>
<body>
<div id="container" style="display:none; background:red;">
<!-- IMPORTANT
When DOM first created, the iframe.src MUST BE initialize.html
I have some code that I need to fire on that page before the rest
of this document starts
-->
<iframe id="iframe" src="initialize.html"></iframe>
</div>
<input type="button" onclick="clicknext()"; value="next page" />
</body>
</html>
close.html
<!DOCTYPE html>
<html>
<script type="text/javascript">
parent.hideContainer();
</script>
</html>
count.html
I CAN NOT modify the contents of count.html. In my real project, count.html is actually a youtube video, which is on a server I can't directly access.
<html>
<body>Youtube video at url <script type="text/javascript">document.write(location.href);</script></body>
</html>
initialize.html
Perform application specific functionality
Can anyone correct my code to achieve the results of step 4 and step 5 as described in section 1?
UPDATE
Ok, I'm appreciating the problem a bit more based on some experiments I'm doing.
Experiment 1: I tried changing the line:
$('#iframe').attr('src','count.html?count='+count.toString());
to
$('#iframe')[0].contentWindow.location.replace('count.html?count='+count.toString());
This allowed me to perform step 4 correctly. Apparently, contentWindow.location.replace() will not create an entry in the history object. However, this caused some other issues related with the contents of count.html, which is actually a page to youtube/vimeo content. The youtube/vimeo content REQUIRES that you load information via the attr('src') approach instead of .contentWindow.location.replace(). So perhaps the solution is to find a way to make attr('src') NOT create an entry with the history object?
Experiment 2 Another possible solution I tried was changing the order of the attr('src') and history.pushState() call. I tried calling attr('src') first then history.pushState() second, and also history.pushState() first then attr('src') second. But in both cases, when I push the browser's back button, it is the iframe content that goes back first. So there's no way for me to capture pass myself a message via the history object to do a "double back", since information in the history object is available LAST in the sequence of events.
Experiment 3 I also tried working with History.js. It did not do anything to solve my problems above. From what I could tell, it worked exactly like the regular history object.
Does anyone have any thing else I can try? Or suggest modifications to any of the experiments above? I'm going to explore Experiment 1 further as a separate stack overflow question.
I create a new iframe and destroy the iframe when loading new content. That solves the history issues.
I know this is a history problem but if you are still open to other possibilities, I think jquery-pjax is actually more suitable for what you are trying to do.
UPDATE I think this should work.
count.html
<div id="pjax-container">
<a id="pjax" data-pjax href="#">Next Page</a>
</div>
javascript
// get URL parameter (count): http://stackoverflow.com/questions/1403888/get-url-parameter-with-jquery
function getURLParameter(name) {
return decodeURI(
(RegExp(name + '=' + '(.+?)(&|$)').exec(location.search)||[,null])[1]
);
}
$(document).on('pjax:beforeSend', function() {
// your fading code goes here
})
$(document).on('pjax:complete', function() {
// fade out
// and then modify the anchor's href with something like
var new_count = getURLParameter('count') + 1;
$('a#pjax').attr('href', 'count.html?count=?' + new_count);
})
// where the pjaxed content should go
$(document).pjax('a[data-pjax]', '#pjax-container')

jQuery Auto refresh div messing up

I have a script that auto-refreshes a certain div on the page (That I got from another post on here)
<script type="text/javascript">
var auto_refresh = setInterval(
function(){
$('#refresh').load('index.php?_=' +Math.random()).fadeIn("slow");
}, 10000); // refresh every 10000 milliseconds
</script>
...............
<div id="refresh">
<!-- Some PHP Code -->
</div>
This refreshes, however when it does, I takes the entire html document and puts it into the div. Like this:
As you can see, the refreshed div (the one marked in red) is getting the body shouved into it. Any ideas???
You are loading entire page to the div.
Modify the code to use only part of the document that is fetched:
<script type="text/javascript">
var auto_refresh = setInterval(
function(){
$('#refresh').empty();
$('#refresh').load('index.php?_=' +Math.random()+' #refresh').fadeIn("slow");
}, 10000); // refresh every 10000 milliseconds
</script>
First off, you are loading the entire page into the divider, thus causing the file to reload entirely. Instead, you should be having the Recent Posts divider load from a single file, even on the first page load. Then have that consistently refresh over time.
Secondly, you should be transferring as little data as possible from your server to your clients. At most, you should use a minimalistic checksum of sorts (number of messages, for instance) to confirm that the client and server are synced up.
Lastly, if you choose to use this format, aim to transfer your data in something such as JSON or XML and have the client display it on the page. Transferring the styled HTML increases network overhead and is not the best practice.

Preloader does not preload and loads the page a second time

I found this nice jQuery preloader/progress bar, but I cannot get it to work as it is supposed to. The problem is that it first loads my page and after my whole page is loaded the 0%-100% bar displays quickly, after that it reloads my page again. So it does not show the progress bar BEFORE the page loads and it loads the page a second time as well.
Here is my implementation code:
<head>
<script src="js/jquery-1.7.2.min.js" type="text/javascript"></script>
<script src="js/jquery.queryloader2.js" type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$("body").queryLoader2();
});
</script>
</head>
<body>
My content...No other reference in here for the Jquery preloader
</body>
Thanks for any help in advance.
I could be very, very wrong here, but in my opinion:
The plugin is flawed.
You have some issue in your page that causes a redirect.
I have created a test fiddle and found out the following:
If there are no images on the page, then the plugin's private function completeImageLoading(); is never called because it is only bound to the image elements. When there are no images -> there's no binding -> no triggering -> nothing completes -> you stay with overlay 0% as demonstrated by the fiddle that is NOT RUN (jsfiddle doesn't see relative images when the page is not run).
The plugin doesn't take into consideration remote images. So if you declare them like so <img src="http://example.com/image.jpg"> - then it won't work because the plugin doesn't recognize them. In fact it is using $.ajax to load images which, obviously, generates a error when trying to access another domain.
The plugin doesn't reload the page (at least in Google Chrome)... check your console output while in the fiddle. It displays the message once per click on Run.
Suggestions:
Make sure you provide at least one relative or background image (though I haven't tested backgrounds...) for the plugin to work.
Show us more code. The fiddle demonstrates that the plugin does NOT cause page reload (at least in Chrome... are you using another browser?). It must be something you made that interferes here.
Specify some options for the plugin (behaves weird when there are none).
Edit regarding preloader
Regarding preloader... if displaying progress is not mandatory for you, then you can just use a window.onload trick. On DOM ready $(...) you create an opaque page overlay with a "Please wait..." message and some animation if you fancy it. Then you wait for window.onload event which "fires at the end of the document loading process... when all of the objects in the document are in the DOM, and all the images and sub-frames have finished loading." When window.onload triggers, you just remove your overlay and voila - the page is ready!
Edit 2 regarding preloader
Actually, you don't even need $(...)... what the hell was I thinking? Just create your overlay (a simple div with a unique id) in your html, style it so that it fills the screen and give it a z-index:1337 CSS attribute so that it covers the entire page. Then, on window.onload:
window.onload = function () {
// Grab a reference to your overlay element:
var overlay = document.getElementById('myOverlay');
// Check if the overlay really exists
// and if it is really appended to the DOM,
// because if not - removeChild throws an error
if (overlay && overlay.parentNode && overlay.parentNode.nodeType === 1) {
// Remove overlay from DOM:
overlay.parentNode.removeChild(overlay);
// Now trash it to free some resources:
overlay = null;
}
};
Of course, it's not really a preloader, but simply an imitation.
Here's a working fiddle you can play with.
P.S. I personally don't appreciate preloaders, but that's just me...
Try out this(Remove the document.ready event and simply call this):-
<script type="text/javascript">
$("body").queryLoader2();
</script>

Categories