r/learnjavascript • • Mar 26 '21

“10 Algorithms To Solve Before your Coding Interview” - great little repo, I’d say it’s a mix of leetcode easy with a few leetcode medium problems mixed in.

Thumbnail
github.com
331 Upvotes

r/learnjavascript • • Oct 26 '19

This is a future computer programmer! Clearly a debugging savant. An ability to stay on point and savor the fruits of her labor.

331 Upvotes

r/learnjavascript • • May 31 '22

Switch statement explained for beginners

Post image
330 Upvotes

r/learnjavascript • • Jul 24 '21

Anatomy of a Function

Post image
327 Upvotes

r/learnjavascript • • Sep 29 '20

Anyone fed up with Medium blog posts with promising titles that deliver very little?

327 Upvotes

I actively avoid Medium now when I’m googling javascript concepts. I am not saying I’ve never learned from a Medium article, but I am saying that I usually find those posts to be low effort. When I can’t understand official documentation, I might explore the google hits and then stumble upon a Medium article hoping it’ll help put something in plain English for me, and end up reading a lot of fluff in the beginning and then before I know it, I’m at the end of the article, reading some examples which barely demonstrate the concept, and that’s the end. What is this, a recipe blog? I feel more than anything that some writers on there are just trying to pad their resumes with another extra activity and hope that no employer actually reads it.

Sorry to rant, but I just ran into another bad one and had to see if anyone else is experiencing this or if it’s just me.


r/learnjavascript • • Jan 16 '23

Project I’m really proud of. Sure it’s not the hardest thing to do out there but I learned alot and I’m proud with the results.

326 Upvotes

r/learnjavascript • • Dec 16 '21

I Wrote a Script to Download Every NFT

325 Upvotes

By now, you might have learned how to right click and save or screenshot NFTs. But compared to what I'll show you in this post, that'll just look like petty theft. I'm going to show you how to create a script to download tens of thousands of NFTs in just minutes.

Memes aside, I thought this was a fun project to get more familiar with Node.js and Puppeteer, a library you can use for web scraping and more. If that sounds interesting, read on. And if you want to follow along better, here's the GitHub with the code.

(If you'd like to watch this post in video format, click here.)

Casing the Joint

We're going to be lifting the NFTs from Rarible, one of the most popular NFT marketplaces.

Here you can buy JPEG images of monkies, anime girls, cats, and more. But what we're after are the monkies. Some of the most sought-after NFTs. But I don't want to just save one or two of them--I want ALL of them. To be more precise, all 9,800 of them in this collection.

Installing Dependencies

I'm going to be writing this script in Node.js because I never learned a real programming language. And we're going to be using a library called Puppeteer in order to lift the NFTs. What Puppeteer does is basically starts up a remote-controlled version of Chromium that we can program to do our bidding. Let's initialize the project and install Puppeteer.

npm init -y
npm install puppeteer

Writing the Script

Let's create our script. I've created a file called index.js and added the following:

const puppeteer = require("puppeteer");
const fs = require("fs");
const path = require("path");

const url = "https://rarible.com/boredapeyachtclub";

(async () => {
  console.log("Loading...");
  const browser = await puppeteer.launch({ headless: true });
  const page = await browser.newPage();

  await page.goto(url);
  await page.setViewport({
    width: 1200,
    height: 800,
  });
});

Let's explain what's going on here. First, we're importing Puppeteer and a couple of Node.js libraries that will allow us to save files to our local machine.

Next, we're setting the URL of the page that we're going to be lifting the images from. This can be any Rarible collection page.

Finally, we're starting the browser with Puppeteer, navigating to the URL, and setting the viewport dimensions. The await keywords will ensure that the previous command will finish before the next one runs. This is all from the Puppeteer documentation, so it's not rocket science.

If this is all correct, then when we run the script with node index.js, it should open up a Chromium window and navigate to the URL.

Looks good so far. But there's more that needs to be done.

Getting the Name of the Collection

We want to grab the name of the collection that we're downloading and create a folder to deposit all of our loot into.

We can get the name from the page title. However, it doesn't load in the name of the collection until the entire page has been loaded. So, we have to wait until the React app has been completely loaded.

I opened up the devtools and found a class name that we can hook onto. There's a div with the class of ReactVirtualized__Grid that is the grid that holds all the images. Once that's loaded, the name of the collection has already been loaded in the page title. All we need to do is wait for this element to load, then we can proceed.

await page.waitForSelector(".ReactVirtualized__Grid");

const pageTitle = await page.title();
const collection = await pageTitle.split("-").shift().trim();
if (!fs.existsSync(collection)) {
  fs.mkdirSync(collection);
}

We're using the Puppeteer method waitForSelector to hold off until this element is loaded. After that, we grab the page title, do a bit of JavaScript string manipulation to get the right value, and finally create the directory with Node (if it hasn't already been created).

