00:00
00:00
B1KMusic
Hi. I make games and software. I'm not on NG much, but feel free to peruse my youtube and gitlab for interesting stuff.

Braden @B1KMusic

Age 29, Male

Programmer/Musician/

fish

Earth, Milky Way

Joined on 6/19/11

Level:
10
Exp Points:
948 / 1,110
Exp Rank:
69,513
Vote Power:
5.20 votes
Rank:
Police Sergeant
Global Rank:
8,626
Blams:
42
Saves:
1,040
B/P Bonus:
12%
Whistle:
Normal
Medals:
799

Some Web Development Tricks

Posted by B1KMusic - October 6th, 2012


These are for the client. Meaning these involve any combination of HTML, Javascript and CSS

1) Multiple Keystroke detection.

Sounds complex, right? Actually no. It's easy. You just have to find out how to save the state of previous keys.

map={}
onkeydown=onkeyup=function(e){
map[e.keyCode]=e.type=='keydown'?true:false
if(map[17]&&map[16]&&map[13]){//CTRL+SHIFT+ENTER
alert(1)
}
}

You can also use names:

keys={
CTRL:17,
SHIFT:16,
ENTER:13
}

and then you can check for CTRL+SHIFT+ENTER like so:

if(map[keys['CTRL']]&&map[keys['SHIFT']]&&map[ke ys['ENTER']]){}

Q "But wait! Now every time I hit enter after the initial combo, the alert box keeps popping up!"
A This is because the alert box takes the focus from the window and fails to update since no keyup even tis received.

Q "When I try to use CTRL+D the stupid bookmarks dialog opens up"
A I also have a fix for that.

A fix for these is this:

if(map[17]&&map[16]&&map[13]){//CTRL+SHIFT+ENTER
alert(1)
map={}
return false
}

Q "what?"
A the "map={}" line clears the map object, and the "return false" line...well I should explain that a little.

a return statement in a function immediately exits a function to return information. So as a very convenient side effect, it will also suppress events. So if you put "return false" at the end of an oncontextmenu event, it suppresses the right-click context menu. If you put "return false" in an onclick event, it makes everything un-clickable. Yeah, links won't click, you can click them all you want and the link will not do anything. Put it in an onkeypress event and you can't type. So if you put return false in the end of an if statement for a combination CTRL+D (I recommend doing it for all key combos), the Bookmarks dialogue will be suppressed. The return statement can also be used for "are you sure?" dialogues.

DELETEEVERYTHING=function(){
if(!confirm('Are You Sure?')){//clicked Cancel
return false
}
//delete everything
}

So if the user clicks OK, the function will proceed, if the user clicks Cancel, it will quit without doing that

You can make a very simple keylogger to help find the id's of keys by using something like:

in HTML:
<div id=output></div>

in Javascript:
onkeydown=function(e){
output.innerText=e.keyCode
}

This way you don't have to look online for a key chart, just Press A and see 65 appear on screen.

A More advanced implementation that shows multiple keys could be written as:

HTML:
<div id=output></div>

Javascript:
map={}
onkeydown=onkeyup=function(e){
map[e.keyCode]=e.type=='keydown'?true:false
output.innerHTML=''
for(i in map){
if(map[i]){//only writes if key is "down"
output.innerHTML+=i+'<hr>'
}
}
}

This will tell you multiple keys

Note about IE: You know how almost every browser will accept a variable in an event? Internet Explorer don't play dat. To reference the event object universally, you might as well just use window.event, or event (since the reference pointer in javascript is AT the window level already), so e.keyCode becomes event.keyCode
__________________________________________
2)Saving and loading

This is pretty simple.

localStorage['key']='value'

this actually saves a key called "key" with the value of "value"

it can be loaded later on with something like:

key=localStorage['key']

key will reutrn 'value'

Of course, there is a little drawback to localStorage. Everything is saved as a string, even numbers, objects, and arrays. This is where the little known JSON object shines.

JSON, not an API. It's actually a built in object containing two functions, stringify, and parse. They do the opposite of each other

JSON.stringify({key:'value',key2:{key:'value2'}}
) will return '{"key":"value","key2":{"key":"value2"}}'
JSON.parse('{"key":"value","key2":{"key":"value2 "}}') will return the object in full glory

so if you use asdf=JSON.parse('{"key":"value","key2":{"key":"v alue2"}}'), then you can check asdf.key2.key, which will return "value2"

So this can be saved and loaded from localStorage as an object!

assuming and object named data is defined

localStorage['object']=JSON.stringify(data)

later on:

data={}

if(localStorage['object']){
data=JSON.parse(localStorage['object'])
}

Note: There is one thing to consider: do not "multi-layer" the JSON.stringify function. This has resulted in tons of errors for me, and it is not worth the hassle
________________________________
3) Random Strings

Quickly, a string is a variable of the data type Text. so "hello world" is a string. This term is universal in all programming (except joke languages like LolCode and brainfuck, but I digress).

So what am I talking about here? Go to YouTube. Click on any video. Look at the url. That video id is randomly generated at the time of the video's creation.

This can be useful for many things, including a login system, which I will get into later.

This is a function I wrote that quickly and efficiently generates a random string up to 10,000 digits without lag:

