Currently I am working on a webapplication for my company, and recently started learning JS/Jquery. I have set up content in a Tabs plugin/libary from the github link below:
https://github.com/samsono/Easy-Responsive-Tabs-to-Accordion
The JS file
// Easy Responsive Tabs Plugin
// Author: Samson.Onna <Email : samson3d#gmail.com>
(function ($) {
$.fn.extend({
easyResponsiveTabs: function (options) {
//Set the default values, use comma to separate the settings, example:
var defaults = {
type: 'default', //default, vertical, accordion;
width: 'auto',
fit: true,
closed: false,
tabidentify: '',
activate: function () {
}
}
//Variables
var options = $.extend(defaults, options);
var opt = options, jtype = opt.type, jfit = opt.fit, jwidth = opt.width, vtabs = 'vertical', accord = 'accordion';
var hash = window.location.hash;
var historyApi = !!(window.history && history.replaceState );
//Events
$(this).bind('tabactivate', function (e, currentTab) {
if (typeof options.activate === 'function') {
options.activate.call(currentTab, e)
}
});
//Main function
this.each(function () {
var $respTabs = $(this);
var $respTabsList = $respTabs.find('ul.resp-tabs-list.' + options.tabidentify);
var respTabsId = $respTabs.attr('id');
$respTabs.find('ul.resp-tabs-list.' + options.tabidentify + ' li').addClass('resp-tab-item').addClass(options.tabidentify);
$respTabs.css({
'display': 'block',
'width': jwidth
});
if (options.type == 'vertical')
$respTabsList.css('margin-top', '0px');
$respTabs.find('.resp-tabs-container.' + options.tabidentify).css('border-color', options.active_content_border_color);
$respTabs.find('.resp-tabs-container.' + options.tabidentify + ' > div').addClass('resp-tab-content').addClass(options.tabidentify);
jtab_options();
//Properties Function
function jtab_options() {
if (jtype == vtabs) {
$respTabs.addClass('resp-vtabs').addClass(options.tabidentify);
}
if (jfit == true) {
$respTabs.css({ width: '100%', margin: '0px' });
}
if (jtype == accord) {
$respTabs.addClass('resp-easy-accordion').addClass(options.tabidentify);
$respTabs.find('.resp-tabs-list').css('display', 'none');
}
}
//Assigning the h2 markup to accordion title
var $tabItemh2;
$respTabs.find('.resp-tab-content.' + options.tabidentify).before("<h2 class='resp-accordion " + options.tabidentify + "' role='tab'><span class='resp-arrow'></span></h2>");
$respTabs.find('.resp-tab-content.' + options.tabidentify).prev("h2").css({
'background-color': options.inactive_bg,
'border-color': options.active_border_color
});
var itemCount = 0;
$respTabs.find('.resp-accordion').each(function () {
$tabItemh2 = $(this);
var $tabItem = $respTabs.find('.resp-tab-item:eq(' + itemCount + ')');
var $accItem = $respTabs.find('.resp-accordion:eq(' + itemCount + ')');
$accItem.append($tabItem.html());
$accItem.data($tabItem.data());
$tabItemh2.attr('aria-controls', options.tabidentify + '_tab_item-' + (itemCount));
itemCount++;
});
//Assigning the 'aria-controls' to Tab items
var count = 0,
$tabContent;
$respTabs.find('.resp-tab-item').each(function () {
$tabItem = $(this);
$tabItem.attr('aria-controls', options.tabidentify + '_tab_item-' + (count));
$tabItem.attr('role', 'tab');
$tabItem.css({
'background-color': options.inactive_bg,
'border-color': 'none'
});
//Assigning the 'aria-labelledby' attr to tab-content
var tabcount = 0;
$respTabs.find('.resp-tab-content.' + options.tabidentify).each(function () {
$tabContent = $(this);
$tabContent.attr('aria-labelledby', options.tabidentify + '_tab_item-' + (tabcount)).css({
'border-color': options.active_border_color
});
tabcount++;
});
count++;
});
// Show correct content area
var tabNum = 0;
if (hash != '') {
var matches = hash.match(new RegExp(respTabsId + "([0-9]+)"));
if (matches !== null && matches.length === 2) {
tabNum = parseInt(matches[1], 10) - 1;
if (tabNum > count) {
tabNum = 0;
}
}
}
//Active correct tab
$($respTabs.find('.resp-tab-item.' + options.tabidentify)[tabNum]).addClass('resp-tab-active').css({
'background-color': options.activetab_bg,
'border-color': options.active_border_color
});
//keep closed if option = 'closed' or option is 'accordion' and the element is in accordion mode
if (options.closed !== true && !(options.closed === 'accordion' && !$respTabsList.is(':visible')) && !(options.closed === 'tabs' && $respTabsList.is(':visible'))) {
$($respTabs.find('.resp-accordion.' + options.tabidentify)[tabNum]).addClass('resp-tab-active').css({
'background-color': options.activetab_bg + ' !important',
'border-color': options.active_border_color,
'background': 'none'
});
$($respTabs.find('.resp-tab-content.' + options.tabidentify)[tabNum]).addClass('resp-tab-content-active').addClass(options.tabidentify).attr('style', 'display:block');
}
//assign proper classes for when tabs mode is activated before making a selection in accordion mode
else {
// $($respTabs.find('.resp-tab-content.' + options.tabidentify)[tabNum]).addClass('resp-accordion-closed'); //removed resp-tab-content-active
}
//Tab Click action function
$respTabs.find("[role=tab]").each(function () {
var $currentTab = $(this);
$currentTab.hover(function () {
var $currentTab = $(this);
var $tabAria = $currentTab.attr('aria-controls');
if ($currentTab.hasClass('resp-accordion') && $currentTab.hasClass('resp-tab-active')) {
$respTabs.find('.resp-tab-content-active.' + options.tabidentify).slideUp('', function () {
$(this).addClass('resp-accordion-closed');
});
$currentTab.removeClass('resp-tab-active').css({
'background-color': options.inactive_bg,
'border-color': 'none'
});
return false;
}
if (!$currentTab.hasClass('resp-tab-active') && $currentTab.hasClass('resp-accordion')) {
$respTabs.find('.resp-tab-active.' + options.tabidentify).removeClass('resp-tab-active').css({
'background-color': options.inactive_bg,
'border-color': 'none'
});
$respTabs.find('.resp-tab-content-active.' + options.tabidentify).slideUp().removeClass('resp-tab-content-active resp-accordion-closed');
$respTabs.find("[aria-controls=" + $tabAria + "]").addClass('resp-tab-active').css({
'background-color': options.activetab_bg,
'border-color': options.active_border_color
});
$respTabs.find('.resp-tab-content[aria-labelledby = ' + $tabAria + '].' + options.tabidentify).slideDown().addClass('resp-tab-content-active');
} else {
console.log('here');
$respTabs.find('.resp-tab-active.' + options.tabidentify).removeClass('resp-tab-active').css({
'background-color': options.inactive_bg,
'border-color': 'none'
});
$respTabs.find('.resp-tab-content-active.' + options.tabidentify).removeAttr('style').removeClass('resp-tab-content-active').removeClass('resp-accordion-closed');
$respTabs.find("[aria-controls=" + $tabAria + "]").addClass('resp-tab-active').css({
'background-color': options.activetab_bg,
'border-color': options.active_border_color
});
$respTabs.find('.resp-tab-content[aria-labelledby = ' + $tabAria + '].' + options.tabidentify).addClass('resp-tab-content-active').attr('style', 'display:block');
}
//Trigger tab activation event
$currentTab.trigger('tabactivate', $currentTab);
//Update Browser History
if (historyApi) {
var currentHash = window.location.hash;
var tabAriaParts = $tabAria.split('tab_item-');
// var newHash = respTabsId + (parseInt($tabAria.substring(9), 10) + 1).toString();
var newHash = respTabsId + (parseInt(tabAriaParts[1], 10) + 1).toString();
if (currentHash != "") {
var re = new RegExp(respTabsId + "[0-9]+");
if (currentHash.match(re) != null) {
newHash = currentHash.replace(re, newHash);
}
else {
newHash = currentHash + "|" + newHash;
}
}
else {
newHash = '#' + newHash;
}
history.replaceState(null, null, newHash);
}
});
});
//Window resize function
$(window).resize(function () {
$respTabs.find('.resp-accordion-closed').removeAttr('style');
});
});
}
});
})(jQuery);
Orginally the tabs are set to a onclick like this on line number 142:
$currentTab.click(function () {
I've changed the tabs to a hover because I like that more for my application, like so:
$currentTab.hover(function () {
It works fine on my desktop but when I resize my browser to a smaller resolution the tabs will change in a accordion. Normally it works totally fine, but because I've changed it to a hover system it's not the best option to have now. Is there any way to detect smaller resolutions in javascript/jquery so when its like under 800px the function changes back to $currentTab.click(function () {? Or any other solution for my problem?
What I want: Change a jquery hover event function based on resolution OR change a JS script based on resolution (So I create 2 js files, one for mobile and one for desktop and then decide which script I would load).
Make a named function and do
if (window.screen.width < whatever ) $currentTab.click(doIt);
else $currentTab.hover(doIt);
Related
I'm trying to comment out a block of code in my site's main.js file, since it makes my sticky header jump in a funny way upon scrolling.
When I comment out the sticky header section, it fixes the jumpy header issue.
However, it also throws the following error in Firefox or Chrome developer console:
Uncaught ReferenceError: jQuery is not defined
Here is the original unedited code:
jQuery(function ($) {
// Sticky Header
if ($('body').hasClass('sticky-header')) {
var header = $('#sp-header');
if($('#sp-header').length) {
var headerHeight = header.outerHeight();
var stickyHeaderTop = header.offset().top;
var stickyHeader = function () {
var scrollTop = $(window).scrollTop();
if (scrollTop > stickyHeaderTop) {
header.addClass('header-sticky');
} else {
if (header.hasClass('header-sticky')) {
header.removeClass('header-sticky');
}
}
};
stickyHeader();
$(window).scroll(function () {
stickyHeader();
});
}
if ($('body').hasClass('layout-boxed')) {
var windowWidth = header.parent().outerWidth();
header.css({"max-width": windowWidth, "left": "auto"});
}
}
// go to top
$(window).scroll(function () {
if ($(this).scrollTop() > 100) {
$('.sp-scroll-up').fadeIn();
} else {
$('.sp-scroll-up').fadeOut(400);
}
});
$('.sp-scroll-up').click(function () {
$("html, body").animate({
scrollTop: 0
}, 600);
return false;
});
// Preloader
$(window).on('load', function () {
$('.sp-preloader').fadeOut(500, function() {
$(this).remove();
});
});
//mega menu
$('.sp-megamenu-wrapper').parent().parent().css('position', 'static').parent().css('position', 'relative');
$('.sp-menu-full').each(function () {
$(this).parent().addClass('menu-justify');
});
// Offcanvs
$('#offcanvas-toggler').on('click', function (event) {
event.preventDefault();
$('.offcanvas-init').addClass('offcanvas-active');
});
$('.close-offcanvas, .offcanvas-overlay').on('click', function (event) {
event.preventDefault();
$('.offcanvas-init').removeClass('offcanvas-active');
});
$(document).on('click', '.offcanvas-inner .menu-toggler', function(event){
event.preventDefault();
$(this).closest('.menu-parent').toggleClass('menu-parent-open').find('>.menu-child').slideToggle(400);
});
//Tooltip
$('[data-toggle="tooltip"]').tooltip();
// Article Ajax voting
$('.article-ratings .rating-star').on('click', function (event) {
event.preventDefault();
var $parent = $(this).closest('.article-ratings');
var request = {
'option': 'com_ajax',
'template': template,
'action': 'rating',
'rating': $(this).data('number'),
'article_id': $parent.data('id'),
'format': 'json'
};
$.ajax({
type: 'POST',
data: request,
beforeSend: function () {
$parent.find('.fa-spinner').show();
},
success: function (response) {
var data = $.parseJSON(response);
$parent.find('.ratings-count').text(data.message);
$parent.find('.fa-spinner').hide();
if(data.status)
{
$parent.find('.rating-symbol').html(data.ratings)
}
setTimeout(function(){
$parent.find('.ratings-count').text('(' + data.rating_count + ')')
}, 3000);
}
});
});
// Cookie consent
$('.sp-cookie-allow').on('click', function(event) {
event.preventDefault();
var date = new Date();
date.setTime(date.getTime() + (30 * 24 * 60 * 60 * 1000));
var expires = "; expires=" + date.toGMTString();
document.cookie = "spcookie_status=ok" + expires + "; path=/";
$(this).closest('.sp-cookie-consent').fadeOut();
});
$(".btn-group label:not(.active)").click(function()
{
var label = $(this);
var input = $('#' + label.attr('for'));
if (!input.prop('checked')) {
label.closest('.btn-group').find("label").removeClass('active btn-success btn-danger btn-primary');
if (input.val() === '') {
label.addClass('active btn-primary');
} else if (input.val() == 0) {
label.addClass('active btn-danger');
} else {
label.addClass('active btn-success');
}
input.prop('checked', true);
input.trigger('change');
}
var parent = $(this).parents('#attrib-helix_ultimate_blog_options');
if( parent ){
showCategoryItems( parent, input.val() )
}
});
$(".btn-group input[checked=checked]").each(function()
{
if ($(this).val() == '') {
$("label[for=" + $(this).attr('id') + "]").addClass('active btn btn-primary');
} else if ($(this).val() == 0) {
$("label[for=" + $(this).attr('id') + "]").addClass('active btn btn-danger');
} else {
$("label[for=" + $(this).attr('id') + "]").addClass('active btn btn-success');
}
var parent = $(this).parents('#attrib-helix_ultimate_blog_options');
if( parent ){
parent.find('*[data-showon]').each( function() {
$(this).hide();
})
}
});
function showCategoryItems(parent, value){
var controlGroup = parent.find('*[data-showon]');
controlGroup.each( function() {
var data = $(this).attr('data-showon')
data = typeof data !== 'undefined' ? JSON.parse( data ) : []
if( data.length > 0 ){
if(typeof data[0].values !== 'undefined' && data[0].values.includes( value )){
$(this).slideDown();
}else{
$(this).hide();
}
}
})
}
$(window).on('scroll', function(){
var scrollBar = $(".sp-reading-progress-bar");
if( scrollBar.length > 0 ){
var s = $(window).scrollTop(),
d = $(document).height(),
c = $(window).height();
var scrollPercent = (s / (d - c)) * 100;
const postition = scrollBar.data('position')
if( postition === 'top' ){
// var sticky = $('.header-sticky');
// if( sticky.length > 0 ){
// sticky.css({ top: scrollBar.height() })
// }else{
// sticky.css({ top: 0 })
// }
}
scrollBar.css({width: `${scrollPercent}%` })
}
})
});
The portion I want to comment out is just the "sticky header" block.
I tried to do so like this:
jQuery(function ($) {
// Sticky Header
/* if ($('body').hasClass('sticky-header')) {
var header = $('#sp-header');
if($('#sp-header').length) {
var headerHeight = header.outerHeight();
var stickyHeaderTop = header.offset().top;
var stickyHeader = function () {
var scrollTop = $(window).scrollTop();
if (scrollTop > stickyHeaderTop) {
header.addClass('header-sticky');
} else {
if (header.hasClass('header-sticky')) {
header.removeClass('header-sticky');
}
}
};
stickyHeader();
$(window).scroll(function () {
stickyHeader();
});
}
if ($('body').hasClass('layout-boxed')) {
var windowWidth = header.parent().outerWidth();
header.css({"max-width": windowWidth, "left": "auto"});
}
}
*/
// go to top
$(window).scroll(function () {
if ($(this).scrollTop() > 100) {
$('.sp-scroll-up').fadeIn();
} else {
$('.sp-scroll-up').fadeOut(400);
}
});
$('.sp-scroll-up').click(function () {
$("html, body").animate({
scrollTop: 0
}, 600);
return false;
});
// Preloader
$(window).on('load', function () {
$('.sp-preloader').fadeOut(500, function() {
$(this).remove();
});
});
//mega menu
$('.sp-megamenu-wrapper').parent().parent().css('position', 'static').parent().css('position', 'relative');
$('.sp-menu-full').each(function () {
$(this).parent().addClass('menu-justify');
});
// Offcanvs
$('#offcanvas-toggler').on('click', function (event) {
event.preventDefault();
$('.offcanvas-init').addClass('offcanvas-active');
});
$('.close-offcanvas, .offcanvas-overlay').on('click', function (event) {
event.preventDefault();
$('.offcanvas-init').removeClass('offcanvas-active');
});
$(document).on('click', '.offcanvas-inner .menu-toggler', function(event){
event.preventDefault();
$(this).closest('.menu-parent').toggleClass('menu-parent-open').find('>.menu-child').slideToggle(400);
});
//Tooltip
$('[data-toggle="tooltip"]').tooltip();
// Article Ajax voting
$('.article-ratings .rating-star').on('click', function (event) {
event.preventDefault();
var $parent = $(this).closest('.article-ratings');
var request = {
'option': 'com_ajax',
'template': template,
'action': 'rating',
'rating': $(this).data('number'),
'article_id': $parent.data('id'),
'format': 'json'
};
$.ajax({
type: 'POST',
data: request,
beforeSend: function () {
$parent.find('.fa-spinner').show();
},
success: function (response) {
var data = $.parseJSON(response);
$parent.find('.ratings-count').text(data.message);
$parent.find('.fa-spinner').hide();
if(data.status)
{
$parent.find('.rating-symbol').html(data.ratings)
}
setTimeout(function(){
$parent.find('.ratings-count').text('(' + data.rating_count + ')')
}, 3000);
}
});
});
// Cookie consent
$('.sp-cookie-allow').on('click', function(event) {
event.preventDefault();
var date = new Date();
date.setTime(date.getTime() + (30 * 24 * 60 * 60 * 1000));
var expires = "; expires=" + date.toGMTString();
document.cookie = "spcookie_status=ok" + expires + "; path=/";
$(this).closest('.sp-cookie-consent').fadeOut();
});
$(".btn-group label:not(.active)").click(function()
{
var label = $(this);
var input = $('#' + label.attr('for'));
if (!input.prop('checked')) {
label.closest('.btn-group').find("label").removeClass('active btn-success btn-danger btn-primary');
if (input.val() === '') {
label.addClass('active btn-primary');
} else if (input.val() == 0) {
label.addClass('active btn-danger');
} else {
label.addClass('active btn-success');
}
input.prop('checked', true);
input.trigger('change');
}
var parent = $(this).parents('#attrib-helix_ultimate_blog_options');
if( parent ){
showCategoryItems( parent, input.val() )
}
});
$(".btn-group input[checked=checked]").each(function()
{
if ($(this).val() == '') {
$("label[for=" + $(this).attr('id') + "]").addClass('active btn btn-primary');
} else if ($(this).val() == 0) {
$("label[for=" + $(this).attr('id') + "]").addClass('active btn btn-danger');
} else {
$("label[for=" + $(this).attr('id') + "]").addClass('active btn btn-success');
}
var parent = $(this).parents('#attrib-helix_ultimate_blog_options');
if( parent ){
parent.find('*[data-showon]').each( function() {
$(this).hide();
})
}
});
function showCategoryItems(parent, value){
var controlGroup = parent.find('*[data-showon]');
controlGroup.each( function() {
var data = $(this).attr('data-showon')
data = typeof data !== 'undefined' ? JSON.parse( data ) : []
if( data.length > 0 ){
if(typeof data[0].values !== 'undefined' && data[0].values.includes( value )){
$(this).slideDown();
}else{
$(this).hide();
}
}
})
}
$(window).on('scroll', function(){
var scrollBar = $(".sp-reading-progress-bar");
if( scrollBar.length > 0 ){
var s = $(window).scrollTop(),
d = $(document).height(),
c = $(window).height();
var scrollPercent = (s / (d - c)) * 100;
const postition = scrollBar.data('position')
if( postition === 'top' ){
// var sticky = $('.header-sticky');
// if( sticky.length > 0 ){
// sticky.css({ top: scrollBar.height() })
// }else{
// sticky.css({ top: 0 })
// }
}
scrollBar.css({width: `${scrollPercent}%` })
}
})
});
This is effectively commenting out the section and fixing the header bug, but it's also throwing the jQuery not defined error. Is there a more appropriate method for commenting out the section?
Note that the same error occurs if I simply delete the entire sticky header block.
Thank you from a newbie for any help!
Simply try single line comments for each line in the code block. If you have VS Code or similar IDE, then it should do it for you. Select all the lines and press CTRL + / or CMD + / (Mac).
// if ($('body').hasClass('sticky-header')) {
// var header = $('#sp-header');
// if($('#sp-header').length) {
// var headerHeight = header.outerHeight();
// var stickyHeaderTop = header.offset().top;
// var stickyHeader = function () {
// var scrollTop = $(window).scrollTop();
// if (scrollTop > stickyHeaderTop) {
// header.addClass('header-sticky');
// } else {
// if (header.hasClass('header-sticky')) {
// header.removeClass('header-sticky');
// }
// }
// };
// stickyHeader();
// $(window).scroll(function () {
// stickyHeader();
// });
// }
// if ($('body').hasClass('layout-boxed')) {
// var windowWidth = header.parent().outerWidth();
// header.css({"max-width": windowWidth, "left": "auto"});
// }
// }
for some reason my input elements are getting wrapped twice or sometimes even more when I refresh the screen.
I've tried to check if the parent is e-wrap and if not add the e-wrap but the result is nothing and causes the placeholders to not show at all.
var InputClass = BaseClass.extend(function(inputName) {
this.type = 'InputClass';
this.dom = jQuery(inputName);
if (this.dom.attr('placeholder')) {
if (this.dom.data('flaying-placeholder'))
return false;
this.dom.data('flaying-placeholder', true);
this.dom.wrap('<div class="e-wrap"></div>');
var ph = this.jq('<div class="placeholder-text"></div>');
this.dom.data("placeholder", this.dom.attr('placeholder'));
ph.html(this.dom.attr('placeholder'));
ph.css({
'font-size': this.dom.css('font-size')
});
if (this.dom.val() != '') {
this.dom.attr('placeholder', '');
ph.css({
'top': '-' + this.dom.css('font-size')
});
ph.addClass('active');
ph.show();
} else {
ph.hide();
ph.removeClass('active');
}
this.dom.bind('focus', function() {
this.dom.parent().addClass('focused');
this.dom.attr('placeholder', '');
ph.css({
'left': '12px',
'top': '-1px'
});
ph.show();
ph.addClass('active');
if (this.dom.val() != '') {
ph.css({
'top': '-' + this.dom.css('font-size')
});
} else {
ph.animate({
'top': '-' + this.dom.css('font-size')
}, 500);
}
}.bind(this));
this.dom.bind('focusout', function() {
this.dom.parent().removeClass('focused');
this.dom.attr('placeholder', this.dom.data("placeholder"));
if (this.dom.val() != '') {
ph.show();
ph.css({
'top': '-' + this.dom.css('font-size')
});
ph.addClass('active');
} else {
ph.hide();
ph.removeClass('active');
}
}.bind(this));
this.dom.before(ph);
}
}).statics({}).methods({
toggleDialog: function(text) {},
});
The result would be the inputs not getting wrapped multiple times when I refresh the screen or return the screen.
So I have this code from here: j360
This code is perfect for what I want: an html wich has a draggable 360º product image view, but it lacks one thing: a button for auto rotation.
I already have the button into the html, but I can't, for more that I try, to make a function or anything to make the images go by itself, and not only when I drag it over the screen.
Here is the code I have in the moment.
(function($){
$.fn.j360 = function(options) {
var defaults = {
clicked: false,
currImg: 1
}
var options = jQuery.extend(defaults, options);
return this.each(function() {
var $obj = jQuery(this);
var aImages = {};
$obj.css({
'margin-left' : 'auto',
'margin-right' : 'auto',
'text-align' : 'center',
'overflow' : 'hide'
});
$overlay = $obj.clone(true);
$overlay.html('<img src="images/loader.gif" class="loader" style="margin-top:' + ($obj.height()/2 - 15) + 'px" />');
$overlay.attr('id', 'view_overlay');
$overlay.css({
'position' : 'absolute',
'z-index': '5',
'top' : $obj.offset().top,
'left' : $obj.offset().left,
'background' : '#fff'
});
$obj.after($overlay);
$obj.after('<div id="colors_ctrls"></div>');
jQuery('#colors_ctrls').css({
'width' : $obj.width(),
'position' : 'absolute',
'z-index': '5',
'top' : $obj.offset().top + $obj.height - 50,
'left' : $obj.offset().left
});
var imageTotal = 0;
jQuery('img', $obj).each(function() {
aImages[++imageTotal] = jQuery(this).attr('src');
preload(jQuery(this).attr('src'));
})
var imageCount = 0;
jQuery('.preload_img').load(function() {
if (++imageCount == imageTotal) {
$overlay.animate({
'filter' : 'alpha(Opacity=0)',
'opacity' : 0
}, 100);
$obj.html('<img src="' + aImages[1] + '" />');
$overlay.bind('mousedown touchstart', function(e) {
if (e.type == "touchstart") {
options.currPos = window.event.touches[0].pageX;
} else {
options.currPos = e.pageX;
}
options.clicked = true;
return false;
});
jQuery(document).bind('mouseup touchend', function() {
options.clicked = false;
});
jQuery(document).bind('mousemove touchmove', function(e) {
if (options.clicked) {
var pageX;
if (e.type == "touchmove") {
pageX = window.event.targetTouches[0].pageX;
} else {
pageX = e.pageX;
}
var width_step = 50;
if (Math.abs(options.currPos - pageX) >= width_step) {
if (options.currPos - pageX >= width_step) {
options.currImg++;
if (options.currImg > imageTotal) {
options.currImg = 1;
}
} else {
options.currImg--;
if (options.currImg < 1) {
options.currImg = imageTotal;
}
}
options.currPos = pageX;
$obj.html('<img src="' + aImages[options.currImg] + '" />');
}
}
});
}
});
if (jQuery.browser.msie || jQuery.browser.mozilla || jQuery.browser.opera || jQuery.browser.safari ) {
jQuery(window).resize(function() {
onresizeFunc($obj, $overlay);
});
} else {
var supportsOrientationChange = "onorientationchange" in window,
orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
window.addEventListener(orientationEvent, function() {
onresizeFunc($obj, $overlay);
}, false);
}
onresizeFunc($obj, $overlay)
});
}
})
(jQuery)
function onresizeFunc($obj, $overlay){
$obj.css({
'margin-top' : $(document).height()/2
});
$overlay.css({
'margin-top' : 200,
'top' : $obj.offset().top,
'left' : $obj.offset().left
});
jQuery('#colors_ctrls').css({
'top' : $obj.offset().top + $obj.height - 50,
'left' : $obj.offset().left
})
}
function preload(image) {
if (typeof document.body == "undefined") return;
try {
var div = document.createElement("div");
var s = div.style;
s.position = "absolute";
s.top = s.left = 0;
s.visibility = "hidden";
document.body.appendChild(div);
div.innerHTML = "<img class=\"preload_img\" src=\"" + image + "\" />";
}
catch(e) {
// Error. Do nothing.
}
};
I need a method to increment over time a function, to make the ilusion of auto-rotate.
This plugin doesn’t seem to have this option (a kind of autoplay) so you have to code it or search an other plugin.
Since it is a list of image, you can maybe don’t use the plugin and display images one after another with jQuery and .delay()
The question is very simple but also a bit theoretical.
Let's imagine you have a long JQuery script which modifies and animate the graphics of the web site. It's objective is to handle the UI. The UI has to be responsive so the real need for this JQuery is to mix some state of visualization (sportlist visible / not visible) with some need due to Responsive UI.
Thinking from an MVC / AngularJS point of view. How should a programmer handle that?
How to refactor JS / JQuery code to implement separation of concerns described by MVC / AngularJS?
I provide an example of JQuery code to speak over something concrete.
$.noConflict();
jQuery(document).ready(function ($) {
/*variables*/
var sliderMenuVisible = false;
/*dom object variables*/
var $document = $(document);
var $window = $(window);
var $pageHost = $(".page-host");
var $sportsList = $("#sports-list");
var $mainBody = $("#mainBody");
var $toTopButtonContainer = $('#to-top-button-container');
/*eventHandlers*/
var displayError = function (form, error) {
$("#error").html(error).removeClass("hidden");
};
var calculatePageLayout = function () {
$pageHost.height($(window).height());
if ($window.width() > 697) {
$sportsList.removeAttr("style");
$mainBody
.removeAttr("style")
.unbind('touchmove')
.removeClass('stop-scroll');
if ($(".betslip-access-button")[0]) {
$(".betslip-access-button").fadeIn(500);
}
sliderMenuVisible = false;
} else {
$(".betslip-access-button").fadeOut(500);
}
};
var formSubmitHandler = function (e) {
var $form = $(this);
// We check if jQuery.validator exists on the form
if (!$form.valid || $form.valid()) {
$.post($form.attr("action"), $form.serializeArray())
.done(function (json) {
json = json || {};
// In case of success, we redirect to the provided URL or the same page.
if (json.success) {
window.location = json.redirect || location.href;
} else if (json.error) {
displayError($form, json.error);
}
})
.error(function () {
displayError($form, "Login service not available, please try again later.");
});
}
// Prevent the normal behavior since we opened the dialog
e.preventDefault();
};
//preliminary functions//
$window.on("load", calculatePageLayout);
$window.on("resize", calculatePageLayout);
//$(document).on("click","a",function (event) {
// event.preventDefault();
// window.location = $(this).attr("href");
//});
/*evet listeners*/
$("#login-form").submit(formSubmitHandler);
$("section.navigation").on("shown hidden", ".collapse", function (e) {
var $icon = $(this).parent().children("button").children("i").first();
if (!$icon.hasClass("icon-spin")) {
if (e.type === "shown") {
$icon.removeClass("icon-caret-right").addClass("icon-caret-down");
} else {
$icon.removeClass("icon-caret-down").addClass("icon-caret-right");
}
}
toggleBackToTopButton();
e.stopPropagation();
});
$(".collapse[data-src]").on("show", function () {
var $this = $(this);
if (!$this.data("loaded")) {
var $icon = $this.parent().children("button").children("i").first();
$icon.removeClass("icon-caret-right icon-caret-down").addClass("icon-refresh icon-spin");
console.log("added class - " + $icon.parent().html());
$this.load($this.data("src"), function () {
$this.data("loaded", true);
$icon.removeClass("icon-refresh icon-spin icon-caret-right").addClass("icon-caret-down");
console.log("removed class - " + $icon.parent().html());
});
}
toggleBackToTopButton();
});
$("#sports-list-button").on("click", function (e)
{
if (!sliderMenuVisible)
{
$sportsList.animate({ left: "0" }, 500);
$mainBody.animate({ left: "85%" }, 500)
.bind('touchmove', function (e2) { e2.preventDefault(); })
.addClass('stop-scroll');
$(".betslip-access-button").fadeOut(500);
sliderMenuVisible = true;
}
else
{
$sportsList.animate({ left: "-85%" }, 500).removeAttr("style");
$mainBody.animate({ left: "0" }, 500).removeAttr("style")
.unbind('touchmove').removeClass('stop-scroll');
$(".betslip-access-button").fadeIn(500);
sliderMenuVisible = false;
}
e.preventDefault();
});
$mainBody.on("click", function (e) {
if (sliderMenuVisible) {
$sportsList.animate({ left: "-85%" }, 500).removeAttr("style");
$mainBody.animate({ left: "0" }, 500)
.removeAttr("style")
.unbind('touchmove')
.removeClass('stop-scroll');
$(".betslip-access-button").fadeIn(500);
sliderMenuVisible = false;
e.stopPropagation();
e.preventDefault();
}
});
$document.on("click", "div.event-info", function () {
if (!sliderMenuVisible) {
var url = $(this).data("url");
if (url) {
window.location = url;
}
}
});
function whatDecimalSeparator() {
var n = 1.1;
n = n.toLocaleString().substring(1, 2);
return n;
}
function getValue(textBox) {
var value = textBox.val();
var separator = whatDecimalSeparator();
var old = separator == "," ? "." : ",";
var converted = parseFloat(value.replace(old, separator));
return converted;
}
$(document).on("click", "a.selection", function (e) {
if (sliderMenuVisible) {
return;
}
var $this = $(this);
var isLive = $this.data("live");
var url = "/" + _language + "/BetSlip/Add/" + $this.data("selection") + "?odds=" + $this.data("odds") + "&live=" + isLive;
var urlHoveringBtn = "/" + _language + '/BetSlip/AddHoveringButton/' + $this.data("selection") + "?odds=" + $this.data("odds") + "&live=" + isLive;
$.ajax(urlHoveringBtn).done(function (dataBtn) {
if ($(".betslip-access-button").length == 0 && dataBtn.length > 0) {
$("body").append(dataBtn);
}
});
$.ajax(url).done(function (data) {
if ($(".betslip-access").length == 0 && data.length > 0) {
$(".navbar").append(data);
$pageHost.addClass("betslipLinkInHeader");
var placeBetText = $("#live-betslip-popup").data("placebettext");
var continueText = $("#live-betslip-popup").data("continuetext");
var useQuickBetLive = $("#live-betslip-popup").data("usequickbetlive").toLowerCase() == "true";
var useQuickBetPrematch = $("#live-betslip-popup").data("usequickbetprematch").toLowerCase() == "true";
if ((isLive && useQuickBetLive) || (!isLive && useQuickBetPrematch)) {
var dialog = $("#live-betslip-popup").dialog({
modal: true,
dialogClass: "fixed-dialog"
});
dialog.dialog("option", "buttons", [
{
text: placeBetText,
click: function () {
var placeBetUrl = "/" + _language + "/BetSlip/QuickBet?amount=" + getValue($("#live-betslip-popup-amount")) + "&live=" + $this.data("live");
window.location = placeBetUrl;
}
},
{
text: continueText,
click: function () {
dialog.dialog("close");
}
}
]);
}
}
if (data.length > 0) {
$this.addClass("in-betslip");
}
});
e.preventDefault();
});
$(document).on("click", "a.selection.in-betslip", function (e) {
if (sliderMenuVisible) {
return;
}
var $this = $(this);
var isLive = $this.data("live");
var url = "/" + _language + "/BetSlip/RemoveAjax/" + $this.data("selection") + "?odds=" + $this.data("odds") + "&live=" + isLive;
$.ajax(url).done(function (data) {
if (data.success) {
$this.removeClass("in-betslip");
if (data.selections == 0) {
$(".betslip-access").remove();
$(".betslip-access-button").remove();
$(".page-host").removeClass("betslipLinkInHeader");
}
}
});
e.preventDefault();
});
$("section.betslip .total-stake button.live-betslip-popup-plusminus").click(function (e) {
if (sliderMenuVisible) {
return;
}
e.preventDefault();
var action = $(this).data("action");
var amount = parseFloat($(this).data("amount"));
if (!isNumeric(amount)) amount = 1;
var totalStake = $("#live-betslip-popup-amount").val();
if (isNumeric(totalStake)) {
totalStake = parseFloat(totalStake);
} else {
totalStake = 0;
}
if (action == "decrease") {
if (totalStake < 1.21) {
totalStake = 1.21;
}
totalStake -= amount;
} else if (action == "increase") {
totalStake += amount;
}
$("#live-betslip-popup-amount").val(totalStake);
});
toggleBackToTopButton();
function toggleBackToTopButton() {
isScrollable() ? $toTopButtonContainer.show() : $toTopButtonContainer.hide();
}
$("#to-top-button").on("click", function () { $("#mainBody").animate({ scrollTop: 0 }); });
function isScrollable() {
return $("section.navigation").height() > $(window).height() + 93;
}
var isNumeric = function (string) {
return !isNaN(string) && isFinite(string) && string != "";
};
function enableQuickBet() {
}
});
My steps in such cases are:
First of all write (at least) one controller
Replace all eventhandler with ng-directives (ng-click most of all)
Pull the view state out of the controller with ng-style and ng-class. In most of all cases ng-show and ng-hide will be sufficed
If there is code that will be used more than once, consider writing a directive.
And code that has nothing todo with the view state - put the code in a service
write unit tests (i guess there is no one until now:) )
Error message (Last line):
$("select").selectList is not a
function
Code:
(function( $ ){
$.fn.selectList = function(options) {
var settings = {
'buttonClass' : 'custom-select',
'buttonTextClass' : 'custom-select-status',
'buttonIconClass' : 'custom-select-button-icon',
'menuClass' : 'custom-select-menu',
'menuClassHidden' : 'custom-select-menu-hidden'
}
$('body').click(function() {
$('.' + settings.menuClass).each(function() {
$(this).addClass(settings.menuClassHidden);
})
});
return this.each(function() {
if (options) {
$.extend(settings, options);
}
var $this = $(this).hide(),
$menu = $('<ul></ul>').addClass(settings.menuClass)
.addClass(settings.menuClassHidden),
optionsTexts = new Array(),
currIdx;
$this.find('option').each(function(idx) {
var $opt = $(this);
if ($opt.is(':selected')) {
currIdx = idx;
}
optionsTexts[idx] = $opt.text();
})
for (var i = 0; i < optionsTexts.length; i++) {
var $item = $('<li></li>'),
$link = $('' + optionsTexts[i] + '');
if (i == currIdx) {
$item.addClass('selected');
}
$link.click(function() {
var linkIdx = $link.parent().parent().find('li').index($link.parent());
$this.find('option').eq(linkIdx).attr('selected', 'selected');
$menu.prev().find('.' + settings.buttonTextClass).text($link.text());
if ($menu.hasClass(settings.menuClassHidden)) {
$menu.removeClass(settings.menuClassHidden);
} else {
$menu.addClass(settings.menuClassHidden);
}
});
$item.append($link);
$menu.append($item);
}
$menu.insertBefore($this);
$('')
.html('<span class="'+ settings.buttonTextClass + '">'+ optionsTexts[currIdx] +'</span><span class="' + settings.buttonIconClass + '"></span>')
.addClass(settings.buttonClass)
.insertBefore($menu)
.click(function() {
$('.custom-select-menu').addClass(settings.menuClassHidden);
$menu.hasClass(settings.menuClassHidden)
? $menu.removeClass(settings.menuClassHidden)
: $menu.addClass(settings.menuClassHidden);
return false;
});
});
};
})(jQuery);
$(document).ready(function() {
if (! $('.section-admin').length > 0) {
$('select').selectList();
}
});
Could somebody help?
This works perfect.
See an working example here: Custom jQuery works
Please check if somewhere, somehow you're not initializing jQuery twice. See this answer: https://stackoverflow.com/a/33054683/1712145