jQuery: How do I check a number from string? - javascript

there is a class named:
<div class="level_11 price_level" style="display: block;">
I have a script that runs a browser function.
But I want to run this only when my number in the script is lower than the number from the "level_" div.
I have no idea how to do this.
Well, there are everytime another number. Sometimes level_4, sometimes level_18, etc.
I need to check the number and say if my number is lower then the number from the level_, then run the script.
let setLevel = 3; // Change this to set the building level. Example: let Level = 20 //
let Level = setLevel -1; // Don't touch this //
let logLevel = Level +1; // Don't touch this //
console.log(`Success ✓ - ${IBuilding.length} buildings left`);
$.each(IBuilding, function(Index, Entity) {
let BuildingMissing = IBuilding.length - (Index + 1);
window.setTimeout(function() {
$.get(`/buildings/${Entity.id}/expand_do/credits?level=${Level}`)
console.log(`${BuildingMissing > 0 ? BuildingMissing : 'Success ✓ - last building successfully expanded to level: ' + logLevel }`);
}, Index * 250);
});
});
Basically the script request all sites, and every site have another "level_".
On the sites where the "level_" number is higher than the number in my variable, then dont run the script at the site. but run the script at the sites where my number is higher then the "level_"
Can anyone help me out? :/

You can get the level number like this:
let classname = $("div[class^='level']").attr("class").split(" ").filter(getClass);
function getClass(value) {
return value.startsWith("level_");
}
let level = classname.toString().substr(6);
console.log(level);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="level_11 price_level" style="display: block;">

I found this on link /buildings/ID/:
current level of building
Maybe I can check the Level from there?
The HTML section for that is:
<dd>
13
Ausbauen
</dd>

Related

Is there any way to optimize my client side search function?

I've created a page that needs to show all records from a table, instead of paginating.
The problem is that my search function actually takes about 10 seconds to run for 1300 records. Is there any way to optimize it?
I'm using bootstrap d-none class to hide elements.
if (document.getElementById("form_search_user")) {
document.getElementById("form_search_user").addEventListener("submit",function (event) {
event.preventDefault();
let start = performance.now();
let search = document.getElementById("search_input").value;
let table_row = document.querySelectorAll(".user_table tbody tr");
table_row.forEach(element => {
element.innerText.toUpperCase().indexOf(search.toUpperCase()) > -1 ?
element.classList.remove("d-none") : element.classList.add("d-none");
});
console.log(((performance.now() - start) / 1000).toFixed(3));
})
}
Do not use .innerText which is known to be slow because it has to take styling into account. You probably want to search in .textContent instead.

Performance with jQuery .nextUntil on large DOM

I'm looking to address a performance issue I'm having with a very large DOM. In essence, this a word-processing style app inside the browser using contenteditable divs.
Suppose I have a structure like this:
<div class="header">...</div>
<div class="actor">...</div>
<div class="director">...</div>
<div class="producer">...</div>
<div class="writer">...</div>
<div class="executive">...</div>
<div class="studio">...</div>
<div class="footer">...</div>
I then have some code which ends up returning (for example):
<div class="writer">...</div>
as a jQuery object. I then need to retrieve all of this object's surrounding divs between header and footer as a selection and then further filter this list using a class e.g. 'actor'.
Currently, I have the following code, which works correctly:
// Find header
var header_object = object.prevUntil(".header").last().prev();
// Select all objects between header and footer, and then filter
var object_list = header_object.nextUntil(".footer", ".actor");
// Iterate through object_list
object_list.each(function()
{
// Run additional code on the objects
});
The only problem is that due to the app being a word processor of sorts, the DOM structure is often very large (e.g. over 5000 elements) and executing this code locks up the browser for an unacceptable amount of time (over 10 - 30 seconds).
As such, I'm looking for a way to customize the code I have to make it more efficient / improve performance.
I should also point out that the HTML structure above is not (header - 5000 elements - footer), rather it is 200 x (header - elements - footer). As such, each traversal operation is only maybe 25 elements from header to footer, but it has to run many times.
Any suggestions? Many thanks!
You could enhance performance by not using jQuery, and creating your own functions that are more specific to your use case.
function getClosest(el, klass, dir) {
while (el && (!el.classList.contains(klass))) {
el = el[dir ? 'previousElementSibling' : 'nextElementSibling'];
}
return el;
}
function getbetween(from, to, filterKlass) {
var list = [];
while(from && to && from !== to) {
if ((from = from.nextElementSibling) !== to) {
filterKlass ? (from.classList.contains(filterKlass) ? list.push(from) : Infinity) : list.push(from);
}
}
return list;
}
var object = $('.writer');
var element = object.get(0);
var header_object = getClosest(element, 'header', true);
var footer_object = getClosest(element, 'footer', false);
var object_list = getbetween(header_object, footer_object, 'actor');
object_list.forEach(function(element) {
console.log(element);
});
FIDDLE
Traversing the next element sibling directly, and checking for classes, should be much faster than using nextUntil