We now have a folder to put all the images in! Let's fill it up.

Downloading the Images

This is the meat of the script. What we want to do is get all the resources that are downloaded to the page. That includes HTML, CSS, JS, and images. We only want the images, but only the NFTs, not any logos, avatars, or other images.

If you look in the network tab of the dev tools, we can see all the images being loaded. We can also see that all of the NFTs are loaded in with a path containing t_preview. None of the other images on this page are from the same path. So, if we sort out these images with these URLs, we can single out the NFTs from all the noise.

let currentImage = 1;

page.on("response", async (response) => {
  const imageUrl = response.url();
  if (response.request().resourceType() === "image") {
    response.buffer().then((file) => {
      if (imageUrl.includes("t_preview")) {
        const fileName = imageUrl.split("/").pop() + ".avif";
        const filePath = path.resolve(__dirname, collection, fileName);
        const writeStream = fs.createWriteStream(filePath);
        writeStream.write(file);
        console.log(`${collection} #${currentImage} saved to ${collection}/${fileName}`);
        currentImage++;
      }
    });
  }
});

There's a lot going on here, but we're getting all the resources, selecting the images, then only getting the ones we want. After that, we use some string manipulation to get the filename and save them as AVIF files (a next-gen image format you can learn more about here). Then we're saving these to the new folder we created with some Node.js methods. Finally, we're just logging to console the image that's just been downloaded and how many images have already been downloaded.

Phew! That works, and we're finally downloading some images. But the images are being lazy-loaded. That means they aren't being loaded until you actually scroll down the page. That's great from a user perspective, as the users are only loading in images they can actually see, but not so much from ours. Let's make an function to scroll down the page for us, and click the "Load more" button that keeps you from seeing all the images.

The Autoscroller

In order to start scrolling, we just want to run some JavaScript on the page to scroll it. We can do that with Puppeteer's evaluate method. This will run some JavaScript on the page, same as if you had written it in the dev tools console.

async function autoScroll(page) {
  await page.evaluate(async () => {
    await new Promise((resolve) => {
      let totalHeight = 0;
      let distance = 500;
      let timer = setInterval(() => {
        let scrollHeight = document.body.scrollHeight;
        window.scrollBy(0, distance);
        totalHeight += distance;

        if (totalHeight >= scrollHeight) {
          clearInterval(timer);
          resolve();
        }
      }, 1000);
    });
  });
}

What this does is jumps down on the page 500 pixels, and sets a timer to do it again every second. We're scrolling by 500px/second. A little slow, but if I make it faster it could scroll too fast and skip saving some images. Not good. Then, with totalHeight, we're saving how much distance we've scrolled already and comparing it to the total height of the page, scrollHeight. Once we're at the bottom, we're going to stop the setInterval and resolve the promise. No more scrolling.

However, once we're at the bottom, we still need to click the "Load more" button.

We need to tell Puppeteer to run some JavaScript on the page to find all the buttons and narrow it down to the button with the text "Load more". There's no unique ID or class on this button, so we have to find it like this. Finally, we click on the button with help from Puppeteer. Finally finally, we resume the autoscroll function now that there are no more buttons to click.

await autoScroll(page);

await page.evaluate(() => {
  const elements = [...document.querySelectorAll("button")];
  const targetElement = elements.find((e) => e.innerText.includes("Load more"));
  targetElement && targetElement.click();
});

await autoScroll(page);

After all that, we can close the browser once we've gotten to the bottom of this page containing 10,000 NFTs.

await browser.close()

Running the Script

That's it! We can now run the script and see if it works.

node index.js

Actually, this will take a while because we have to scroll down and save 10,000 images. Grab a cup of coffee or something and stretch your legs while you're waiting.

...

All right, we're back. Let's take a look at what we have here...

What a haul! We now have millions of dollars worth of NFTs on our computer. Not bad for a day's work. What am I going to do with all of these monkey pictures??

I've put the code on GitHub if you want to pull an NFT heist like me--or just play around with Puppeteer some more. It's pretty fun.

That's all for now. I think I'm just going to be sitting over here counting my fat stacks of NFTs.


r/learnjavascript • • May 13 '21

Exponent Power

Post image
323 Upvotes

r/learnjavascript • • Jan 23 '22

Spent an entire day making this. Plain HTML, CSS, & JS. I present to you an animal party!

322 Upvotes

r/learnjavascript • • May 21 '21

I created a free & interactive 7-hour JS course for beginners

322 Upvotes

Hey all 👋

I just wanted to share that I have just launched a 7-hour long JavaScript course for beginners. It is completely free (not even email needed to take it).

It contains 140+ interactive Scrimba challenges, and teaches you JavaScript (+ DOM) in through building three projects.

