Framework constructor
First of all, nice effort for the code. But I highly go against it because there's jQuery. And if you don't like jQuery because it's heavy, then I suggest going for Sizzle.

But anyways, back to your code. First I notice this one:

var optionalSelector = "$";


Never use $. It's being abused already by frameworks. Use another namespace to avoid collisions with mainstream libraries, something unique, like MyVeryAmazingDomLibrary or MVADL for short. Hehehe. 

Also, I notice this namespace declaration happens to be outside the library. Do include it inside the library's module:

;(function(window){
  ...
  window.myNamespace = myLibraryStuffHere;
  ...
}(window));


So far, your code looks ok. Everything is pretty much covered. I also see that it works only with single selectors at the moment. However, I notice you are using replace to remove the # and .:

document.getElementById(input.replace(/#/, ""));


RegExp is heavy for trivial operations such as this. You can remove the first character using substr or substring. That way, you avoid RegExp.

document.getElementById(input.substr(1));


Now, in the demo, I see this:

a[0].onclick = function() { alert("you clicked the classes"); }
a[1].onclick = function() { alert("you clicked the classes"); }


If you had a hundred elements, would you do this still? I assume you'd do a loop, right? But wouldn't it be neat if the library took care of that? Yes?

So there's a reason they call it a "jQuery object". jQuery objects are basically arrays (array-like to be exact, normally called a set or collection) that applies operations to each item in the collection.

So to get you on the right track, think of this code:

a.on('click',someFunction);


a is the jQuery object, and on is a method of jQuery that attaches a click handler to each item in set a. on would look like:

myAmazingLibraryObject.prototype.on = function(event,handler){

  //assuming "this" represents the current collection and "elements"
  //is an array of elements, a result of getting by tag or by class.
  //Let's say we are standards compliant and ES5 compliant, 
  //we use forEach to loop through the set, and addEventListener to 
  //add the handlers.

  this.elements.forEach(function(element){
    element.addEventListener(event,handler,false);
  });
}


Now, you can do this:

var elements = myAmazingLibrary('a'); //get all &lt;a&gt;

elements.on('click',function(event){
  event.preventDefault();
  console.log('clicked');
});


An advantage of using a jQuery-like object, where the results are contained in an array, is that even when your collection is empty, the code does not break. If we used on on an empty collection, nothing will go wrong. Empty set, no loop, no element access, no error.

Lastly, don't just console.log or return false on errors. Throw meaningful errors instead. Use Error objects so that try-catch can collect them and inspect them. The last thing you would want from your code is to have it running broken and not know about it.