Hello lovely people of StackOverflow.
I'm trying to create a dynamic page using JavaScript AJAX and PHP.
I have created a list of images which have unique ids numbers 1-12. When one is clicked it should pass that id onto a function which changes the page, then uses the id number to load in content to the new page.
My problem is that when I use document.location to change the page (or window.assign) it does not change the page before enacting the following code which loads in the content. Therefore it tries to load the content to a div which doesn't exist on the current page, then changes the page. Does anybody know why this is? And how I can solve it?
I have tried putting the document.location and innerHTML code in separate functions, but the next function is still called before the page changes. I have also tried putting an if statement ahead of the content load but that is also called before the page changes.
Here is my code:
function output (bookList){
for (var i = 0; i < titles.length; i++) {
document.getElementById("insertBooksHere").innerHTML += "<ul class=\"bookItem\">";
for (var t = 0; t<position.length; t++){
if (t==position.length-1)
{
x = bookList[i][0];
document.getElementById("insertBooksHere").innerHTML += "<img class=\'books\' id = \'" + x + "\' src=\'" +bookList[i][t]+ "\' onClick=\'getBookDetails("+ x +")\'>";
}
else
if ( t == 1 || t==2){
document.getElementById("insertBooksHere").innerHTML += "<li>"+bookList[i][t]+"</li>";
}
}
document.getElementById("insertBooksHere").innerHTML += "</ul></div>";
}
}
function getBookDetails(id){
bookID = id;
for ( var t = 0; t<12; t++)
{
bookDetails[t] = bookList[bookID-1][t];//grab details about specified book from array using x as the value for i.
}
loadBookPage(bookID, bookDetails)
}
function loadBookPage(bookID, bookDetails){
console.log(window.location.href);
}
function loadBookDetails(){
if ( document.location == 'books/'+bookID+'.php')
{
x = bookID;
console.log(bookDetails);
document.getElementById("book").innerHTML += "<ul class=\"bookItem\">";
for (var t = 0; t<position.length; t++){
if (t==position.length-1)
{
document.getElementById("book").innerHTML += "<img class=\'books\' id = \'" + x + "\' src=\'" +bookDetails[t]+ "\'>";
}
else {
document.getElementById("book").innerHTML += "<li>"+bookDetails[t]+"</li>";
console.log("for loop");
}
console.log(bookDetails[t]);
}
document.getElementById("book").innerHTML += "</ul>";
document.getElementById("book").innerHTML += "HELLO!!!";
}
}
And you can see my work here: http://itsuite.it.brighton.ac.uk/rlr17/bookClub/home.php
Thanks guys! Really appreciate your help.
My problem is that when I use document.location to change the page (or window.assign) it does not change the page before enacting the following code which loads in the content.
That is how JavaScript (when running client side, embedded in a webpage) works.
It runs in that page.
If the page goes away (because you loaded a new page) then its execution environment goes away and it stops running.
If you want to do something in the next page then you have to pass some data to that page and have code in the new page read that data and act on it.
Ideally, you would do this using server side code (as it is more reliable, and rarely has an additional runtime cost when you are loading a new page anyway).
Related
I have a js code that adds margin-top to a row with a specific class name (page with id=3) . I would like this code runs before page load because now it instantly displays the row without margin-top and then add it. The row should be displayed with the margin-top already be added.
My site is on wordpress and i added the js script on head.
I have tried
window.onpaint = checkMargin();
but it did not work. Any idea?
This is my js code
<script type="text/javascript">
//sets margin-top in serv-col --- IF not mobile version
function addServMargin() {
containers = document.getElementsByClassName('serv-cont');
titles = document.getElementsByClassName('serv-col-title');
texts = document.getElementsByClassName('serv-col-text');
links = document.getElementsByClassName('serv-col-link');
col_pad = '0px';
if ( window.innerHeight > 800) { col_pad = '8.3vh'; }
for (var i = 0; i < titles.length; i++) {
title_height = titles[i].offsetHeight;
text_height = texts[i].offsetHeight;
style = window.getComputedStyle(containers[i], '');
cont_height = style.getPropertyValue('height');
cont_padd = style.getPropertyValue('padding-top');
links[i].style.marginTop = 'calc(' + cont_height + ' - ' +
cont_padd + ' - ' + col_pad + ' - ' + title_height + 'px - 1.48vh - ' +
text_height + 'px - 127px - 5vh)';
}
}
function checkMargin() {
if (document.getElementsByClassName('page-id-13')[0] && window.innerWidth > 900) { addServMargin(); }
}
window.onresize = checkMargin;
</script>
I don't think making it run first will solve anything. The first thing the code does is get the containers, titles, texts, and links... which it does by searching the DOM. It then loops through the titles array and does the adjusting as needed. If the script runs before any rendering is done, the DOM elements won't exist. It 1) won't be able to find them, and 2) can't loop through them because the array will be empty.
Actually even before that, it checks for the existence of the elements it's looking for, and the screen size. I think the only way to get it to work w/o making it look like an after thought adjustment, would be to use CSS and media sizing to set the styles in the first place.
As I know JS is executed as the script tag is reached by Browser html interpreter. So putting it in the head tag on the first position may guarantee that it strats first, but can't guarantee that it ends execution before page loads, because the page loads asynchroniously.
I'm trying to make a JSP that refresh itself every 2scd approximately and keep what the user tip in input form.
My idea was to save the input with javascript, add them to the URL and refresh the page, then retrieve and set the input.
This is my JS code :
$(document).ready(function () {
function refreshPage(){
var mapValue = new Array();
var mapName = new Array();
var i = 0;
$(".positionInput").each(function() {
mapValue[i] = $(this).val();
mapName[i] = $(this).attr("name");
i++;
});
var parameters = "";
for(i = 0; i < mapName.length; i++){
if(mapValue[i] != ""){
parameters += "?" + mapName[i] + "=" + mapValue[i];
}
}
window.location.href = "http://localhost:8080/drawinguess/waitingplayer.jsp" + parameters;
setTimeout(refreshPage, 2000); //execute itself every 2s
}
refreshPage();
});
But the timer get crazy (even with 1mn delay), it refresh itself as fast as he can with window.location.href (without this, it's working fine)
Thanks in advance if you have any other idea or if I'm making something wrong
You could try and use local storage for this. The best way would be that instead of refreshing the entire page, you only refresh what is needed by having services set up and using an async function like fetch() to hit those services and update the page.
I'm building a Firefox Add-On, and I need to a button in the settings page that opens a page with a list of words that the Add-On has stored. What's the best way to do this?
I've come up with this:
function ShowList() {
// We get the array from the local storage.
function createList(item){
var list = [];
// Get the stored list, if there's any.
if (item[0].list){
list = item[0].list;
}
}
function onError(e) {
alert("Error:" + e);
}
browser.storage.local.get("list").then(createList, onError);
// Once we have the list, build an HTML string with its contents
var listhtml = ['<!DOCTYPE html>',
'<html>',
' <head>',
' <meta charset="utf-8">',
' </head>',
' <body>',
' <ul>'].join("\n");
for (var w= 0; w < list.length ; w++) {
listhtml += ' <il>' + list[w][0] + '</il>\n';
}
listhtml += [' </ul>',
' </body>',
'</html>'].join("\n");
var oMyBlob = new Blob([listhtml], {type : 'text/html'}); // the blob
window.open(URL.createObjectURL(oMyBlob));
}
but HTML inside a string looks pretty awful. Any suggestions?
Normally, one would have a results page (e.g. results.html) that is within your extension directory. This will have the basic HTML framework and any included CSS and scripts for the page. You can then dynamically modify the page's DOM once it is open.
If you are in a background page, or a content script is not stated in your Question. Assuming you are doing this from a background page, you could open the results.html by following the information in Show HTML file contained within the extension. That answer provides code for opening the page in the current tab, a new tab, or a new window.
I am using this JavaScript popup menu in my ASP.NET Web Forms project: http://jsfiddle.net/o8x59caz/4/
This code is working fine until I call a JavaScript function that contains Ajax code. And this function and the one given in the fiddle has no relation or common tags (or tag classes) between them. But whenever I call this Ajax function, it disables the popup menu and nothing happens when I click on the button that displays this popup menu. But before the control reaches this Ajax function, this popup menu is working fine. I tried to check the browser console but it shows no error or warning. Following is the code of my Ajax function:
var curevaldiv, ecount = 0;
function SaveAll() {
var gifurl = '<data url of gif animation';
var evalDivs = $("div.evld");
if (evalDivs.length > 0) {
evalDivs.html("<img src='" + gifurl + "' alt='Please wait. ' style='height:35px'/> <span style='font-size: medium'>Evaluating...</span>");
var i; var infoids = '';
for (i = 0; i < evalDivs.length; i++) {
curevaldiv = evalDivs[i];
infoids = infoids + curevaldiv.dataset.infoid + ';';
}
SendToServer(3,
{ "InfoIDs": infoids },
null,
function (data) {
if (data.rstat != -1) {
var infoid, infoval;
var infovals = data.rhtml.split(';');
for (var j = 0; j < infovals.length; j++) {
infoid = infovals[j].split(':')[0];
infoval = infovals[j].split(':')[1];
$('#val' + infoid).html("<i class='fa fa-calculator'></i> <span class='counter'>" +
(infoval == "[ERROR]" ? "<font color='red'><small><i class='fa fa-exclamation-circle'></i> ERROR</small></font>" : infoval) +
"</span>");
}
ecount++;
}
else
curevaldiv.innerHTML = "<font color='red'><small><i class='fa fa-exclamation-circle'></i> ERROR</small></font>";
},
function () {
curevaldiv.innerHTML = "<font color='red'><small><i class='fa fa-exclamation-circle'></i> ERROR</small></font>";
});
}
}
SendToServer() is a Utility function created by me to avoid writing common Ajax parameters again and again.
Please help me! This problem is making my head heavy for past three days. :(
Thanks to #eck for suggesting Chrome's Break On feature. It helped me in detecting where the DOM was breaking. I traced the function call sequence and found a function that was making the HTML of the div containing the popup menu's HTML to null and then again resetting it back to the popup menu's HTML. But the plugin was called on previous popup menu's HTML. I removed that code and now it's working fine. :)
I have a function that should be called whenever my html page loads. The <body> tag should call the startAdPage() function. However, nothing at all happens. I am not completely sure why. Any suggestions? Here is the <body> call in my HTML page
<body onload="startAdPage();">
Next, here is my startAdPage() function, as well as the two functions it calls. Those two aren't completely finished yet. One of them is supposed to create a small image gallery slide show. The other is supposed to create a countdown from 10 - 1 before displaying a separate web page. Neither work yet, so any advice on them would also be appreciated, though they aren't my main focus yet.
function startAdPage(){
setInterval(changeAd(), 2000);
setInterval(startCountdown(), 1000);
}
Here is changeAd()
function changeAd() {
for(var i = 1; i < 4; i++){
document.images[0].src = "images/pic" + intNumber + ".jpg";
}
}
Lastly, startCountdown(). I haven't made the webpage that I said this function calls yet
function startCountdown() {
window.alert('Test');
for(var i = 10; i >= 1; i++){
document.getElementById("countdown").value = i;
}
}
Your problem is right here:
document.images[0].src = "images/pic" + intNumber + ".jpg";
You refer to intNumber but you should be using i instead. So change the above to
document.images[0].src = "images/pic" + i + ".jpg";
and your function will be called.
You should consider removing the onload in the body tag and do a
window.onload = startAdPage;
instead - to keep your html and Js logic separate.
Also, your countdown logic is wrong - you want to decrement i, not increment:
var i = 10; i>0; i--