├── .gitignore ├── README.md ├── close-tab ├── index.html └── script.js ├── device-info ├── index.html ├── script.js └── style.css └── fake-copy ├── index.html └── script.js /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | # weird-js 7 | #### Demonstrating some weird features of JavaScript 8 | 9 | ## [Magically Closing a Tab](https://chiroyce1.github.io/weird-js/close-tab/) 10 | This demonstrates how a tab opened by a regular HTML link can be closed automatically. The link will be clicked, and then the click can be prevented by using a simple function called `preventDefault()` 11 | ```js 12 | linkElement.addEventListener("click", (e) => { 13 | e.preventDefault(); // Prevent the link from being clicked 14 | }) 15 | ``` 16 | and then, opening a new tab (using `window.open`) and closing it after a while. Users might think this is a link that takes them to the new page but it actually is a new `window` object made by JavaScript, when we got input from the user, we cancelled it and used it for another purpose. 17 | 18 | ```js 19 | linkElement.addEventListener("click", (e) => { 20 | e.preventDefault(); // Prevent the user from clicking the link 21 | tab = window.open("https://wikipedia.org"); // Open a new tab 22 | setTimeout(() => tab.close(), 2000); // Close the newly opened tab after 2 seconds 23 | }) 24 | ``` 25 | Kinda scary but fun at the same time. 26 | 27 | --- 28 | 29 | ## [Faking copying some text](https://chiroyce1.github.io/weird-js/fake-copy/) 30 | This demonstrates how whatever you copy from a website can be modified, when you copy text, `preventDefault()` is called to prevent copying it, and `clipboardData.setData()` is used to modify the contents of the clipboard. 31 | 32 | ```js 33 | element.addEventListener("copy", (e) => { 34 | e.clipboardData.setData("text/plain", "Foo Bar"); // Use the event to copy something into the users clipboard 35 | e.preventDefault(); // Cancel the actual event. 36 | }) 37 | ``` 38 | This is why you should always be careful when you copy text from a website and paste it somewhere else. 39 | 40 | --- 41 | 42 | ## [Getting device info](https://chiroyce1.github.io/weird-js/device-info/) 43 | JavaScript has access to lots of information regarding your browser and computer, this info is not very sensitive but can be easily used to uniquely identify a user. The `navigator` object contains a lot of info about the user's browser and computer without requiring the user's permission, [here's](https://chiroyce1.github.io/weird-js/device-info/) an example. The most commonly used is `navigator.userAgent`, which returns the userAgent string of a user, which contains the name and version of the user's Operating System and browser. 44 | 45 | --- 46 | -------------------------------------------------------------------------------- /close-tab/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Magically Close Tabs 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /close-tab/script.js: -------------------------------------------------------------------------------- 1 | linkElement = document.createElement("a"); 2 | linkElement.innerText = "Click me, I will open in another tab, wait 2 seconds and see the magic." 3 | linkElement.setAttribute("href", "https://wikipedia.org") 4 | document.body.appendChild(linkElement) 5 | 6 | linkElement.addEventListener("click", (e) => { 7 | e.preventDefault(); 8 | tab = window.open("https://wikipedia.org") 9 | setTimeout(() => tab.close(), 2000); 10 | document.write(`Boom! I just closed the tab
More info here`) 11 | }) -------------------------------------------------------------------------------- /device-info/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Device Info 8 | 9 | 10 |

Your device's info

11 |

All gathered through vanilla JavaScript

12 | 13 | 14 | -------------------------------------------------------------------------------- /device-info/script.js: -------------------------------------------------------------------------------- 1 | const table = document.createElement("table"); 2 | 3 | document.body.appendChild(table); 4 | 5 | const addRow = (key, value) => { 6 | const row = document.createElement("tr"); 7 | const keyCell = document.createElement("td"); 8 | const valueCell = document.createElement("td"); 9 | keyCell.innerText = key; 10 | valueCell.innerText = value; 11 | keyCell.classList.add("key"); 12 | valueCell.id = value; 13 | row.appendChild(keyCell); 14 | row.appendChild(valueCell); 15 | table.appendChild(row); 16 | }; 17 | 18 | let canvas = document.createElement("canvas"); 19 | let webgl = 20 | canvas.getContext("webgl") || canvas.getContext("experimental-webgl"); 21 | let debugInfo = 22 | webgl.getExtension("RENDERER") || 23 | webgl.getExtension("webgl_debug_renderer_info"); 24 | 25 | addRow("GPU", webgl.getParameter(debugInfo.UNMASKED_RENDERER_WEBGL)); 26 | 27 | for (const property in navigator) { 28 | if ( 29 | navigator[property].toString().includes("[native code]") || 30 | navigator[property].toString().includes("[object") 31 | ) { 32 | continue; 33 | } 34 | 35 | let key = property; 36 | let value = navigator[property]; 37 | 38 | switch (key) { 39 | case "hardwareConcurrency": 40 | value += " (number of physical CPU cores)"; 41 | break; 42 | case "maxTouchPoints": 43 | value += " (number of touch points on your device's screen)"; 44 | break; 45 | } 46 | 47 | addRow(key, value); 48 | } 49 | 50 | addRow("Browser window size", `${window.innerWidth}x${window.innerHeight}`); 51 | addRow("Computer Screen size", `${screen.width}x${screen.height}`); 52 | addRow("Timezone", Intl.DateTimeFormat().resolvedOptions().timeZone); 53 | -------------------------------------------------------------------------------- /device-info/style.css: -------------------------------------------------------------------------------- 1 | table { 2 | border-collapse: collapse; 3 | width: 90%; 4 | margin: 2em auto; 5 | font-size: 1.5em; 6 | } 7 | 8 | @media screen and (max-width: 700px) { 9 | table { 10 | width: 90%; 11 | font-size: 1em; 12 | } 13 | } 14 | 15 | table, 16 | td, 17 | th { 18 | border: 1px solid black; 19 | } 20 | 21 | td { 22 | padding: 10px 10px; 23 | font-family: monospace; 24 | } 25 | 26 | h1, 27 | h3 { 28 | text-align: center; 29 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif; 30 | } 31 | 32 | .key { 33 | font-weight: bold; 34 | max-width: fit-content; 35 | } 36 | 37 | @media screen and (min-width: 700px) { 38 | .key { 39 | min-width: 300px; 40 | } 41 | } -------------------------------------------------------------------------------- /fake-copy/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Fake-Copy 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /fake-copy/script.js: -------------------------------------------------------------------------------- 1 | copy = document.createElement("p") 2 | copy.innerText = "Copy me!" 3 | document.body.appendChild(copy) 4 | 5 | input = document.createElement("input") 6 | input.placeholder = "Paste it here and see!" 7 | document.body.appendChild(input) 8 | 9 | document.body.appendChild(document.createElement("br")) 10 | document.body.appendChild(document.createElement("br")) 11 | 12 | info = document.createElement("a") 13 | info.href = "https://developer.mozilla.org/en-US/docs/Web/API/ClipboardEvent/clipboardData" 14 | info.innerText = "More info here." 15 | document.body.appendChild(info) 16 | 17 | copy.addEventListener("copy", (e) => { 18 | e.clipboardData.setData("text/plain", "You didn't copy this right? 😱"); 19 | e.preventDefault(); 20 | }); 21 | --------------------------------------------------------------------------------