How to create a persistent random countdown?

Basically, I need a counter that will go backwards from 100-1 slowly as users enter our website. We are only giving out "100" free coupon but want to give the appearance that users are quickly grabbing them in order to create urgency and have the prospect give us their email. I am using Unbounce to host our mobile landing page.
I came across a similar post to mine but the code generated numbers randomly in the millions. Here is the link for further help: https://stackoverflow.com/a/17964971
Quick example:
Be the first to know when we launch! We are only giving out 100 coupons and there are only (x) amount left.
Click here to get yours!
Count down at a random rate between 5 seconds and 1 second, save the current to the browser so if the user revisits the page the number doesn't reset
(Demo)
var i = 100;
var counter = document.getElementById('counter');
if(localStorage.counter) {
i = localStorage.counter;
}
function countDown() {
if(i > 0) {
i--;
console.log(i);
counter.innerText = i;
localStorage.counter = i;
var timeout = Math.floor(Math.random() * (5000 - 1000)) + 1000;
setTimeout(function(){
countDown();
}, timeout);
} else {
document.getElementById('counter-wrp').innerText = 'Oh no, you missed out! All of the coupons are gone.'
}
}
countDown();
<span id="counter-wrp">Be the first to know when we launch! We are only giving
out 100 coupons and there are only <span id="counter" style="color: red;"></span> left</span>
I create this jsFiddle for you using your example
My method utilizes localStorage, which is perfect for this type of function. You can read more about local storage here w3schools. You need to this save the count.
You will notice that to initialize the counter you need additional options
var counter = new Counter({
start: 123456789,
up: '#btnUp',
down: '#btnDn',
storageKey: 'count'
});
up: and down: are just jQuery selectors for the buttons I added with id's btnUp and btnDn. storagekey: can be whatever string you'd like to set to retrieve our count out of localstorage.
here are my buttons
<div class="buttons">
<button id="btnUp" type="button">+</button>
<button id="btnDn" type="button">-</button>
</div>
I hope this helps

Scroll to a particular element in a UL list with dynamic ids