You might wonder why I think we need yet another JavaScript course??

Well, let me explain...

The reason I created this course is because I have talked with hundreds of JS beginners over the last few years, and I see a few problems arise again and again:

  • Not being able to transition from watching JS tutorials to building JS projects

  • Falling off the wagon because the learning curve is too steep

  • Losing motivation because of boring (overly theoretical) courses

However, very few online courses take these problems seriously enough. So this course is built with these issues in mind. Thus, it is extremely interactive and project-based, has a very gentle learning curve, and spreads theory evenly out throughout the course instead of up-front.

Here are the concepts I go through:

  • const & let

  • strings

  • numbers

  • booleans

  • objects

  • arrays

  • functions

  • methods

  • for loops

  • logical operators

  • mathematical operators

  • JSON

  • The Math object

  • The DOM

  • getElementById()

  • querySelector()

  • addEventListener()

  • innerText

  • textContent

  • innerHTML

  • conditional statements

  • truthy vs falsy values

  • template strings

  • localStorage

  • debugging with Google

If this sounds interesting to you, you can check it out here: https://scrimba.com/learn/learnjavascript

Would be happy to answer any questions you might have :)


r/learnjavascript • • Apr 02 '21

Particle text effect with randomly generated images from a sprite sheet (+ source code)

321 Upvotes

r/learnjavascript • • Sep 24 '22

Very simple Mandelbrot in vanilla JS

Post image
320 Upvotes

r/learnjavascript • • Nov 24 '21

Coding a Fully 3D Tic-Tac-Toe Cube with Three JS

319 Upvotes

r/learnjavascript • • Feb 26 '21

Built an app to solve the media bias in our country towards politicians. you can view every side of the story just by sliding a toggle!

318 Upvotes

r/learnjavascript • • Sep 18 '20

You've Come a Long Way, Baby

Post image
316 Upvotes

r/learnjavascript • • Nov 13 '21

HTML and CSS Handwritten Cheat Sheets

Thumbnail
gallery
315 Upvotes

r/learnjavascript • • Dec 17 '21

Coding Naruto's Rasengan with Three.js

314 Upvotes

r/learnjavascript • • Aug 08 '26

10 JavaScript questions that came up in almost every frontend interview I sat this year

312 Upvotes

I've been interviewing for frontend roles (SDE-2, around 4.5 years experience, React and Next.js) over the last few months and sat through a fair number of loops at product companies and mid-size startups. I kept a running doc of everything that got asked so I could spot patterns. Ten questions came up often enough that I'd now treat them as near guaranteed.

Sharing in case it saves someone else the trial and error.

  1. Implement debounce from scratch, then explain when you'd use debounce vs throttle. This one showed up in almost every single loop, usually as the warm up before harder coding.

  2. Closures. Not just the definition, but where you use them in React and the classic closure-inside-a-loop output question with var vs let.

  3. Hoisting, and how it differs from closures. Usually followed by var vs let vs const and when you actually hit a ReferenceError.

  4. The event loop. Call stack, microtask queue, macrotask queue, followed by predicting output from a snippet mixing setTimeout and Promise.then.

  5. The this keyword. Normal vs arrow functions, and what happens when you detach a method from its object. const a = obj.getName; a()

  6. Prototypal inheritance and the prototype chain, and how it differs from class inheritance.

  7. Deep copy vs shallow copy. Explain the difference, then implement a deep clone. Interviewers usually push on why JSON.parse(JSON.stringify()) is not good enough.

  8. Flatten a nested array, first without Array.flat() and then with it.

  9. Promise vs async/await. When you prefer each, and how error handling actually differs between them.

  10. Event delegation. Why it exists and how you'd apply it to a list with thousands of rows.

Two things that surprised me. Polyfills for call/apply/bind and the Promise combinators came up far less than the prep content online suggests. And output prediction questions were much more common than I expected, often used as a filter before anyone let me write real code.

Curious whether this matches what others have seen recently, or if it's specific to the kind of companies I was talking to.


r/learnjavascript • • Mar 13 '21

Vanilla JavaScript audio visualizers for beginners (code included)

312 Upvotes

r/learnjavascript • • May 05 '20

Little procedural tree generator I'm working on in javascript

310 Upvotes

r/learnjavascript • • Nov 09 '20

Learn Javascript by building 5 Games - beginner course

Thumbnail
youtube.com
308 Upvotes

r/learnjavascript • • Sep 05 '21

useEffect() React hook Illustrated - part 2

Post image
306 Upvotes

r/learnjavascript • • Jul 19 '22

Can somebody explain to me the point of arrow functions? I seriously have no clue what their purpose is.

Post image
301 Upvotes

r/learnjavascript • • Nov 08 '22

Sorry I am late for halloween but here is a spooky script for your nightmares!

Post image
300 Upvotes