.js file executes every time I click a link - javascript

I've been googling the whole day for this... I'm still a beginner at html/css/php/javascript, so I probably have some rookie mistakes, but that's why you guys are here to help me!
So, I have a dynamic website with a static template and dynamically loaded content. For example, when I click the "About Us" link, the template remains the same, but the content gets loaded from another .php file and printed out in a iframe in that same index, using the $_GET method. I'm using iframe so I don't affect the template layout. My problem is that my .js file with animations gets executed each time I click any of the navigation links, so it makes my wish to, for example, fade in the whole website once it's loaded impossible. Each time I click a link the entire website would dissapear and fade in again. I don't know did I use Google wrong, but I cannot find the solution to my problem. I only want that script to run once when the page is loaded, not whenever I click a link! Here are some parts of the code:
Part of index.php:
<?php
include('setup/setup.php');
?>
<html>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script src="javascript.js"></script>
<body>
<div class="wrapOverall">
<div class="header">Logo, language buttons etc.</div>
<div class="wrapMainNav">Main navigation (Home, About us etc.)</div>
<div class="content">
<iframe src=<?php echo "content_$language/$pg.php"; ?> frameborder="0" style="width:951px; height:486px;">aaa</iframe>
</div>
</div>
</body>
</html>
where "content_$language" is the folder from which I get the file, and "$pg.php" is the file itself.
The setup.php file:
<?php
error_reporting(E_ALL ^ E_NOTICE);
if($_GET['page'] == '')
{
$pg = 'naslovna';
}
else
{
$pg = $_GET['page'];
}
if($_GET['lang'] == '')
{
$language = 'cro';
}
else
{
$language = $_GET['lang'];
}
?>
The javascript.js file:
$(document).ready(function() {
$(".wrapOverall").hide(); //Hide the website
$("html").css("visibility", "visible");
var bg = new Image();
bg.src = "images/background.jpg";
bg.onload = function(){ //Load the background image
$("html").css("background-image", "url(images/background.jpg)");
$("html").css("background-repeat","no-repeat");
$("html").css("background-attachment", "fixed");
$("html").css("background-position", "center");
$(".wrapOverall").fadeIn(1000); //Fade in the site
$(".content").animate({height:'468px'},1000); //Animate content loading
}
});
That's about it, if you guys think you need more code I can send it.

Each time you click a link, and the URL changes, the browser makes a GET request to the server for that page. PHP will return the page and the browser will reload it, even if it's 95% the same as the last page you were on. It'll re-render the DOM and hence the $(document).ready event will fire again.
What you're looking to do is to refresh a part of the page without making a GET request to the server for the whole page. To do this you need to use AJAX.
One of the simplest ways to do this is using jQuery's load() method (click for documentation).
Have a look at the documentation and try a simple example, hopefully that will get you started.
NOTE: as has been mentioned already in the comments, there are plenty of frameworks that try to make achieving this functionality easier. Take a look at backbone.js, angularjs and ember.js to name a few. They also add a lot more, so depending on what you're trying to do, might be overkill, but it's worth a look.

Since your javascript is included in every page, it runs each time the page loads, and therefore hides and then shows the whole page. You should exclude it when loading other pages.

Have you tried to call the the iframe content with ajax ? That way the php will be called in the same time than your js functions.

Related

How to run a php file without refreshing the web page?

I have a problem. It is my full honor if anyone helps.
First, let me explain the workflow I want. My CMS is Wordpress. I have a webpage (views.php). In this page, I want to show a download button (id=” download-button”) just to users who has the role subscriber. In default, no one has the role subscriber. So, the button is hidden in default. When a user buys a specific product he gains the role subscriber. Now, suppose a user has opened views.php page as a tab in his browser. In this step, the button is hidden. After that, he opens another tab and buys that specific product and he gains the role subscriber. Now, if he refresh the view.php page, the download button is seen. But, I want the user to see the download button without refreshing the page. In this regard, I wrote button.php file to be called in ajax. However, it does not work.
My codes:
html code (written in view.php which is the place of download button):
<div id="div1"></div>
my javascript code (which is put inside view.php file):
<script>
$(document).ready(function(){
$("button").click(function(){
$("#div1").load("button.php");
});
});
</script>
my button.php code:
<?php
if (check_user_role(array('subscriber'))) {
echo ('<button id="download-button">Download</button>');
}
?>
I should note that I have written check_user_role php function in views.php.
It would be my honor if you help.
Thanks in advance.
Milad
As stated by smartdroid in one of the answers above, you can subscribe an event listener function to the window.onfocus event. Try following:
document.addEventListener("DOMContentLoaded", function (event) {
window.onfocus = function () {
$("#div1").load("button.php");
}
});
I highly recomment you to read further into javascript events.
For plain javascript:
https://www.w3schools.com/js/js_events.asp
For jQuery:
https://api.jquery.com/category/events/
Hey you have to use Window setInterval() Method, what this method does it will fire in background at your time interval set.
You can call your ajax code to set/show your button
setInterval(function(){
$("#div1").load("button.php");
}, 3000);
Make sure once you do add this button put return false so it wont execute again and again not to increase load on webpage.
$(document).ready event runs only once after the DOM is loaded. So this event will not fire unless page is reloaded.
If the user is buying a subscription in another browser tab and then returns to the original tab, windows.onfocus event will fire.
So you can use window.onfocus event to check for subscription every time view.php tab becomes active, and then show the button when necessary. So you can use something like the following, in your view.php
$(document).ready(function(){
window.onfocus = function () {
$("#div1").load("button.php");
}
});
Add an iframe to your view.php that doesn't need to contain anyting nor be visible.
<iframe name="download" id="if_download" src="blank.html"></iframe>
Target the download-action to the iframe. With some JS:
function download(href) {
window.frames['download'].location = 'download.php?file=' + href;
return false;
}
You may need to wrap the download-action through a php-file to modify its header
download.php:
$file_name = $_GET['file'];
//validate file exists and *remove any ../ - simple:
if (strpos($file_name, '/') !== false) die('yeah right..');
header("Content-Disposition: attachment;filename=\"$file_name\"");
echo file_get_contents($file_name);
die();

