Im using vanilla JS. I was making a poker game and decided to break it into smaller files. But i cant make the classes work. I broke it down into the smallest parts as a test and am still failing.
I tried using the import, require and link methods of sending the data. The main error i get is 'Uncaught ReferenceError: can't access lexical declaration 'Player' before initialization'. Maybe im missing a return function in my class. But i just want to make a player. It prevents the otherwise working startGame() function and html button from working. Maybe i need an extension? i just did npm init. I dont want to use import if possible
// index.html
<div class="container">
<button onclick="startGame()">Name = Tom</button>
<div id="name__container">Name: </div>
<div id="bank__container">bank: </div>
</div>
// Player.js
class Player {
constructor() {
this.name = 'tim';
this.bank = 100;
}}
module.exports = Player;
// main.js
const Player = require('../js/Player');
function startGame() {
console.log('start game');
let player = new Player();
console.log('player', player);
}
im hoping to create a new class of character. I failed
Related
I'm trying to fix the issue on a mobile website where I'm using swiper.js, but it doesn't always load correctly, which I find odd, because I have to refresh the website a couple of times and then it loads and works as expected.
Here is the whole script I'm trying to work with
let $;
const swiperSelector = '#dog-swiper-carousel .swiper-container';
let swiperRef;
let swiperId;
let slide1, slide2, slide3;
let slides;
let carousel;
window.addEventListener('load', function() {
$ = jQuery;
swiperRef = $(swiperSelector).data('swiper');
swiperRef.params.allowTouchMove = false;
swiperRef.params.noSwiping = true;
swiperRef.params.noSwipingClass = 'swiper-slide';
swiperRef.params.grabCursor = false;
swiperRef.params.navigation.nextEl = '.js-next1';
swiperRef.params.navigation.prevEl = '.js-prev1';
swiperId = document.getElementById('swiper-slide-index').children[0].children[0];
slide1 = document.getElementById('js-slide1').children[0].children[0].children[0];
slide2 = document.getElementById('js-slide2').children[0].children[0].children[0];
slide3 = document.getElementById('js-slide3').children[0].children[0].children[0];
slides = document.querySelectorAll('.mobile-card');
//Then here are a bunch of functions that take care of the navigation and perform actions on these variables
swiperRef.update();
});
I've tried to rewrite code to be more focused on vanilla js, since jQuery isn't something I'm very experienced in. I've already changed the event on window/document load from DOMContentLoaded to load, so all css styles, html elements and content can load first, before I start executing my code. However I couldn't find any issues in the code itself. I'm even creating variables and then waiting for the whole page to load before I assign values to them.
However the error I'm getting everytime I'm on the page is
Uncaught TypeError: Cannot read properties of undefined (reading 'params') at HTMLDocument.<anonymous>
And then it points to the line
swiperRef.params.allowTouchMove = false;
The problem is present only on mobile device (iPhone 12 and google chrome browser as well as safari browser). I haven't tired any other mobile devices, because I have none.
I'm trying to bypass a root detection mechanism on an android app using Frida, I've tried so many different scripts (frida code share) and different approaches (like hiding root) with no luck!
So I tried to locate the class and method responsible for checking if the device is rooted or not and changing it's return value.
This is my script :
setTimeout(function() { // avoid java.lang.ClassNotFoundException
Java.perform(function() {
var hook = Java.use("app.name.RootUtils");
console.log("info: hooking target class");
hook.isRooted.overload().implementation = function() {
console.log("info: entered target method");
return Java.use("java.lang.Boolean").$new(false);
}
});
},0);
If I inject this code normally it won't work because it looks like the isRooted method will get called before it
If I use spawn to run the app and change this method return value it fails with error :
frida.core.RPCException: Error: java.lang.ClassNotFoundException: Didn't find class ...
I've also tried spawning the app and then using objection to run "android root disable" but it will return this error :
frida.core.RPCException: TypeError: cannot read property 'getApplicationContext' of null
at getApplicationContext (src/android/lib/libjava.ts:21)
I'm not sure if this is a problem with Frida or my system or ...
I think if I was able to make my main code runs at exactly after the class gets loaded (like using a loop to check or using a hook) the problem would be fixed but I don't know how to write that kind of code in js for frida.
I'm on macOS 11.5.1 using python 3.9 and installed latest version of frida and objection
I've tested on one rooted phone with android 10 and an emulator with android 6
I was able to solve this issue with a simple yet not very technical solution.
I used a setInteval to run my hooking over and over until it gets to work, (as #Robert mentioned, I also needed to wrap hooking inside a try catch to prevent the code from stoping after first try)
This may not work for everyone but since it worked for me I will post the final code, may it helps someone else in the future :)
Java.perform(function() {
var it = setInterval(function(){
try{
var hook = Java.use("app.name.RootUtils");
console.log("info: hooking target class");
hook.isRooted.overload().implementation = function() {
console.log("info: entered target method");
clearInterval(it);
return Java.use("java.lang.Boolean").$new(false);
}
} catch(e) {
console.log("failed!");
}
},200); // runs every 200milisecods
});
PS : you may need to change interval time to match your app needs, it worked for me with 200 miliseconds.
Sometimes app would do encryptions in its class loader, you may need to replace Java.classFactory.loader with the app's customized class loader in order to make Java.use function properly.
Here's how it's done:
Java.perform(function() {
//get real classloader
//from http://www.lixiaopeng.top/article/63.html
var application = Java.use("android.app.Application");
var classloader;
application.attach.overload('android.content.Context')
.implementation = function(context) {
var result = this.attach(context); // run attach as it is
classloader = context.getClassLoader(); // get real classloader
Java.classFactory.loader = classloader;
return result;
}
//interesting classes
const interestingClassPath = "com.myApp.SometingInteresting";
interestingClass = Java.use(interestingClassPath);
//do whatever you like here
})
Class not found
How do you know the class is app.name.RootUtils have you decompiled to app using Jadx or apktool? How about the method where RootUtils.isRooted() is called? Is there any special code that loads the RootUtils class e.g. from a non-standard dex file included in the app? If the class is loaded from a special dex file you could hook this dex loading mechanism and first execute it and then install your hook for RootUtils.isRooted().
Alternatively assuming RootUtils.isRooted() is called only from one other method and does not use special code for loading the RootUtils class you could hook that method and use the this hook to install install your RootUtils.isRooted() hook.
Error handling
The correct way to handle errors in JavaScript is using try catch block, not the setTimeout function:
Java.perform(() => {
try {
var hook = Java.use("app.name.RootUtils");
...
} catch (e) {
console.log("Failed to hook root detection" + e);
}
}
Regarding your problems hooking the class
I'm very new to JS and am running into an issue while trying to separate some JS into modules. I'm thinking that this is a simple fix, but I'm hoping someone here can help steer me in the right direction. My code works fine if I just put it all into one JS file and link it directly with index.html via a tag, so something is breaking specifically from the move over to a module.
Within my HTML, I have several elements that will change visibility depending on the buttons a user clicks while on the site. The JS as it was written in the original script file worked fine before I attempt to place it in a module:
showHideSections = (section) => {
if (section.classList.contains("hidden")){
section.classList.remove("remove-tab");
section.classList.remove("slideout");
... };
So, I added export const to the start of the code to export it to a main.js file:
export const showHideSections = (section) => { ...
And then imported it to main.js:
import { ..., showHideSections, ... } from "./modules/script.js"
window.addEventListener("DOMContentLoaded", () => {
...
showHideSections();
... });
And now I'm ending up with Uncaught TypeError: cannot read property "ClassList" of undefined.
I'm guessing this has to do with the order in which the code is running now that the JS has moved into a module, but after a few attempts with directing the code to execute differently, I'm feeling stuck. I've tried adjusting the addEventListener on main.js to execute on "load" vs on DOM Content loading. I have also tried creating an object for the element within the script.js file as a workaround, but no dice there, either.
Any thoughts?
Well, it seems you are not passing the section argument in the method call:
import { ..., showHideSections, ... } from "./modules/script.js"
window.addEventListener("DOMContentLoaded", () => {
const section = document.querySelector("#someSelectorHere");
showHideSections(section);
});
I'm using Swiper 6.4.10 for a project. It's the first time I use Swiper.
This website has multiple sliders on 1 page. So I decided to create some initializing script. I'm using data-attributes to create the slider settings. Every slider has different setups. One of those settings is to run the slider only on a mobile device and destroy it on desktop or tablet.
I've read a whole lot of posts here and in Google but I just can't get it to work.
It is about this part:
if(container){
var initID = '#' + container;
if(mobile){
if(mobile_breakpoint.matches){
var init = new Swiper(this, settings)
} else if (!mobile_breakpoint.matches){
var init = this.swiper.destroy();
}
}
//var init = new Swiper(initID, settings)
}
When I use this code here above then all carousels are destroyed OR I get an error saying this.swiper.destroy is undefined.
When I run my code like this:
if(container){
var initID = '#' + container;
var init = new Swiper(initID, settings)
}
Then all carousels just work. When I check for data attribute mobile and try to destroy the carousels then all stop working. I clearly miss something out.
Anybody have any idea what I do wrong? Any help greatly appreciated!
"Your mistake" under else if you forgot first to Initialize swiper instance .
This is why when you uncomment this block of code - the page is broken (error: this.swiper.destroy is undefined).
To destroy an instance you first should create this instance (destroy() is a Method of swiper instance).
const swiper = new Swiper('.swiper-container', {});
swiper.destroy();
Otherwise, your code is like writing:
bla_bla.destroy(); /* Uncaught ReferenceError: bla_bla is not defined */
Create an instance (Missing in your code)
Destroy
else if (!mobile_breakpoint.matches){
var init = new Swiper(this, settings) /* missing in your code */
init = this.swiper.destroy();
}
In general - your code is very long ==> next time create a Minimal, Reproducible Example (A lot of code not related to your issue/error).
I was trying to create a simple library and ran into problems. This is my html file:
`
<html>
<script src = 'p5.min.js'></script>
<script src = 'mosaic.js'></script>
<script src = 'sketch.js'></script>
<body>
<script>setMosaic(true)</script>
</body>
</html>
`
mosaic.js is the library I am creating.
The content of mosaic.js is :
`
p5.prototype._isMosaic = false;
p5.prototype.setMosaic = function(status){
this._isMosaic = status;
console.log('set worked');
};
`
If I call setMosaic from inside the as shown in the html file, it gives me a function not defined error. But I can call setMosaic() successfully from inside setup() or draw() of sketch.js. Calling setMosaic from outside the sketch works when I define setMosaic in /src/environment/environment.js and build p5.js again.
Is there a way to call setMosaic from outside the sketch?
EDIT (in response to the comment):
1) I'm trying to build a framework that can scale the sketch into multiple screens. So the person who writes the sketch has to do it the normal way, but my tool will be calling some functions that communicates with a server e.t.c. So I need to call these functions outside the sketch, but they should be bound to the p5 object (namespace) because the functions I write in turn will have to call some functions internal to p5js. This is my project.
2) Value is going to be affected per sketch.
The issue was solved by calling setMosaic as p5.prototype.setMosaic().
It was answered here.