<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<div id="mvc">
<h1>0</h1>
<button>+</button>
<button>-</button>
</div>
<div id="mvp">
<h1>0</h1>
<button>+</button>
<button>-</button>
</div>
<div id="mvvm">
<h1>0</h1>
<button>+</button>
<button>-</button>
</div>
<div id="flux">
<h1>0</h1>
<button>+</button>
<button>-</button>
</div>
</body>
</html>
//MVC
(function mvc() {
const root = document.getElementById('mvc'),
view = root.children[0],
btnAdd = root.children[1],
btnDec = root.children[2];
const model = () => {
let value = 0;
return {
add: () => {
value++;
view.innerText = value;
},
dec: () => {
value--;
view.innerText = value;
}
}
};
(function controller() {
const m = model();
root.addEventListener('click', (event) => {
//View -> Controller
if(event.target === btnAdd) {
//Controller -> Model
m.add();
} else if(event.target === btnDec) {
//Controller -> Model
m.dec();
}
})
}());
})();
//MVP
(function mvp() {
const root = document.getElementById('mvp'),
view = root.children[0],
btnAdd = root.children[1],
btnDec = root.children[2];
//Model
class Model {
constructor(value) {
this._value = value;
this.listeners = [];
}
addListener(listener) {
this.listeners.push(listener);
}
notifyListener() {
for (let listener of this.listeners) {
//Model --> Presenter
listener(this._value);
}
}
addOne() {
this._value++;
this.notifyListener();
}
decOne() {
this._value--;
this.notifyListener();
}
};
//Presenter
const presenter = () => {
const model = new Model(0);
//Presenter -> View
model.addListener((value) => view.innerText = value);
return (todo) => {
switch(todo) {
case 'add': {
//Presenter -> Model
model.addOne();
break;
};
case 'dec': {
//Presenter -> Model
model.decOne();
break;
};
}
};
};
//View
const pst = presenter();
root.addEventListener('click', (event) => {
if(event.target === btnAdd) {
//view -> presenter
pst('add')
} else if(event.target === btnDec) {
//view -> presenter
pst('dec')
}
});
}());
//MVVM
(function mvvm() {
const root = document.getElementById('mvvm'),
view = root.children[0],
btnAdd = root.children[1],
btnDec = root.children[2];
const observe = (view, model, prop) => {
let old = model[prop];
Object.defineProperty(model, prop, {
get: () => old,
set: (now) => {
if(now !== old) {
//ViewModel -> View
view.innerText = now;
//ViewModel <-> Model
old = now;
}
}
});
};
const model = {counter: 0};
const viewModel = (function() {
observe(view, model, 'counter');
return {
add: () => {
model.counter++;
},
dec: () => {
model.counter--;
}
}
})();
root.addEventListener('click', (event) => {
if(event.target === btnAdd) {
//View -> ViewModel
viewModel.add();
} else if(event.target === btnDec) {
//View -> ViewModel
viewModel.dec();
}
});
})();
//Flux
(function flux() {
const root = document.getElementById('flux'),
view = root.children[0],
btnAdd = root.children[1],
btnDec = root.children[2];
//Store -> View
const render = (view, state) => {
view.innerText = state;
};
//Dispatcher -> Store
const createStore = (view, reducer) => {
let state = reducer();
return (action) => {
const nowState = reducer(state, action);
if(nowState !== state) {
state = nowState;
render(view, state);
}
}
}
const reducer = (state = 0, action) => {
switch(action) {
case 'ADD': {
return state+1;
};
case 'DEC': {
return state-1;
};
default: {
return state;
}
}
}
const store = createStore(view, reducer);
root.addEventListener('click', (event) => {
if(event.target === btnAdd) {
//Action -> Dispatcher
store('ADD');
} else if(event.target === btnDec) {
//Action -> Dispatcher
store('DEC');
}
});
})();
Output
You can jump to the latest bin by adding /latest
to your URL
Keyboard Shortcuts
Shortcut | Action |
---|---|
ctrl + [num] | Toggle nth panel |
ctrl + 0 | Close focused panel |
ctrl + enter | Re-render output. If console visible: run JS in console |
Ctrl + l | Clear the console |
ctrl + / | Toggle comment on selected lines |
ctrl + ] | Indents selected lines |
ctrl + [ | Unindents selected lines |
tab | Code complete & Emmet expand |
ctrl + shift + L | Beautify code in active panel |
ctrl + s | Save & lock current Bin from further changes |
ctrl + shift + s | Open the share options |
ctrl + y | Archive Bin |
Complete list of JS Bin shortcuts |
JS Bin URLs
URL | Action |
---|---|
/ | Show the full rendered output. This content will update in real time as it's updated from the /edit url. |
/edit | Edit the current bin |
/watch | Follow a Code Casting session |
/embed | Create an embeddable version of the bin |
/latest | Load the very latest bin (/latest goes in place of the revision) |
/[username]/last | View the last edited bin for this user |
/[username]/last/edit | Edit the last edited bin for this user |
/[username]/last/watch | Follow the Code Casting session for the latest bin for this user |
/quiet | Remove analytics and edit button from rendered output |
.js | Load only the JavaScript for a bin |
.css | Load only the CSS for a bin |
Except for username prefixed urls, the url may start with http://jsbin.com/abc and the url fragments can be added to the url to view it differently. |