white screen shows while scroll down /up the - javascript

We get the data from server and append list view .our problem is while scroll up/down first it shows white screen then after shows data.
while scroll down/up the before coming white screen should remove
for (var i=0; i<len1; i++){
if (!listCreated) {
$("#ulcontent").append("<ul id='content' data-role='listview' data-split-icon='plus' data-split-theme='b' data-inset='true' class='ui-listview ui-listview-inset ui-corner-all ui-shadow'></ul>");
var listCreated = true;
$("#ulcontent").trigger("create");
}
var geImage=result.rows.item(i).Image;
var Custimage="";
if(geImage)
{
Custimage=result.rows.item(i).Image;
}
$('#content').append('<li class="ui-li-static ui-body-inherit ui-li-has-thumb ui-first-child"><img src='+appendurl+append+Custimage+'><p style="white-space: normal;"><b>Location:</b>'+result.rows.item(i).Location+'<br><b> Description:</b>'+ result.rows.item(i).Comments+'</p></a></li>');
}
When we remove images it's not showing any white screen.But we need image
Please tell to us what wrong in my code.

ThelistCreated variable in the if (!listCreated) statement and the listCreated variable in the var listCreated = true; statement are two different variables, so if (!listCreated) is always going to return false. That means means you're never actually creating the unordered list and then the list items are just getting displayed on the page background. So try moving listCreated to the outer scope like this:
var listCreated = false;
for (var i = 0; i < len1; i++) {
if (!listCreated) {
$("#ulcontent").append("<ul id='content' data-role='listview' data-split-icon='plus' data-split-theme='b' data-inset='true' class='ui-listview ui-listview-inset ui-corner-all ui-shadow'></ul>");
listCreated = true;
$("#ulcontent").trigger("create");
}
var geImage = result.rows.item(i).Image;
var Custimage = "";
if (geImage) {
Custimage = result.rows.item(i).Image;
}
$('#content').append('<li class="ui-li-static ui-body-inherit ui-li-has-thumb ui-first-child"><img src=' + appendurl + append + Custimage + '><p style="white-space: normal;"><b>Location:</b>' + result.rows.item(i).Location + '<br><b> Description:</b>' + result.rows.item(i).Comments + '</p></a></li>');
}

Related

Javascript can't get content of element

