I use the library "Sinova / Collisions" on GitHub, with Node.js.
https://github.com/Sinova/Collisions
I need a function, to delete all data at once. There is a function to delete Objects one by one. But, that doesn't always work correctly.
All Collision saved in colArr "Array"
for(let i = 0; i < colArr.length; i++){
system.remove(colArr[i]);
}
Is there a Way to delete everything in the Library, directly? A new Function?
system.removeAll(); //???
I wrote to the Github-Issues a few days ago. But without Success
From reading the code, no such function exists, no.
If you want to start from scratch just create a new Collisions object and work with that.
Of course, unless you scope it carefully, or replace it, the old one will still exist and take up memory.
Making a feature request to the library author is a good idea, but we can't really help you to get any traction on that. You have to be patient and wait for a response from them.
var system = new Collisions();
Should fix the Problem
Related
Like the title said, how do I get all elements from a scroll div? The elements in the scroll list are loaded and destroyed dynamically.
I tried to crawl all course names from this website:
https://public.enroll.wisc.edu/search?term=1204
The code below only works for one time:
let list = document.getElementsByClassName('md-virtual-repeat-scroller')[0]
let childs = document.getElementsByClassName("result__name")
console.log(childs[0].innerText)
However, if I do this, I will get the same result for 10 times:
let list = document.getElementsByClassName('md-virtual-repeat-scroller')[0]
for(let i = 0; i < 10; i++) {
let childs = document.getElementsByClassName("result__name")
for(let j = 0; j < childs.length; j++) {
console.log(childs[j].innerText)
}
// scroll by 1000px every time
list.scrollBy(0, 1000)
}
I don't know what's the problem. Is it because that scrollBy() works asynchronously? But I tried to use async and await. It still doesn't work.
Give more information in less words as a possible. Many problems could be related to browser and its version, for example. How is this script called? Are you giving commands via browser console? Have you done a copy of the site and performed some modification on it? It's hard to understand the problem in a realistic level.
Tip: Avoiding use innerText. It's slower and is supported in many browsers only for compability to scripts written to old versions of IE. (I don't know why so many examples in internet use it as first option). User textContent instead.
It's always good to test the returned value of a function/methods - specially during the development of the program.
Never ask to the StackOverFlow community (and to any other) to write progams for you!
You question "how do I get all elements from a scroll div?" is so "loose". scroll div? The answer to this, independently to the "type of div" (and tag!) would be found below.
Your code seems to be no sense in order to do what you want. Why iterate from 0 to 10?
Look at this snipet. I think it will help you
const list = document.getElementsByClassName('md-virtual-repeat-scroller')[0];// if there is no intention to reassign it. Use [0] if you are sure it's the first element of this collection
let childs = list.getElementsByClassName("result__name"); // get only elements inside the first variable!
Use the iterator of the variable.
for(item of childs)
{
/*code*/
}
I am sure you will achieve your goals!
And never suggest us (Community) to code for you or even to resolve your problem. This sound very agressive! To you too! I'm sure.
I solved my problem by reading this article:https://intoli.com/blog/scrape-infinite-scroll/
The reason why I kept getting the same elements is that scrollBy() works asynchronously, so I have to wait then evaluate the page again. I am using puppeteer by the way.
please read the article, super helpful.
I have an idea for a game where people can type in some simple instructions for their character like player.goLeft() or player.attackInFront() and for that I have people type their code into a text box and then I parse it into eval(). This works well but it also allows people to change their own character object by typing things like player.health = Infinity; or something similar. I have a list of functions I want to allow people to use, but I am unsure how to restrict it to only use them.
I understand that the whole point of not letting people use eval is to avoid accidental cross-site scripting but I am unsure on how else to do this. If you have a suggestion please leave a comment about that.
I asked some people around on what to do and most suggested somehow changing scope(which is something I was not able to figure out) or to add some odd parameter to each function in my code that would be required to be a specific string to execute any function, but that seems hacky and since I am making the game in browser with p5js it would be easy to just inspect element and see what the password is.
basically every character has variable called "instruction" which is just a string of javascript. Then every frame of the game I execute it by doing eval(playerList[i].instruction);
tl;dr, how can I only allow specific function to be executed and not allow any others?
EDIT: I forgot to mention that I also am planning to provide player with information so that people can made code that would adapt to the situation. For example there will be parameter called vision that has vision.front and vision.left etc. These variables would just say if there is an enemy, wall, flower, etc around them in a grid. Some people suggested that I just replace some functions with key words but then it compromises the idea of using if statements and making it act differently.
EDIT 2: Sorry for lack of code in this post, but because of the way I am making it, half of the logic is written on server side and half of it works on client side. It will be a little large and to be completely honest I am not sure how readable my code is, still so far I am getting great help and I am very thankful for it. Thank you to everybody who is answering
Do NOT use eval() to execute arbitrary user input as code! There's no way to allow your code to run a function but prevent eval() from doing the same.
Instead, what you should do is make a map of commands the player can use, mapping them to functions. That way, you run the function based on the map lookup, but if it's not in the map, it can't be run. You can even allow arguments by splitting the string at spaces and spreading the array over the function parameters. Something like this:
const instructions = {
goLeft: player.goLeft.bind(player),
goRight: player.goRight.bind(player),
attackInFront: player.attackInFront.bind(player)
};
function processInstruction(instruction_string) {
const pieces = instruction_string.split(' ');
const command = pieces[0];
const args = pieces.slice(1);
if (instructions[command]) {
instructions[command](...args);
} else {
// Notify the user their command is not recognized.
}
};
With that, the player can enter things like goLeft 5 6 and it will call player.goLeft(5,6), but if they try to enter otherFunction 20 40 it will just say it's unrecognized, since otherFunction isn't in the map.
This issue sounds similar to the SQL Injection problem. I suggest you use a similar solution. Create an abstraction layer between the users input and your execution, similar to using parameters with stored procedures.
Let the users type keywords such as 'ATTACK FRONT', then pass that input to a function which parses the string, looks for keywords, then passes back 'player.attackInFront()' to be evaluated.
With this approach you simplify the syntax for the users, and limit the possible actions to those you allow.
I hope this isn't too vague. Good luck!
From your edit, it sounds like you're looking for an object-oriented approach to players. I'm not sure of your existing implementation needs, but it would look like this.
function Player() {
this.vision = {
left: '',
// and so on
}
}
Player.prototype.updateVisibilities = function() {
// to modify the values of this.visibility for each player
}
Player.prototype.moveLeft = function() {
}
Don't give the user an arbitrary interface (such as an input textfield that uses eval) to modify their attributes. Make a UI layer to control this logic. Things like buttons, inputs which explicitly run functions/methods that operate on the player. It shouldn't be up to the player as to what attributes they should have.
Mongodb is cool enough to create the database/collection on the fly, if we run a code similar to
db.store.save({a: 789});
It automatically creates store collection and add a document to it.
My javascript understanding says it is not possible to call a method on an undefined property of db object. It should have resulted in some kind of error/exception.
I am curious to understand the happenings behind the scene and if there is any helpful link please point me to those. Googling did not help me much.
In JavaScript there is a way to define a function that will be executed when an undefined method is called.
Example:
var o = {
__noSuchMethod__: function(id, args) { console.log(id, '(' + args.join(', ') + ')'); }
};
o.foo(1, 2, 3);
o.bar(4, 5);
o.baz();
// Output
// foo (1, 2, 3)
// bar (4, 5)
// baz ()
Note this is a non-standard feature and today only works in Firefox.
I do not know how MongoDB implemented this feature, but I'm just responding in order to report that can be done this way.
Fot more details see: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/noSuchMethod
As I recall in a NodeJS environment you must do something like this to actually create a record: db.get('collectionName').insert({..something...}); or db.get('collectionName').save({...something...}); but you don't get to use the collection name as a property of db.
The line you're mentioning is only used in MongoDB shell, which is not Javascript.
I guess you're misunderstanding what's MongoDB shell and what's a MongoDB driver.
So long story short MongoDB (driver) is not able to access an undefined property.
EDIT
In response to your comment..
MongoDB JS driver's GitHub page pretty much points out how to insert a field and always uses the syntax I mentioned: https://github.com/mongodb/node-mongodb-native
As for what you're using in the shell it's pretty clear that you can't just use Javascript in a command shell. So I guess I'll point you to a place in which you can see in what language was MongoDB developed: http://www.mongodb.org/ pretty much the first line says it's written in C++.
Hope this helps clarify your question
This answer suggested i should put my data in JS instead of a textarea.
Thinking about it i could have scripts and do something like myarray[i]="data" where i is the index of my for loop. However when i click a div how do i find out what i is? I have used var data = $(this).parent('.parent').find('.valuestr').eq(0).val(); which is extremely simple. Should i use a script or should i continue to do it with a textarea? if i should use a script 1) Whats the easiest way to find i and 2) Is it bad pratice to have dozens or hundreds of <script> in my html? or i can go through the loop twice but i still dont know the easiest way to find i. I would have to store it somewhere or go through multiple tags and count them.
Answering the other part of your question:
2) Is it bad pratice to have dozens or
hundreds of in my html?
It will depend on who you talk to, but in general, yes, I think it is. There's actually a push for html to be completely devoid of Javascript, save loading of .js files. For more info, look into unobtrusive javascript.
http://en.wikipedia.org/wiki/Unobtrusive_JavaScript
jQuery has a data() function just for that.
You store arbitrary data related to some element like this:
$('#my_div').data('foo', 'bar');
$('#my_div').data('hello', 'world');
Then you retrieve it like this:
alert($('#my_div').data('foo')); // alerts "bar".
alert($('#my_div').data('hello')); // alerts "world".
Since each DOM_Element is just an object, you can declare a variable in the object.
for(var i = 0; i < elements.length; i++)
{
elements[i].i = i;
elements[i].onclick = function(){
alert(this.i);
}
}
On one page of my website the user has the ability to choose and remove up to 2000 items through selecting multiple string representations of them in a dropdown list.
On page load, the objects are loaded onto the page from a previous session into 7 different drop-down lists.
In the window.onload event, the function looping through the items in the drop-downs makes an internal collection of the objects by adding them to a global array - This makes the page ridiculously slow to load, so, I'm fairly certain probably doing it wrong!
How else am I supposed to store these variables?
This is their internal representation:
function Permission(PName, DCID, ID) {
this.PName = PName;
this.DCID = DCID;
this.ID = ID;
}
where: PName is string. DCID is int. ID is int.
EDIT:
Thanks for the quick replies! I appreciate the help, I'm not great with JS! Here is more information:
'selectChangeEvent' is added to the Change and Click event of the Drop down list.
function selectChangeEvent(e) {
//...
addListItem(id);
//...
}
'addListItem(id)' sets up the visual representation of the objects and then calls :
function addListObject(x, idOfCaller) {
var arIDOfCaller = idOfCaller.toString().split('-');
if (arIDOfCaller[0] == "selLocs") {
var loc = new AccessLocation(x, arIDOfCaller[1]);
arrayLocations[GlobalIndexLocations] = loc;
GlobalIndexLocations++;
totalLocations++;
}
else {
var perm = new Permission(x, arIDOfCaller[1], arIDOfCaller[2]);
arrayPermissions[GlobalIndexPermissions] = perm;
GlobalIndexPermissions++;
totalPermissions++;
}
}
Still not enough to go on, but there are some small improvements I can see.
Instead of this pattern:
var loc = new AccessLocation(x, arIDOfCaller[1]);
arrayLocations[GlobalIndexLocations] = loc;
GlobalIndexLocations++;
totalLocations++;
which seems to involve redundant counters and has surplus assignment operations, try:
arrayLocations[arrayLocations.length] = new AccessLocation(x, arIDOfCaller[1]);
and just use arrayLocations.length where you would refer to GlobalIndexLocations or totalLocations (which fromt he code above would seem to always be the same value).
That should gain you a little boost, but this is not your main problem. I suggest you add some debugging Date objects to work out where the bottleneck is.
You may want to consider a design change to support the load. Some sort of paged result set or similar, to cut down on the number of concurrent records being modified.
As much as we desperately want them to be, browsers aren't quite there yet in terms of script execution speed that allow us to do certain types of heavy lifting on the client.
While I haven't tested this idea, I figured I'd throw it out there - might it be faster to return a JSON string from the server side, where your array is fully calculated on that side?
From that point, I'd wager that eval()'ing it (as evil as this may be) might be fast enough to where you could then write the contents onto the page, and your array setup would already be taken care of.
Then again, I suppose the amount of work it'd take the browser to construct the 2k new objects and inject them into the DOM wouldn't necessarily help the speed side of things in the end. At the end of the day, a design change is probably necessary, but sometimes we're stuck with what we've got, eh?