jQuery сохраняет у себя все обработчики навешанные с помощью $.fn.on для подобных случаев и при клонировании переносит их на новые элементы в соответствии с оригиналами. Если хотите всё-таки делать без jQuery, то тоже потребуется писать свою обёртку не только для клонирования, но и для добавления обработчиков.
function bind(elem, event, handler) {
var events = elem.__events__ || (elem.__events__ = {}),
currentEvent = events[event] || (events[event] = []);
elem.addEventListener(event, handler);
currentEvent.push(handler);
}
function cloneWithEvents(elem) {
var clone = elem.cloneNode(),
originalEvents = elem.__events__;
if (originalEvents) {
for (var eventName in originalEvents) {
if (originalEvents.hasOwnProperty(eventName)) {
var currentEvent = originalEvents[eventName];
for (var i = 0, l = currentEvent.length; i < l; i++) {
clone.addEventListener(eventName, currentEvent[i]);
}
}
}
}
return clone;
}
Примерно так. Чтобы сделать красивее и для потомков можете глянуть в исходники jQuery как там устроен $.fn.clone, особой сложности нет.
upd. Для корректной работы ещё потребуется функция unbind, написанная по тому же принципу, что и bind.