I've written code using Javascript to format the following section of a webpage based on the values:
<div class="col-md-auto mx-auto">
<h3>Average price</h3>
<p id="avgPrice"></p>
<br>
<div>Average change</div>
<div class="change" id = "avgChange"></div>
</div>
<div class="col-md-auto mx-auto">
<h3>Max price</h3>
<p id="maxPrice"></p>
<br>
<div>Max change</div>
<div class="change" id="maxChange"></div>
</div>
(The values for the text within each of the id's are getting pulled from a database, and appear correctly on the webpage when I start the server)
Here is my Javascript to format the HTML based on positive/negative values:
function changeFormatter() {
var elements = document.getElementsByClassName("change");
for (var i = 0; i < elements.length; i++) {
var change = elements[i]; //this is where the problem is
console.log(change);
if (change > 0) {
elements[i].innerHTML = "▴ " + change + "%";
elements[i].classList.add("text-success");
}
if (change < 0) {
elements[i].innerHTML = "▾ " + change + "%";
elements[i].classList.add("text-danger");
}
}
}
This code is being called by the following eventlistener:
window.addEventListener('load', (event) => {
console.log('page is fully loaded');
getData(); //gets values from database and adds them to HMTL
changeFormatter();
});
The issue is the line where I'm defining the var change. The output of the console.log on the line below it shows the text I want is there, see image below:
But no matter what I try I cannot get the text contained within this div. I've tried elements[i].value, .textContent, .innerHTML, .innerText, parseFloat(elements[i].innerHTML)... but they all return 'undefined' when I try and log them. I would really appreciate any suggestions!
Output of console.log(elements[i], elements[i].innerHTML)
.innerHTML should be correct as seen here: https://jsfiddle.net/awLynp28/3/. All I did was copy your script, have it run on page load (since it looks like you have something like that in there, I am assuming your function is getting called after the data is fully called in), and change
var change = parseFloat(elements[i].innerHTML);
document.addEventListener('DOMContentLoaded', function() {
var elements = document.getElementsByClassName("change");
for (var i = 0; i < elements.length; i++) {
var change = parseFloat(elements[i].innerHTML); //this is where I put innerHTML
console.log(change);
if (change > 0) {
elements[i].innerHTML = "▴ " + change + "%";
elements[i].classList.add("text-success");
}
if (change < 0) {
elements[i].innerHTML = "▾ " + change + "%";
elements[i].classList.add("text-danger");
}
}
}, false);

Remove all HTML <button> elements with regex

I'm trying to build a program to run a function every time I press a button, and output the returned value. To do this, I use the following HTML:
<h2>Test Results:</h2>
<strong><span id='runs'>0</span> tests</strong><br>
<div id='testResults'>
<button id='test' onClick='this.parentNode.innerHTML = initiatePlanB()'>Begin</button>
</div>
Here's the javascript:
var tests = document.getElementById('runs');
var inner = document.getElementById('testResults').innerHTML;
//Here's the part I can't figure out
var wo = inner.replace(??????, '');
var out = wo + '<br><strong>Test #' + String(Number(tests.innerText) + 1) + '</strong><br>';
tests.innerText = Number(tests.innerText) + 1;
//More stuff here
return out;
Basically, I need either a regex expression, or some other function that can remove any html tag and it's contents.
Why not just find all buttons using getElementsByTagName('button')
and then remove them all?
var testCount = 0;
var tests = document.getElementById('runs');
var inner = document.getElementById('testResults')
function initiatePlanB() {
var buttons = inner.getElementsByTagName('button');
if (buttons) {
for (var i = 0; i < buttons.length; i++) {
buttons[i].remove();
}
}
testCount++;
inner.insertAdjacentHTML('beforeend', '<br><strong>Test #' + testCount + '</strong><br>');
tests.innerText = testCount;
//More stuff here
}
<h2>Test Results:</h2>
<strong><span id='runs'>0</span> tests</strong><br>
<div id='testResults'>
<button id='test' onClick='initiatePlanB()'>Begin</button>
</div>
Though you should probably just hide the buttons, or disable them.

Chrome - Hiding scrolled content causing body and other elements to scroll up

I am dividing my webpage in two vertical parts. Where left panel is used to render a list of categories of books and right panel is used for rendering books associated with selected category. We also have buttons to hide a specific category from left side.
<div class="content">
<div class='col-3'>
<h3> Category </h3>
<div class="category-container dev-category-list">
</div>
</div>
<div class='col-9'>
<h3> Books </h3>
<div class="books-container dev-books-list">
</div>
</div>
</div>
Javascript Code:
var categories = ['category-1','category-2','category-3','category-4','category-5','category-6','category-7'];
var books = {'cat1':['1984','Dracula','Twilight','Holes','Homes','Uglies','Othello'],'cat2':['Dracula','Twilight','1984','Holes','Homes','Uglies','Othello'],'cat3':['1984','Twilight','Holes','Homes','Dracula','Uglies','Othello'],'cat4':['Othello','1984','Dracula','Uglies','Holes','Twilight','Eclipse'],'cat5':['Hamlet','Macbeth','Othello','Holes','Night','Twilight','Eclipse'],'cat6':['1984','Hamlet','Dracula','Uglies','Othello','Night','Twilight'],'cat7':['1984','Hamlet','Macbeth','Uglies','Othello','Holes','Night']};
setup_UI_elements();
function setup_UI_elements(){
appendCategories();
renderBooks('1');
addCategListner();
addBtnListner();
}
function appendCategories(){
container = $('.dev-category-list');
for(var i=0; i< categories.length; i++){
categHtml = "<div data-categ-id='"+ (i+1) + "' class='categ'> "+categories[i]+" </div>";
container.append(categHtml)
}
}
function renderBooks(categ_id){
container = $('.dev-books-list');
container.html('');
categ_key = 'cat'+categ_id
$('.categ').removeClass('selected');
$('div.categ[data-categ-id='+categ_id+']').addClass('selected');
for(var i=0; i< books[categ_key].length; i++){
bookHTML = "<div data-book-id='"+ (i+1) + "' class='book'> "+books[categ_key][i];
bookHTML += "<button type='button' data-book-id='"+ (i+1) + "' data-categ-id='"+ (books[categ_key].length-i) + "' class='btn'> Hide Categ "+ (books[categ_key].length-i) +"</button> </div>";
container.append(bookHTML);
}
}
function addCategListner(){
container = $('.dev-category-list');
container.click(function(e){
target = $(e.target);
$('.categ').removeClass('selected hidden');
target.toggleClass('selected');
categ_id = target.data('categ-id');
renderBooks(categ_id);
});
}
function addBtnListner(){
container = $('.dev-books-list');
container.click(function(e){
target = $(e.target);
if(target.hasClass('btn')){
categ_id = target.data('categ-id');
target.toggleClass('added');
if(target.hasClass('added'))
target.html('Show Categ'+categ_id)
else
target.html('Hide Categ'+categ_id)
categDiv = $('.dev-category-list div[data-categ-id='+categ_id+']')
categDiv.toggleClass('hidden');
}
});
}
When I try to hide a category from left panel which is no longer in above the fold then it is scrolling right panel instead of left panel.
I works fine in Firefox and Safari.
JS Bin: https://jsbin.com/bafasoy/edit?html,js,output

How to rerun javascript after a function is finished

Im starting to do some small functions and tweaks on websites with javascript, but whats really bothers me is that I dont know how to run the javascript again after a function has run?
For instance if I call a function onclick which adds a user to an array that is shown in my website, the new user wont be displayed until the page is refreshed?
How do I work around this?
EXAMPLE:
if (!localStorage.myStorage) {
// CREATE LOCALSTORAGE
}else{
myArray = JSON.parse(localStorage.myStorage);
for (var i = 0; i < myArray.length; i++) {
if(myArray[i].id === 1){
$(".firstIdContainer").append("<p>" + myArray[i].userName + "</p>");
}
if(aUserLogin[i].id === 2) {
$(".secondIdContainer").append("<p>" + myArray[i].userName + "</p>");
}
}
}
$(document).on("click", ".btnRegisterUser", function() {
// ADD NEW USER TO LOCALSTORAGE
}
How do i make sure my new user i register will be shown immediately through my for loop displaying users.
Like:
if(!localStorage.myStorage){
// CREATE LOCALSTORAGE
}
function doIt(){
var myArray = JSON.parse(localStorage.myStorage);
for(var i in myArray){
var apd = '<p>' + myArray[i].userName + '</p>';
if(myArray[i].id === 1){
$(".firstIdContainer").append(apd);
}
else if(aUserLogin[i].id === 2) {
$(".secondIdContainer").append(apd);
}
}
}
}
doIt();
$('.btnRegisterUser').click(doIt);
Try creating a contentUpdate function that resets whatever is getting displayed and creates it again based on new variables (this would go at the bottom of a function to add the user, for example). The reason that variable changes aren't reflected in the DOM is that the DOM has no abstraction for how it was made; it's output, and it won't change itself based on what its input has done after it was put in.
If you just want to insert a new row into a table you don't need to refresh the page.
jsfiddle
html:
<table id="usertable">
<tr><td>user 1</td></tr>
</table>
<input id="newuser"></input>
<input id="adduser" type="submit"></input>
js:
var button = document.getElementById('adduser');
button.onclick = function(event) {
var user = document.getElementById('newuser').value
//add the user to your array here
//add a table row
var table = document.getElementById('usertable');
var row = table.insertRow(0);
var cell1 = row.insertCell(0);
cell1.innerHTML = user;
event.preventDefault();
}

A good JavaScript to add/remove items from/to array?

folks! Today I created this script that has the following functionality:
add new items to array
list all items from the array
remove an item from the array
There are two functions:
addToFood() - adds the value of input to the array and updates
innerHTML of div
removeRecord(i) - remove a record from the array and updates
innerHTML of div
The code includes 3 for loops and you can see it at - http://jsfiddle.net/menian/3b4qp/1/
My Master told me that those 3 for loops make the solution way to heavy. Is there a better way to do the same thing? Is it better to decrease the loops and try to use splice? Thanks in advance.
HTML
<!-- we add to our foodList from the value of the following input -->
<input type="text" value="food" id="addFood" />
<!-- we call addToFood(); through the following button -->
<input type="submit" value="Add more to food" onClick="addToFood();">
<!-- The list of food is displayed in the following div -->
<div id="foods"></div>
JavaScript
var foodList = [];
function addToFood () {
var addFood = document.getElementById('addFood').value;
foodList.push(addFood);
for (i = 0; i < foodList.length; i++) {
var newFood = "<a href='#' onClick='removeRecord(" + i + ");'>X</a> " + foodList[i] + " <br>";
};
document.getElementById('foods').innerHTML += newFood;
}
function removeRecord (i) {
// define variable j with equal to the number we got from removeRecord
var j = i;
// define and create a new temporary array
var tempList = [];
// empty newFood
// at the end of the function we "refill" it with the new content
var newFood = "";
for (var i = 0; i < foodList.length; i++) {
if(i != j) {
// we add all records except the one == to j to the new array
// the record eual to j is the one we've clicked on X to remove
tempList.push(foodList[i]);
}
};
// make redefine foodList by making it equal to the tempList array
// it should be smaller with one record
foodList = tempList;
// re-display the records from foodList the same way we did it in addToFood()
for (var i = 0; i < foodList.length; i++) {
newFood += "<a href='#' onClick='removeRecord(" + i + ");'>X</a> " + foodList[i] + " <br>";
};
document.getElementById('foods').innerHTML = newFood;
}
You should use array.splice(position,nbItems)
function removeRecord (i) {
foodList.splice(i, 1); // remove element at position i
var newFood = "";
for (var i = 0; i < foodList.length; i++) {
newFood += "<a href='#' onClick='removeRecord(" + i + ");'>X</a> "
+ foodList[i] + " <br>";
};
document.getElementById('foods').innerHTML = newFood;
}
http://jsfiddle.net/3b4qp/5/
Now using JQuery:
$(function(){
$(document).on('click','input[type=submit]',function(){
$('#foods')
.append('<div>X '
+ $('#addFood').val() + '</div>');
});
$(document).on('click','.item',function(){
$(this).parent().remove();
});
});
http://jsfiddle.net/jfWa3/
Your problem isn't the arrays, your problem is this code:
node.innerHTML += newFood;
This code is very, very, very slow. It will traverse all exising DOM nodes, create strings from them, join those strings into one long string, append a new string, parse the result to a new tree of DOM nodes.
I suggest to use a framework like jQuery which has methods to append HTML fragments to existing DOM nodes:
var parent = $('#foods');
...
for (var i = 0; i < foodList.length; i++) {
parent.append( "<a href='#' onClick='removeReco..." );
That will parse the HTML fragments only once.
If you really must do it manually, then collect all the HTML in a local string variable (as suggested by JohnJohnGa in his answer) and then assign innerHTML once.
Here's some tips to, at least, make your code more portable (dunno if it will be better performance wise, but should be, since DOM Manipulation is less expensive)
Tips
First separate your event handle from the HTML
Pass the "new food" as a function paramater
Tie the array elements to the DOM using the ID
Instead of rerendering everything when something changes (using innerHTML in the list), just change the relevant bit
Benefits:
You actually only loop once (when removing elements from the array).
You don't re-render the list everytime something changes, just the element clicked
Added bonus: It's more portable.
Should be faster
Example code:
FIDDLE
HTML
<div id="eventBinder">
<!-- we add to our foodList from the value of the following input -->
<input id="addFood" type="text" value="food" />
<!-- we call addToFood(); through the following button -->
<button id="addFoodBtn" value="Add more to food">Add Food</button>
<!-- The list of food is displayed in the following div
-->
<div id="foods"></div>
</div>
JS
// FoodList Class
var FoodList = function (selectorID) {
return {
foodArray: [],
listEl: document.getElementById(selectorID),
idCnt: 0,
add: function (newFood) {
var id = 'myfood-' + this.idCnt;
this.foodArray.push({
id: id,
food: newFood
});
var foodDom = document.createElement('div'),
foodText = document.createTextNode(newFood);
foodDom.setAttribute('id', id);
foodDom.setAttribute('class', 'aFood');
foodDom.appendChild(foodText);
this.listEl.appendChild(foodDom);
++this.idCnt;
},
remove: function (foodID) {
for (var f in this.foodArray) {
if (this.foodArray[f].id === foodID) {
delete this.foodArray[f];
var delFood = document.getElementById(foodID);
this.listEl.removeChild(delFood);
}
}
}
};
};
//Actual app
window.myFoodList = new FoodList('foods');
document.getElementById('eventBinder').addEventListener('click', function (e) {
if (e.target.id === 'addFoodBtn') {
var food = document.getElementById('addFood').value;
window.myFoodList.add(food);
} else if (e.target.className === 'aFood') {
window.myFoodList.remove(e.target.id);
}
}, false);
Here is another sugestion:
function remove(arr, index) {
if (index >= arr.lenght) { return undefined; }
if (index == 0) {
arr.shift();
return arr;
}
if (index == arr.length - 1) {
arr.pop();
return arr;
}
var newarray = arr.splice(0, index);
return newarray.concat(arr.splice(1,arr.length))
}

Categories

Resources