gen=function(l,chars){// l = length of string, chars = optional charset
str=''
R=function(){return Math.floor(Math.random()*10).toString()}
R2=function(){return R()+R()}
l=l||10
charset=chars||'1234567890QWERTYUIOPASDFGHJKLZXC VBNMqwertyuiopasdfghjklzxcvbnm_-'
for(i=0;i<l;i++){
char=charset[R2()]||charset[R2()]||charset[R2()]
||charset[R2()]||charset[R2()]||charset[R()]||ch arset[0]
str+=char
}
return str
}

the secret to this is that you can actually treat a string as an array. for example, 'asdf'[2] returns 'd', 'asdf'[0] returns 'a'
Another little trick is that the OR operator can be used to define defaults in functions, so asdf=value||1 will check if the variable value exists, if it doesn't, it defaults to 1. This can be daisychained, like asdf=value1||value2||1

So that almost last line attempts to grab a random index of the charset in two digits (like 32, or 97, or 01) five times, before trying one last time with a single digit, and then using the first index as a last resort, in the impossibly rare event that the random number is somehow not valid.

The result of this function is completely random. It defaults to 10 characters.

gen(11) will return what looks like a YouTube Video ID, because it is random, and 11 characters long

four samples from Google Chrome's F12 Console:

gen(11)
>"VzePmOCNExF"
gen(11)
>"pVnvGg--9Dg"
gen(11)
>"USbrKnShPlA"
gen(30)
>"UoZXRUYbWsNHGLj0kt8IOmXjNuyEAd"

Even gen(10000) will quickly return a string of 10,000 characters, with only 0.25 second delay between pressing Enter and showing the string

And back to the login system:

The way this is mostly done is as follows:

An account is created. So the user's account is stored in the database. The user account consists of all the user's account and profile information and also contains the credentials: a User Name, a Password, and a 20-50 digit Encryption Key which is generated at the time of account creation.

This can be simulated with localStorage, just have the "user" "sign up" and store the username, password, and gen(30) in an object, stringify it, and store it in localStorage to be loaded next load.

Anyways. Let's say you create an account. Your username is ASDFHAPPYFACE, and your password is applecrack5, when you hit the sign up button, an object is created, {name:'ASDFHAPPYFACE',pass:'applecrack5',key:gen (30)}

Now when you go to log in, the site fetches the object from the username, if it doesn't find it, the user does not exist. After fetching the user's account credentials, it checks the password entered against the password saved. This way I can't just type in TomFulp and automatically log in as him. Sort of obvious.

If the passwords match, then it saves a cookie to the computer with the encryption key from the database, every time the page loads it checks for this cookie. If it finds the cookie and sees an encryption key, then it will search through the database. If it finds a match, it logs you in automatically, else it does nothing. The user can then log out, which would delete the cookie.

All of this happens in less than a second.

And I did create a simulation login system which can be downloaded here. It is an .html file, and can easily be saved (if the download button doesn't work) by copy/pasting the code to notepad, hitting save, selecting ALL FILES in the dialogue under the filename input, and then you just save it as anything.html

You can sign up with multiple accounts, and each can be logged in and managed (the only thing you can do is log out and delete the "account")

Note about IE: Again Micro$oft shows their incredible stubbornness by disregarding something every other browser does. That is to say: You can't save localStorage in IE's client. The only way you can do that is by running the file on a server. So you can try (and fail) to run it on jsfiddle.net, or you can download XAMPP and figure out how to use it. Running on XAMPP, Internet Explorer does save local and session Storage.

__________________________________
4) Dimming the screen

I actually found this surprisingly simple after some thought. This just entails putting a fullscreen, transparent div element over everything, and making it visible is what dims the screen. Then you can put another box over that overlay to make a sort of message or webform. The div also doubles as obscuring everything else, so they can't be clicked.

HTML:
<div id=dim></div>

Javascript:
DIM=function(){//simple dim
dim.style.display='block'
dim.style.opacity='.9'
}
UNDIM=function(){//clicking "outside the form", or on the div element, would trigger this
dim.style.display='none'
}

OR the fancy version

DIMFANCY=function(){//this animates
dim.style.display='block'
op=0
dim.style.opacity=op
fadein=function(){
op+=.1
dim.style.opacity=op
if(op>=.9){
clearInterval(INT)
}
}
INT=setInterval(fadein,10)
}
UNDIMFANCY=function(){
op=.8
dim.style.opacity=op
fadeout=function(){
op-=.1
dim.style.opacity=op
if(op<=.1){
dim.style.display='none'
clearInterval(INT)
}
}
setInterval(fadeout,10)
}

CSS:
#dim{
position:fixed;
left:0px;
top:0px;
width:100%;
height:100%;
background:#000;
z-index:20;
display:none;
}

________________

If you see this and have a question for doing a certain thing in javascript, ask in the comments section and I will do my best to answer it with as much detail as possible.


Comments

did not read lol

No, seriously, I am really doing my best to learn javascript. It's so difficult. You present it pretty clearly here, so thank you. ^__^

NP :) I've been doing html5, css3 and javascript for over 3 years now, and have pretty much mastered it.