I read the question Scroll to a particular element w/ jQuery and in the question, the original HTML code already has ids to the paragraph elements. However, in my case, I generate the element (list element) dynamically and create ID on runtime. How would I scroll to that particular element with or without jQuery?
To give more detail about my problem:
I am creating a phonegap project to get the list of contacts in the iPhone and display a scrolling list (I use the iscroll plugin) in a div. I categorize the first names A-E, F-J, K-O, P-T, U-Z and group them. If the user touches F-J on the side (as you find in iPhone contacts app), the div should scroll to the first contact that belongs to group F-J..
<div id ="tablediv">
<div id="scroller"></div>
</div>
<div id="sorter">
<span id="gr1">A-E</span>
<span id="gr2">F-J</span>
</div>
Javascript:
var g1 = ['a','b','c','d','e']; //contact's first name starting with these chars
var g2 = ['f','g','h','i','j']; //contact's first name starting with these chars
var idg1=null, idg2=null; // first id of the contact which was in g1, g2
//Array is an array of objects
//example: array = [ {'fname':'x','lname':'y','number':'123'},{..},{..}];
function generateTable(array) {
gpDiv = document.getElementById("scroller");
pDiv = document.createElement("ul");
pDiv.id = "thelist";
for(var i=0;i<array.length;i++) {
cDiv = document.createElement("li");
cDiv.id = 'cd'+i; //id created dynamically
cDiv.textContent = array[i].fname+"\u000a"+array[i].lname;
var ch0 = array[i].fname[0].toLowerCase();
if($.inArray(ch0,g1)!=-1 && idg1==null) {
idg1 = cDiv.id;
document.getElementById('gr1').addEventListener('click',function(){goToG1(idg1);},false);
}
if($.inArray(ch0,g2)!=-1 && idg2==null) {
idg2 = cDiv.id;
document.getElementById('gr2').addEventListener('click',function(){goToG2(idg2);},false);
}
pDiv.appendChild(cDiv);
}
gpDiv.appendChild(pDiv);
}
function goToG1(id) {
$('#tablediv').scrollTop($('#'+id).offset().top);
}
function goToG2(id) {
$('#tablediv').scrollTop($('#'+id).offset().top);
}
The above code doesn't work, as I think since the ids are allotted at runtime, I am not able to scroll to that particular element. Please help
Hmmm, All I needed to do was this.
function goToG1(id) {
document.getElementById(id).scrollIntoView();
}
It appears to me that the ids still work even though they are allotted at run time.
You code worked more or less - you were however using code:
$("#tablediv").scrollTop(...)
Instead of
$(document).scrollTop(...)
Other than that it works - see here: http://jsbin.com/umatuj/2/edit

Jquery: Count node separation in xml

I'm loading an xml document using JavaScript (Jquery $.ajax).
I need to be able to count the number of branches (b) separating 2 text nodes (s).
E.g.
<b n="Archaea">
<s>Archaea</s>
<b n="Eubacteria">
<s>Cyanobacteria</s>
<s>Spirochaete</s>
<b n="Seaweeds">
<s>Red rags</s>
<s>Calliblepharis</s>
</b>
</b>
<b n="Land plants">
<s>Liverwort</s>
<s>Moss</s>
<s>Bracken fern</s>
<b n="Seed plants">
<s>Scots pine</s>
<s>Ginko</s>
<s>Welwitschia</s>
</b>
</b>
</b>
So, how many branches is 'Scots pine' away from 'Calliblepharis', for example. In this case, the answer would be 4 (Seed plants > Land plants > Archaea > Eubacteria > Seaweeds).
I also need to calculate the 'closest common ancestor' between 2 elements. For example, between 'Scots pine' and 'Ginko' it would be 'Bracken fern' (because Bracken fern is the closest species to the branch that contains 'Scots pine' and 'Ginko'). I'm really not sure how this would work when the 2 elements are very far from each other in different branches.
Sorry if I'm using the wrong language here. Hope it makes sense.
Sorry about the late reply.
I've set up a a demo at jsbin
Hopefully it's fairly self explanatory but if not ask me.
For the xhr bit you need to have an file.xml in the same directory as the page.
This is the main function that gets the distance between the branches
function elementDistance(elem1, elem2) {
var steps = 0;
//the parent elements are the branches
var first = elem1.parentElement;
var second = elem2.parentElement;
//if the elements are at different depths you need to even them up
//and count each time as a step
if (elem1.depth() > elem2.depth()) {
while (first.depth() > second.depth()) {
first = first.parentElement;
steps++;
}
}
else if (elem1.depth() < elem2.depth()) {
while (first.depth() < second.depth()) {
second = second.parentElement;
steps++;
}
}
while (first !== second) {
steps += 2;
first = first.parentElement;
second = second.parentElement;
}
return steps;
}
p.s. the demo doesn't work in firefox or IE

Categories

Resources