<html>
<head>
<script src="http://code.jquery.com/jquery-1.8.0.min.js"></script>
<meta charset=utf-8 />
<title>JS Bin</title>
</head>
<body>
<div id="tweets">
<div>
</div>
</div>
<nav>
<ul>
<li><a href="#" data-link="http://search.twitter.com/search.json?rpp=4&q=%23rails"><span>Rails</span></a></li>
<li><a href="#" data-link="http://search.twitter.com/search.json?rpp=4&q=%23grails"><span>Grails</span></a></li>
<li><a href="#" data-link="http://search.twitter.com/search.json?rpp=4&q=%23django"><span>Django</span></a></li>
<li><a href="#" data-link="http://search.twitter.com/search.json?rpp=4&q=%23coldfusion"><span>ColdFusion</span></a></li>
<li><a href="#" data-link="http://search.twitter.com/search.json?rpp=4&q"><span>Error</span></a></li>
</ul>
</nav>
</body>
</html>
#tweets{
box-shadow: inset 1px 1px 1px 1px rgba(44, 44, 44, 75);
box-shadow: inset 1px 1px 1px 1px rgba(44, 44, 44, 75);
border-radius: 4px;
border-radius: 4px;
width: 500px;
height: 350px;
overflow: scroll;
padding: 5px 0px 0px 5px;
}
nav{
text-align: center;
}
#tweets div div{
padding-bottom: 5px;
padding-top: 5px;
border-bottom: 1px solid black;
}
nav ul
{
padding: 0;
margin: 0;
list-style: none;
}
nav li
{
float: left;
}
.username{
font-weight: bold;
}
nav a
{
float: left;
color: #eee;
margin: 0 5px;
padding: 3px;
text-decoration: none;
border: 1px solid #831608;
font: bold 14px Arial, Helvetica;
background-color: #831608;
background-image: linear-gradient(#bb413b, #831608);
background-image: gradient(linear, left top, left bottom, from(#bb413b), to(#831608));
background-image: linear-gradient(#bb413b, #831608);
background-image: linear-gradient(#bb413b, #831608);
background-image: linear-gradient(#bb413b, #831608);
background-image: linear-gradient(#bb413b, #831608);
border-radius: 5px;
border-radius: 5px;
border-radius: 5px;
text-shadow: 0 -1px 0 rgba(0,0,0,.8);
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.3), 0 3px 0 rgba(0, 0, 0, 0.7), 0 2px 2px rgba(0, 0, 0, 0.5), 0 1px 0 rgba(255, 255, 255, 0.5) inset;
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.3), 0 3px 0 rgba(0, 0, 0, 0.7), 0 2px 2px rgba(0, 0, 0, 0.5), 0 1px 0 rgba(255, 255, 255, 0.5) inset;
box-shadow: 0 1px 0 rgba(255, 255, 255, 0.3), 0 3px 0 rgba(0, 0, 0, 0.7), 0 2px 2px rgba(0, 0, 0, 0.5), 0 1px 0 rgba(255, 255, 255, 0.5) inset;
}
nav a:hover
{
background-color: #bb413b;
background-image: linear-gradient(#831608, #bb413b);
background-image: gradient(linear, left top, left bottom, from(#831608), to(#bb413b));
background-image: linear-gradient(#831608, #bb413b);
background-image: linear-gradient(#831608, #bb413b);
background-image: linear-gradient(#831608, #bb413b);
background-image: linear-gradient(#831608, #bb413b);
}
nav a:active
{
background: #bb413b;
position: relative;
top: 2px;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.7) inset;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.7) inset;
box-shadow: 0 0 3px rgba(0, 0, 0, 0.7) inset;
}
nav span
{
border: 1px dashed #eba1a3;
display: inline-block;
padding: 4px 15px;
cursor: pointer;
background-color: #bb413b;
background-image: linear-gradient(#d4463c, #aa2618);
background-image: gradient(linear, left top, left bottom, from(#d4463c), to(#aa2618));
background-image: linear-gradient(#d4463c, #aa2618);
background-image: linear-gradient(#d4463c, #aa2618);
background-image: linear-gradient(#d4463c, #aa2618);
background-image: linear-gradient(#d4463c, #aa2618);
}
nav a:hover span
{
background-color: #bb413b;
background-image: linear-gradient(#aa2618, #d4463c);
background-image: gradient(linear, left top, left bottom, from(#aa2618), to(#d4463c));
background-image: linear-gradient(#aa2618, #d4463c);
background-image: linear-gradient(#aa2618, #d4463c);
background-image: linear-gradient(#aa2618, #d4463c);
background-image: linear-gradient(#aa2618, #d4463c);
}
$(function(){
var $tweetDiv = $("#tweets>div");
var tweetClickHandler = function(e){
var $that = $(this);
//while we are cleaning up the div go ahead and get
//the tweets
$.when(
getTweets($that.find('a').data('link'))
//since we care weather the dfd was resolved or rejected we use the .done method
//this only fires when the dfd is resolved
).done(
//each function we call in the when will pass its response
//to the then callback, in order
function(tweets){
//now lets fade the div out and remove everything that was in it
//we could add add tweets in the clean div's fade out callback
//but this is more expressive in my opinion
$.when(
cleanDiv()
)
//then is called weather the dfd is resolved or rejected
.then(
function(){
//again we want to only show the div after the tweets
//have been added
$.when(
addTweets(tweets)
)
.then(
function(){
$tweetDiv.fadeIn('slow');
}
)
}
)
}
)
//this is called when the deferred is rejected, in this
//case when there is an issue getting tweets
.fail(
function(text){
alert("Error getting tweets: " + text || '');
}
);
};
var cleanDiv = function(){
return $.Deferred(function(dfd){
//otherwise fade the dive out before removing the children
$tweetDiv.fadeOut('slow',function(){
$tweetDiv.children().remove();
dfd.resolve();
});
}).promise();
};
var addTweets = function(tweets){
return $.Deferred(function(dfd){
var stop = tweets.length - 1;
$.each(tweets,function(i,tweet){
var $newElem = $('<div><span class="username"></span><span class="tweettext"></span></div>');
$newElem.find("span.username")
.html('<img src="' + tweet.profile_image_url_https + '">')
.end()
.find("span.tweettext")
.html(tweet.text)
.end()
.appendTo($tweetDiv);
if(i === stop){
return dfd.resolve();
}
});
}).promise();
};
var getTweets = function(searchURL){
//since the deferred response relies on the data coming back from
//the server we wrap the ajax call in a deferred. If we only wanted
//to rely on the status of the ajax call we could have returned the
//ajax call itself since it also returns a promise
return $.Deferred(function(dfd){
$.ajax({
url : searchURL,
dataType : 'jsonp',
success : function(data){
//make sure what we got back valid data from twitter
if(typeof data === 'object' && ! ('error' in data)){
dfd.resolve(data.results);
}
else{
//we can pass variables to our callbacks
dfd.reject('bad response from server');
}
},
error : function(){
dfd.reject('ajax error');
}
});
}).promise();
};
$('li').on('click', $.proxy(tweetClickHandler,this));
});
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. |