I have JavaScript widget code for collecting leads:
// Create an immediately invoked functional expression to wrap our code (function() { // Define our constructor this.Widget = function(options) { this.widgetWrap = null; this.widgetClose = null; this.widgetHeaderTitle = null; this.widgetInput = null; this.widgetFormInputError = null; this.widgetFormSubmit = null; this.titleAnimationInterval = null; this.overlay = null; this.formWrap = null; this.formIframe = null; this.images = { close: 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAB0AAAAeCAYAAADQBxWhAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABARJREFUeNqkV0tIm0EQ3lSkviIKKoKKD3wmtsVaxYrkgdVSUYrx4sGbp15FrLcKooJepCC9exSPglAqvuKzvp+RSqA+aioEqbZan9OZn+zPJv+f36QOfJDdncy3OzszO78OAFgA8hhhRpQhDIgUhB7xB3GA2EbYEROI3/daI1INPEVMQXAyiyjQsqtF+B4eJnbEEzXbOhX3mhCfPG6U5O7ujo2OjrLx8XG2tbXF9vf32dnZGYuMjGTJycksLy+PmUwmVl5ezkJDQ0Vbu4h3iC9a7rUivovbHRoaAovFAlFRUbQ7vwgPD4eSkhIYGBgA3KRowo1448+9dA8OWdPthsbGRtDpdJpkaqivr4ejoyOR+BDxUo10lmscHx9DVVVV0GQi0N2wt7cnEq/4kr7iK1dXV1BXVyf9MT09HTo7OyXQby2SxMREaGtrg56eHsjNzZXmKisr4fT0VCR+K5J+47Pd3d3SHzBIYHZWPjysr69DVlaWKiEGE8zNzcm629vbEBcXJ621traKpD84aRmfoXugHZNyZmamIgeWl5chIyNDccKJiQmFbnFxsbQeExMDu7u74lINkbbzUVdXl2yMTjoyMqIwtrS0BNnZ2ZJOUlISTE5OKnQWFxchNjZWttXS0iIu9xLpKB9RaoinSEtLg/n5edUTV1dXA+atYm1jYwMMBoOXncLCQlFlgUjl2Oau9SVeWFhQGL+8vFTM7ezsQH5+vsJGdHS0qPaLSG/4KCQkRDVQKHLVTiwKBY/RaPQb3aJ4jbRSIiEhAaam1Gv/ysrKvSklyiMWoFxfX7Pb21vVNZrH/GYBSyDupTy02+2a7l1dXZWjOhD3agYSpcX09LSCBE+umFtbW4OcnByFDb1eL6qdEqkc91QvReWUlBTVe9zc3ASbzQYzMzOq9+t74oKCAq9UJ9IOPmpvb5cVIyIiYHh4WGGUyiFPC0onsVTKrQPOUSXitpqamsTlj0Rq4aODgwOIj4/3WwbphLyYi95QIy4qKpJzlPJXkFpe8J18pqOjQ1KmR5vKGReHw+E3D1NTU6UqxYVqLS/4zc3NIuFP8ZV5zWcvLi6gpqZG+gPdTW9vrwS1APE9Mb1QfX19svutViucnJyIpDbfR/yr+NpUVFQ86BEvLS0Fp9PpFQ5qncML0c3UPTQ0NPwXYW1tLRweHoqEx54nVLUFfeV5aGUZHByUGq6wsDBNIuwCpdTo7++Hm5sbrwJPb+h9LajV04Lm8Akqcfi2srGxMYYRzFwuFzs/P2e4EYYFhWFEM7PZzPBKGKaaaMvpaUE/B9rhf3hgs01l7FmwHT7hOWIuSDLKs2Itu7oAP6DoY8ni+YAyIhIR5Me/CBfC4fmAGke47zP2T4ABAFQ+98JlesRjAAAAAElFTkSuQmCC', loading: 'url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKEAAAAgBAMAAACIkwX4AAAAMFBMVEUAAAAREREiIiIzMzNERERVVVVmZmZ3d3eIiIiZmZmqqqq7u7vMzMzd3d3u7u7///97EBgKAAAClklEQVR4Xu3WT2jTUBwH8F/arrZNJYH9QWG4nIa3TgSPW6cBPQi6mwfR6MmTLejB26LC2EFMPXiuMPDaehC8ZV68Zh4UQTBzE9ktYW7d0jb9+ntJJ5srqJCDh30Pr7y8Xz5J3+9BS0g4/v8sHonhPRpzEhVXJV0tJCru2vguJb2PIdkJiyAnYTFIAc/VIQcdIpJ95Z066rTJBaozxjR8BWtZBHN0HcBGedQGcTLoPaZRJ7xPNHJYfFZAR9I1mUVdv+znuVd5aBag1VsZIZYraI6cJxtd9dqtHPQLpF/EW9LL7qvUgwX6XdyaTdtAHa00i+KqVOFeuWYJXfJgzPvKThYIAGMGa+OM2lFdqN5FD1oFnUOiT+mncX/cWBwCuHKlCCGt532lNg2RleMwLcCMkZYoA9kDRPSW0h7weZHsWJQBmKXtY9gs8OKZ5eKwByB8Y8oou0CzxEi/DFdvDBIh9mmJaL/YVNoSlktAMEWUrgNt/pRBIgojogKcb9KdhUHii4lAeoKDIrRG1QKMMTNnZIHaCYcXaJFj7RPxkGiAyKtfZRwQzSswK5qLQHJ8pavWe6otFvgKJxJ5nzktqTHwW1dn+InhnpgFoFl8SwbYzMNXYJYiQ4Zh/RJ/RJ1pFqOJi5CHvrjhYZfqKwWs74lk8enxsJ3JA8sTQlwthtToTcl4nwPCWGyTOD2GaLzou3GTh1ispXUtix3Sh6f6Yjal07i4ZQKoVoTIfa9mZs/KCNQRXfMiETXSy19UhycCIoWH/jvO0aQNPEpZ5UYsyq9p0gWgzaOnukLsSN6udnqrAHzUpEt9MbxN5z5lICY7OVQtHoR4OCxCJNL+LX8St7NIWKydSlj8QI2EReNk0r+uL/+6L0f/KX4CxOvE6kQR0/oAAAAASUVORK5CYII=)', sprite: 'http://hotpartner.ru/forms/img/widget_sprite.png' }; // Establish our default settings this.options = extend({ formHeaders: ['Заголовок 1', 'Заголовок 2'], formText: 'Бесплатная консультация прямо у нас на сайте!', formPlaceholder: 'Введите Ваш вопрос...', color: '#336699', photo: 1, formPosition: 'right', transitionDuration: 150, questionMinLength: 15 }, options); this.init(); }; // Public Methods Widget.prototype.init = function() { var fragment = document.createDocumentFragment(); this.widgetWrap = document.createElement('div'); this.widgetWrap.style.backgroundColor = this.options.color; this.widgetWrap.style.borderRadius = '3px 3px 0 0'; this.widgetWrap.style.boxSizing = 'border-box'; this.widgetWrap.style.color = '#fff'; this.widgetWrap.style.font = '14px/1 Helvetica,Arial,sans-serif'; this.widgetWrap.style.padding = '10px'; this.widgetWrap.style.position = 'fixed'; this.widgetWrap.style.width = '335px'; this.widgetWrap.style.zIndex = 99999; this.widgetWrap.style.textAlign = 'left'; this.widgetWrap.style[this.options.formPosition] = '10px'; this.widgetWrap.style.bottom = '-185px'; this.widgetWrap.style.transitionProperty = 'bottom'; this.widgetWrap.style.transitionTimingFunction = 'ease-in'; this.widgetWrap.style.transitionDuration = this.options.transitionDuration + 'ms'; this.widgetClose = document.createElement('span'); this.widgetClose.style.backgroundImage = 'url(' + this.images.sprite + ')'; this.widgetClose.style.backgroundColor = this.options.color; this.widgetClose.style.borderRadius = '50%'; this.widgetClose.style.cursor = 'pointer'; this.widgetClose.style.height = '20px'; this.widgetClose.style.position = 'absolute'; this.widgetClose.style.right = '-9px'; this.widgetClose.style.top = '-9px'; this.widgetClose.style.width = '20px'; this.widgetClose.style.display = 'none'; this.widgetClose.style.backgroundPosition = '5px -88px'; this.widgetClose.onclick = this.toState.bind(this, 'mini'); this.widgetWrap.appendChild(this.widgetClose); var widgetHeader = document.createElement('div'); widgetHeader.style.marginBottom = '2px'; widgetHeader.style.padding = '6px 0px 14px'; widgetHeader.style.position = 'relative'; widgetHeader.style.borderBottom = '1px solid rgba(0, 0, 0, 0.1)'; widgetHeader.style.boxShadow = '0 2px 1px -1px rgba(255, 255, 255, 0.05)'; widgetHeader.style.cursor = 'pointer'; widgetHeader.onclick = this.slideToggle.bind(this); this.widgetHeaderTitle = document.createElement('div'); this.widgetHeaderTitle.style.color = '#fff'; this.widgetHeaderTitle.style.backgroundImage = 'url(' + this.images.sprite + ')'; this.widgetHeaderTitle.style.fontSize = '14px'; this.widgetHeaderTitle.style.overflow = 'hidden'; this.widgetHeaderTitle.style.paddingLeft = '27px'; this.widgetHeaderTitle.style.textOverflow = 'ellipsis'; this.widgetHeaderTitle.style.whiteSpace = 'nowrap'; this.widgetHeaderTitle.style.lineHeight = 1; this.widgetHeaderTitle.style.height = '20px'; this.widgetHeaderTitle.style.margin = '0px 10px'; this.widgetHeaderTitle.style.fontWeight = 'bold'; this.widgetHeaderTitle.style.backgroundRepeat = 'no-repeat'; this.widgetHeaderTitle.style.transitionProperty = 'opacity'; this.widgetHeaderTitle.style.transitionTimingFunction = 'ease-in'; this.widgetHeaderTitle.style.transitionDuration = this.options.transitionDuration + 'ms'; this.widgetHeaderTitle.textContent = this.options.formHeaders[0]; contentAnimation.call(this, this.widgetHeaderTitle, this.options.formHeaders); widgetHeader.appendChild(this.widgetHeaderTitle); this.widgetWrap.appendChild(widgetHeader); var widgetBody = document.createElement('div'); widgetBody.style.marginBottom = '10px'; widgetBody.style.padding = '10px'; var div_5 = document.createElement('div'); div_5.style.height = '55px'; div_5.style.marginBottom = '20px'; div_5.style.overflow = 'hidden'; div_5.style.paddingLeft = '72px'; div_5.style.position = 'relative'; var div_6 = document.createElement('div'); div_6.style.top = '0'; div_6.style.left = '0'; div_6.style.position = 'absolute'; div_6.style.borderRadius = '10px'; div_6.style.backgroundColor = '#66CC33'; div_6.style.height = '6px'; div_6.style.width = '6px'; div_5.appendChild(div_6); var photoImg = document.createElement('img'); photoImg.src = 'http://hotpartner.ru/forms/images/' + this.options.photo + '.png'; photoImg.style.width = '52px'; photoImg.style.height = '52px'; photoImg.style.borderRadius = '50%'; photoImg.style.margin = '-27px 0 0'; photoImg.style.position = 'absolute'; photoImg.style.left = '0'; photoImg.style.top = '50%'; photoImg.title = ''; div_5.appendChild(photoImg); var div_8 = document.createElement('div'); div_8.style.backgroundColor = 'rgba(255, 255, 255, 0.2)'; div_8.style.borderRadius = '3px'; div_8.style.boxSizing = 'border-box'; div_8.style.color = '#fff'; div_8.style.height = '53px'; div_8.style.padding = '7px'; div_8.style.position = 'relative'; var i_0 = document.createElement('i'); i_0.style.backgroundImage = 'url(' + this.images.sprite + ')'; i_0.style.height = '10px'; i_0.style.left = '-13px'; i_0.style.marginTop = '-15px'; i_0.style.position = 'absolute'; i_0.style.top = '50%'; i_0.style.width = '14px'; i_0.style.backgroundPosition = '0px -232px'; i_0.style.backgroundRepeat = 'no-repeat'; div_8.appendChild(i_0); var span_1 = document.createElement('span'); span_1.style.display = 'block'; span_1.style.height = '34px'; span_1.style.overflow = 'hidden'; span_1.style.lineHeight = '18px'; span_1.textContent = this.options.formText; div_8.appendChild(span_1); div_5.appendChild(div_8); widgetBody.appendChild(div_5); this.widgetInput = document.createElement('textarea'); this.widgetInput.maxLength = 768; this.widgetInput.rows = 1; this.widgetInput.style.color = '#333'; this.widgetInput.style.resize = 'none'; this.widgetInput.style.display = 'block'; this.widgetInput.style.padding = '8px'; this.widgetInput.style.width = '295px'; this.widgetInput.style.border = '0'; this.widgetInput.style.borderRadius = '3px'; this.widgetInput.style.lineHeight = '16px'; this.widgetInput.style.fontFamily = 'Arial, sans-serif'; this.widgetInput.style.fontSize = '14px'; this.widgetInput.style.margin = '1px 0px'; this.widgetInput.style.boxShadow = '-2px 2px 3px -1px rgba(0, 0, 0, 0.7)'; this.widgetInput.style.boxSizing = 'border-box'; this.widgetInput.style.background = 'url(' + this.images.sprite + ') no-repeat scroll right -251px #fff'; this.widgetInput.style.height = '35px'; this.widgetInput.style.overflowX = 'hidden'; this.widgetInput.style.overflowY = 'auto'; this.widgetInput.style.transitionProperty = 'height'; this.widgetInput.style.transitionTimingFunction = 'ease-in'; this.widgetInput.style.transitionDuration = this.options.transitionDuration + 'ms'; this.widgetInput.placeholder = this.options.formPlaceholder; this.widgetInput.onclick = this.toState.bind(this, 'full'); this.widgetInput.onblur = this.slideToggle.bind(this); widgetBody.appendChild(this.widgetInput); this.widgetFormInputError = document.createElement('div'); this.widgetFormInputError.style.backgroundColor = '#FFFF66'; this.widgetFormInputError.style.border = '1px solid #CCCC00'; this.widgetFormInputError.style.borderRadius = '0 0 4px 4px'; this.widgetFormInputError.style.boxSizing = 'content-box'; this.widgetFormInputError.style.color = '#000'; this.widgetFormInputError.style.height = '20px'; this.widgetFormInputError.style.marginTop = '-31px'; this.widgetFormInputError.style.padding = '5px 0px'; this.widgetFormInputError.style.position = 'absolute'; this.widgetFormInputError.style.textAlign = 'center'; this.widgetFormInputError.style.opacity = 0; this.widgetFormInputError.style.visibility = 'hidden'; this.widgetFormInputError.style.width = '293px'; this.widgetFormInputError.style.fontSize = '12px'; this.widgetFormInputError.style.lineHeight = '20px'; this.widgetFormInputError.style.fontStyle = 'italic'; this.widgetFormInputError.style.transitionProperty = 'opacity'; this.widgetFormInputError.style.transitionTimingFunction = 'ease-in'; this.widgetFormInputError.style.transitionDuration = this.options.transitionDuration + 'ms'; this.widgetFormInputError.textContent = 'Опишите, пожалуйста, подробнее ваш вопрос.'; widgetBody.appendChild(this.widgetFormInputError); this.widgetWrap.appendChild(widgetBody); var widgetForm = document.createElement('div'); widgetForm.style.fontWeight = 'bold'; widgetForm.style.paddingRight = '120px'; widgetForm.style.position = 'relative'; var widgetFormLabel = document.createElement('span'); widgetFormLabel.style.background = 'url(' + this.images.sprite + ') no-repeat scroll 0 -52px rgba(0, 0, 0, 0)'; widgetFormLabel.style.display = 'block'; widgetFormLabel.style.height = '28px'; widgetFormLabel.style.paddingLeft = '30px'; widgetFormLabel.style.marginLeft = '10px'; widgetFormLabel.innerHTML = 'Онлайн<br>Консультация'; widgetForm.appendChild(widgetFormLabel); this.widgetFormSubmit = document.createElement('button'); this.widgetFormSubmit.style.position = 'absolute'; this.widgetFormSubmit.style.right = '0'; this.widgetFormSubmit.style.top = '0'; this.widgetFormSubmit.style.width = '120px'; this.widgetFormSubmit.style.height = '26px'; this.widgetFormSubmit.style.border = '0'; this.widgetFormSubmit.style.borderTop = '1px solid #afe18a'; this.widgetFormSubmit.style.borderRadius = '3px'; this.widgetFormSubmit.style.boxSizing = 'border-box'; this.widgetFormSubmit.style.font = 'bold 14px/1.4 Helvetica, Arial, sans-serif'; this.widgetFormSubmit.style.textShadow = '0 1px 1px rgba(0,0,0,.5)'; this.widgetFormSubmit.style.color = 'white'; this.widgetFormSubmit.style.cursor = 'pointer'; this.widgetFormSubmit.style.outline = 'none'; this.widgetFormSubmit.style.backgroundColor = '#66CC33'; this.widgetFormSubmit.style.marginRight = '10px'; this.widgetFormSubmit.type = 'submit'; this.widgetFormSubmit.textContent = 'Отправить'; this.widgetFormSubmit.onclick = this.send.bind(this); widgetForm.appendChild(this.widgetFormSubmit); this.widgetWrap.appendChild(widgetForm); fragment.appendChild(this.widgetWrap); this.overlay = document.createElement('div'); this.overlay.style.zIndex = '2147483646'; this.overlay.style.display = 'none'; this.overlay.style.position = 'fixed'; this.overlay.style.background = 'rgba(0,0,0,.5)'; this.overlay.style.width = '100%'; this.overlay.style.height = '100%'; this.overlay.style.top = '0'; this.overlay.style.left = '0'; this.overlay.onclick = this.formHide.bind(this); fragment.appendChild(this.overlay); this.formWrap = document.createElement('div'); this.formWrap.style.zIndex = '2147483647'; this.formWrap.style.display = 'none'; this.formWrap.style.position = 'fixed'; this.formWrap.style.borderRadius = '3px'; this.formWrap.style.background = '#fff'; this.formWrap.style.backgroundImage = this.images.loading; this.formWrap.style.backgroundPosition = 'center'; this.formWrap.style.backgroundRepeat = 'no-repeat'; this.formWrap.style.margin = 'auto'; this.formWrap.style.boxShadow = '0 0 20px rgba(0,0,0,.5)'; this.formWrap.style.transform = 'translate(-50%,-50%)'; this.formWrap.style.top = '50%'; this.formWrap.style.left = '50%'; var formClose = document.createElement('img'); formClose.src = this.images.close; formClose.style.position = 'absolute'; formClose.style.right = '0'; formClose.style.margin = '-15px -15px 0 0'; formClose.style.cursor = 'pointer'; formClose.onclick = this.formHide.bind(this); this.formWrap.appendChild(formClose); this.formIframe = document.createElement('iframe'); this.formIframe.urlBase = 'http://hotpartner.ru/forms/form.min.htm'; this.formIframe.width = 400; this.formIframe.height = 530; this.formIframe.style.border = '0'; this.formIframe.style.margin = '1px'; this.formWrap.appendChild(this.formIframe); fragment.appendChild(this.formWrap); document.body.appendChild(fragment); }; Widget.prototype.slideToggle = function() { if (this.widgetInput.value) { this.toState('full'); } else { this.toState('expanded'); } }; Widget.prototype.toState = function(state) { switch (state) { case 'mini': this.widgetWrap.style.bottom = '-185px'; this.widgetClose.style.display = 'none'; this.widgetInput.style.height = '35px'; this.widgetInput.style.background = 'url(' + this.images.sprite + ') no-repeat scroll right -251px #fff'; contentAnimation.call(this, this.widgetHeaderTitle, this.options.formHeaders); break; case 'expanded': this.widgetWrap.style.bottom = '-39px'; this.widgetClose.style.display = ''; this.widgetInput.style.height = '35px'; this.widgetInput.style.background = 'url(' + this.images.sprite + ') no-repeat scroll right -251px #fff'; clearInterval(this.titleAnimationInterval); break; case 'full': this.widgetWrap.style.bottom = '0'; this.widgetClose.style.display = ''; this.widgetInput.style.height = '80px'; this.widgetInput.style.backgroundImage = 'none'; clearInterval(this.titleAnimationInterval); break; } }; Widget.prototype.send = function() { var self = this; if (self.widgetInput.value) { self.widgetInput.style.border = '0'; self.widgetInput.style.boxShadow = '-2px 2px 3px -1px rgba(0, 0, 0, 0.7)'; if (self.widgetInput.value.length < self.options.questionMinLength) { self.widgetFormInputError.style.opacity = 100; self.widgetFormInputError.style.visibility = 'visible'; setTimeout(function() { self.widgetFormInputError.style.opacity = 0; self.widgetFormInputError.style.visibility = 'hidden'; }, 4000); } else { self.formUpdate(); self.toState('mini'); self.overlay.style.display = ''; self.formWrap.style.display = ''; } } else { self.widgetInput.style.borderColor = '#f00'; self.widgetInput.style.boxShadow = '0 0 20px #f00'; } }; Widget.prototype.formHide = function() { this.overlay.style.display = 'none'; this.formWrap.style.display = 'none'; }; Widget.prototype.formUpdate = function() { var url = this.formIframe.urlBase + '?q=' + encodeURI(this.widgetInput.value.substring(0, 768)) + '&partnerId=' + this.options.partnerId + '&channelId=' + this.options.channelId + '&departmentId=' + this.options.departmentId + '&referer=' + encodeURI(document.URL); this.formIframe.src = url; }; // Private Methods function contentAnimation(el, arr) { var self = this; var current = 1; self.titleAnimationInterval = setInterval(function() { el.style.opacity = 0; setTimeout(function() { el.textContent = arr[current]; el.style.opacity = 1; current = ++current % arr.length; }, self.options.transitionDuration); }, 4000); } function extend(out) { out = out || {}; for (var i = 1; i < arguments.length; i++) { if (!arguments[i]) { continue; } for (var key in arguments[i]) { if (arguments[i].hasOwnProperty(key)) { out[key] = arguments[i][key]; } } } return out; } }()); <script> //USAGE of library //doesn't block the load event window.addEventListener('load', function load() { window.removeEventListener('load', load); //remove listener, no longer needed new Widget({ partnerId: '7a611bed-2530-4068-9d34-a0482bd9d626', departmentId: 4, channelId: 9, formHeaders: ['Header 1', 'Header 2', 'Header 3'], formText: 'Invite text', formPlaceholder: 'Placeholder text', photo: 23, color: '#000' }); }); </script> Do you see any improvements / issues?
thiseverywhere? It's not needed, bloats the code and can be confusing when say I needed to really know thatthisis source of an event. \$\endgroup\$