Page is Jumping back to Top after targeting the anchor tag

Hello guys im using wordpress and i need to jump to the comments when the user is clicking a link.
The single.php is opening in a new tab and its loading the page on the anchor (comment-id) but after that its always jumping back to the top of the page.
I Know its a problem with javascript (as its working well when i disable js) but im not sure where to find the peace off javascript i have to stop or to change on single.php.
Has anyone an idea how and where to change the javascript. So that i can stay at the comment after clicking the link on a different page?
this is the target <a name="comment'.$comment_ID.'" href="#comment'.$comment_ID.'" onclick="deletco('.$comment_ID.')">DELETE</a>
and this is the link form the other page to the target on single.php
'.$titlecomm.'
thanks for any help
First I encourage you to comment out your JS files one by one it test it out tell you find the responsible js file.
Another approach is, if its javascript issue, then you can do this with jQuery:
$('a.aCommentLinkCssClass').click(function () {
var url = $(this).attr('href').text();
window.location.href = url;
});
and add css class to your link:
'.$titlecomm.'
or if you want just JavaScript only:
<script>
function goToFunction(url) {
window.location.href = url;
}
</script>
and in your html:
<?php echo ''.$titlecomm.''; ?>
try:
onclick="deletco('.$comment_ID.'); return false;"
Or inside the function itself add a return false; at the end. You need to prevent bubbling of the event.

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')

Loading an external .htm file into a div with javascript

So I got this code
Javascript:
<script type="text/javascript">
$(function(){
$('.ajax') .click(function(e){
e.preventDefault()
$('#content').load( 'file.htm' )
})
})
</script>
html:
Link
it works perfectly in firefox, but nothing happens when I click the link in chrome and IE simply opens a new window with the file. any advice?
I am not a coder of any sort, and I know there is more than one way to make this work.
This is what worked for me for MY situation.
I had a working site but with A LOT of code / DIV content all in one page and I wanted to clean that up.
I hope this Helps someone else!
I have been searching for this solution for quite some time and I have run across many examples of how it can work in different instances.
My scenario was as follows:
I have a photography website that uses a series of DIV tags containing the various "pages" so to speak of the site.
These were all set as:
<div id="DivId" style="display:none"></div>
The following script in the head of the page:
$(document).ready(function(){
$('a').click(function () {
var divname= this.name;
$("#"+divname).show("slow").siblings().hide("slow");
});
});
</script>
and called using the anchor links like this:
HOME
Where name was the name of the DIV to be called.
Please note the DIV will be called inside the parent container DIV.
Lastly and most importantly for this particular question and scenario, the DIV were all placed on the page as shown above.
Each div content was created just as if it were within the DIV tags but minus the opening and closing DIV tags and then saved as a separate .txt file, and called by placing this is the head of the parent page:
src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js">
and
$(document).ready(function() { // this runs as soon as the page is ready (DOM is loaded)
$("#DivName") // selecting "div" (you can also select the element by its id or class like in css )
.load("PathToFile.txt");// load in the file specified
$("#AnotherDiv").load("AnotherFile.txt");// Additional DIV can be added to populate DIVs on th eparent page.
});
Change the link to href="#" or "javascript:void(0);return false;"
<a class='ajax' href='#'>...</a>
The loading logic is all in your ajax call. But, you have also a link which points to the file, too.
So, it seems that some browsers give different priorities on how the click is handled.
Anyway, links that do something other than changing page (f.ex. executing js) shouldn't have an explicit HREF attribute other than something that "does nothing" (like above)
I believe the problem is that the script loads before the document is loaded.
try this:
$(document).ready(function (){
$('.ajax').click(function(e){
e.preventDefault()
$('#content').load( 'file.htm' )
});
});
I am not sure, but i can not see any other problem.

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