<!--
This demo shows two ways to detect changes to a DOM node `.textContent`, one
using a `MutationObserver` and the other using an ES2015 `Proxy`.
From testing, a `Proxy` appears to be 6-8x faster than using a MO in Chrome 50.
Why is this useful? One could imagine creating a primative data-binding system
around the `Proxy` approach or using it to [polyfill `Object.observer()`](https://gist.github.com/ebidel/1b553d571f924da2da06).
Run it: http://jsbin.com/dukuluwufa/edit?html,output
-->
<p><button onclick="update()">update .textContent</button></p>
<p>[MO]'d node content: <span id="source"></span></p>
<p>[Proxy]'d node content: <span id="source-proxied"></span></p>
<output></output>
<script>
let start, finish, start2, finish2;
// Watch accesses/sets on a DOM element property.
function watchPropsOn(el, prop, callback=null) {
return new Proxy(el, {
set(target, propKey, value, receiver) {
let finish2 = performance.now();
out.innerHTML += `Proxy took: ${finish2 - start2}ms<br>`;
console.log(`Proxy set .${propKey} to ${value}`);
target[propKey] = value;
}
});
}
function observe(target) {
// create an observer instance
let observer = new MutationObserver(mutations => {
let finish = performance.now();
out.innerHTML += `MutationObserver took: ${finish - start}ms<br>`;
mutations.forEach(mutation => {
if (mutation.addedNodes.length) {
console.log(`MutationObserver observed childList as ${target.textContent}`)
}
});
});
observer.observe(target, {childList: true});
}
function update() {
out.innerHTML = '';
start = start2 = performance.now();
proxy.textContent = source.textContent = Math.random();
}
let source = document.querySelector('#source');
let proxiedSource = document.querySelector('#source-proxied');
let out = document.querySelector('output');
observe(source); // setup MO
let proxy = watchPropsOn(proxiedSource, 'textContent'); // setup proxy.
</script>
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. |