Jquery - Dynamic button, can I clean this up? - javascript

I created a button that will randomly appear on the screen (per my boss's request) that when clicked will open an email in order to provide feedback.
My goal is to make this script do everything, mainly so I don't have to access the ASP markup or CSS files for each website. Just throw the script in the header and place the image in the folder.
I created the script to:
Create a div that contains the button
set the CSS for the elements of that div (there will be a little image next to some text)
appear to the user at random
The script I came up with works fine, however, I was wondering if there was anyway I can clean this up at all. (I'm kind of new to writing my own Jquery scripts and I'm trying to learn how to be as organized as possible.)
Jquery:
$(function () {
var fbContainer = $('<div id="feedback"><img src="image.gif" /> Feedback</div>')
.css({
'display': 'none',
});
$('#header').append(fbContainer);
$('#feedback a').css({
'font-family': 'arial',
'float': 'left',
'text-decoration': 'none',
'color':'#000000'
});
$('#feedback img').css({
'float': 'left',
'margin': '3px 5px 0 0';
});
var randofactor = .5;
var randomizer = Math.random();
if (randomizer < randofactor) {
fbContainer.css('display', 'block');
}
});
Thanks for any assistance

You could try encapsulating your code inside a javascript object, which I would recommend placing inside a separate file. I would suggest moving the header where the button is placed to be parametrized inside a constructor function, so you can reuse it elsewhere.
Separating the various logical parts such as object creation and styling into their own functions also helps readability of your code.
<script type="text/javascript">
var randomFeedBackButton = {
getfbContainer: function (header,feedBackAddress) {
var fbContainer = $('<div id="feedback"><img src="image.gif" /> <a href=' + feedBackAddress + '>Feedback</a></div>')
.css({
'display': 'none'
});
header.append(fbContainer);
return fbContainer;
},
generateCss: function () {
$('#feedback a').css({
'font-family': 'arial',
'float': 'left',
'text-decoration': 'none',
'color': '#000000'
});
$('#feedback img').css({
'float': 'left',
'margin': '3px 5px 0 0'
});
},
initialize: function (header) {
var container = this.getfbContainer(header, "mailto:feedback#mywebaddress.com");
this.generateCss();
var randofactor = .5;
var randomizer = Math.random();
if (randomizer < randofactor) {
container.css('display', 'block');
}
}
};
$(function () {
randomFeedBackButton.initialize($('#header')); /*call your script*/
});
</script>

Related

JS image resize compatible with fullPage.js

I am trying to integrate this code : http://codepen.io/babybackart/pen/GZPjJd on a section of a website using fullpage.js.
This code is based on a previous question brilliantly answered by #Seika85 : Make a .div act like an image.
The aim was to "contain" and resize the image on its container ".plancheBox" without cuting it.
In this example, the cat picture's dimensions are driven by the container using this first javascript code:
var calculateImageDimension = function() {
$('.plancheBox img').each(function() {
var $img = $(this),
$plancheBox = $img.closest('.plancheBox');
$img.css({
'max-height': $plancheBox.height() + 2,
/* (+2px) prevent thin margins due to rendering */
'max-width': $plancheBox.width()
});
$img.closest('.container').css({
'position': 'relative'
});
});
}
calculateImageDimension();
In order to set these dimensions instantaneously (without a page refresh), I am using this second javascript code:
var resizeEnd;
$(window).on('resize', function() {
clearTimeout(resizeEnd);
resizeEnd = setTimeout(function() {
$(window).trigger('resize-end');
}, 200);
});
$(window).on('resize-end', function() {
$('.plancheBox img').css({
'max-height': 'none',
'max-width': 'none'
})
$('.plancheBox .container').css({
'position': ''
});
calculateImageDimension();
});
As you can see in the first example, it works without fullpage.js.
I managed to insert the first JS code in a fullpage.js website : http://codepen.io/babybackart/pen/ONrbEN but I don't really manage to insert the second one.
I'm not actually a JS coder so I wanted to know what I needed to do to insert this code, if it was possible to do this with fullpage.js and if there were any conflict between both codes.
Thank you for your answer !
The second JS code must be inserted in a fullPage event like this:
$(document).ready(function() {
$('#fullpage').fullpage({
//events
afterResize: function(){
$('.plancheBox img').css({
'max-height' : 'none',
'max-width' : 'none'
})
$('.plancheBox .conteneur').css({'position' : ''});
calculateImageDimension();
}
});
});

jQuery Button Only Works Once

My goal was to create a simple button which once clicked would hide/show a navigational menu, and change the footer's padding alternatively, I'd have used toggle() if not for the latter condition. How do I make the button serve both purposes, that is first hide the menu and decrease footer padding, and then upon another click show the menu and increase the padding, and so forth, so that upon clicking the button one effect would occur and upon another click the other? Any help, suggestions, or alternatives, will be much appreciated.
function collapseOrCondense(event) {
if ($('#block-panels-mini-footer-nice-menu:visible')) {
$('#footer').css({
'padding-bottom': '2.5%'
});
$('#block-panels-mini-footer-nice-menu').hide();
} else {
$('#footer').css({
'padding-bottom': '5.5%'
});
$('#block-panels-mini-footer-nice-menu').show();
}
};
$('#footer').append('<button type=button class=cbutton>*</button>');
$('#footer .cbutton').css({
'position': 'absolute',
'left': '1%',
'top': '1%',
'width': '2%',
'height': '1.5%'
});
$('#footer .cbutton').on('click', collapseOrCondense);
I have made an example here. http://jsfiddle.net/wdakLfcc/2/
var visible = true;
function collapseOrCondense(event) {
if (visible) {
$('#footer').css({
'padding-bottom': '2.5%'
});
$('#block-panels-mini-footer-nice-menu').hide();
visible = false;
} else {
$('#footer').css({
'padding-bottom': '5.5%'
});
$('#block-panels-mini-footer-nice-menu').show();
visible = true;
}
};
$('#footer').append('<button type=button class=cbutton>*</button>');
$('#footer .cbutton').css({
'position': 'absolute',
'left': '1%',
'top': '1%',
'width': '2%',
'height': '1.5%'
});
$('#footer ').on('click', '.cbutton', collapseOrCondense);
On button click different effect will be played - Collapse Or Condense.
It looks like from my analysis that your conditional is always evaluating to true. I propose you add some other form of indicator to better distinguish the toggle.
I jury rigged a simple implementation: http://plnkr.co/edit/y8BugzI89s0i5kxM95H9?p=preview
function collapseOrCondense(event){
if($('#block-panels-mini-footer-nice-menu').css('display') === 'block'){
$('#footer').css({'padding-bottom':'2.5%'});
$('#block-panels-mini-footer-nice-menu').hide();
}
else{
$('#footer').css({'padding-bottom':'5.5%'});
$('#block-panels-mini-footer-nice-menu').show();
}
}
The aforementioned snippet is one way of handling this case given my demo environment -- I am sure there are many ways but the underlying problem is your condition (at least in my scenario with the data provided) is always evaluating to true.
The problem is in this line you have:
if ($('#block-panels-mini-footer-nice-menu:visible')) {
Because that will return a jQuery object with one or zero elements inside. You could fix that by adding .length. But I think using the is function is more clear.
Here I fixed that, and applied some changes that may help you to do the same in a more concise manner:
function collapseOrCondense(event) {
var menu = $('#block-panels-mini-footer-nice-menu');
$('#footer').css({
'padding-bottom': menu.is(':visible') ? '2.5%' : '5.5%'
});
menu.toggle();
}
$('<button type=button class=cbutton>*</button>').css({
'position': 'absolute',
'left': '1%',
'top': '1%',
'width': '2%',
'height': '1.5%'
}).on('click', collapseOrCondense).appendTo('#footer');
Working fiddle: http://jsfiddle.net/yj5evps2/

jQuery plugin overwrite all css or only some attributes

I'm creating a simple jQuery plugin for my web app. Right now i'm adding a 'settings' option, which can be used to change the default CSS for the selected elements:
Html
<script type="text/javascript">
var mycss = {tagNormalStyle: {backgroundColor: '#ddd', color:'#222'}};
$(document).ready(function(){
$("#tag1").tagme(mycss);
$("#tag2").tagme(null);
});
</script>
jQuery plugin
$.fn.tagme = function(options) {
// some defaults
var settings = $.extend({
tagNormalStyle:{
backgroundColor: 'black',
color: 'white',
marginLeft: '5px',
marginTop: '5px',
padding: '5px',
float: 'left',
borderRadius: '5px'
},
//more stuff here...,
options
};
}
In my code, i'm using something like:
if (condition)
tag.css = settings.tagNormalStyle;
The problem is, what if the user only needs to change the color, for example?
var mycss = {tagNormalStyle: {color:'#222'}};
$("#tag1").tagme(mycss);
Now all the defaults are gone for tagNormalStyle! How can i avoid to 'hard-code' every css property on my settings object? Maybe i could 'merge' the defaults and options objects.
Any ideas?
Thanks!
pass true as the first parameter to the extend function.
something like:
$.extend(true,obj1,obj2)

How to finish a setTimeout function when mouseenter on another function?

At http://jsfiddle.net/builtbymay/Wge4n/4/, mouse over the Basecamp call-to-action button and then move your mouse to the left of your browser window. You will notice that the heading changes back after a delay of 1000ms. Nice! Now mouse over it again, but this time move your mouse over Highrise. Not nice!
I'm thinking I need to speed up the delay that occurred when mousing over the Basecamp button. clearTimeout didn't work for me. Any help would be appreciated. Thanks!
$(document).ready(function() {
var delay = 1000;
$('.products .bc').on('mouseenter', function() {
$('header').addClass('hidden');
$('.bc:first').removeClass('hidden').css({
'clear': 'both',
'width': '829px',
'height': '163px',
'margin': '0 auto',
'padding': '6px 0',
'text-align': 'center',
'font-family': '"CrimsonSemiBold", "Times New Roman", Georgia, serif',
});
// Added bc:first to prevent styles being added to other .bc classes.
$('.bc:first h1, .bc:first p').css('padding', '18px 0 0');
// Adjusting vertical layout so red arrow more closely matches location on 37signals.com.
$('.bc:last').css('box-shadow', '0 0 10px #333');
});
$('.products .bc').on('mouseleave', function() {
setTimeout(function() {
$('header').removeClass('hidden');
$('.bc:first').addClass('hidden').removeAttr('style');
$('.bc:last').removeAttr('style');
}, delay);
});
$('.products .hr').on('mouseenter', function() {
$('header').addClass('hidden');
$('.hr:first').removeClass('hidden').css({
'clear': 'both',
'width': '829px',
'height': '163px',
'margin': '0 auto',
'padding': '6px 0',
'text-align': 'center',
'font-family': '"CrimsonSemiBold", "Times New Roman", Georgia, serif',
});
$('.hr:first h1, .hr:first p').css('padding', '18px 0 0');
$('.hr:last').css('box-shadow', '0 0 10px #333');
$('.right-arrow-b').removeClass('right-arrow-b').css({
'left': '80px',
'position': 'relative',
'z-index': '1'
});
});
$('.products .hr').on('mouseleave', function() {
setTimeout(function() {
$('header').removeClass('hidden');
$('.hr:first').addClass('hidden').removeAttr('style');
$('.hr:last').removeAttr('style');
$('.right-arrow-b').addClass('right-arrow-b').removeAttr('style');
}, delay);
});
$('.products .cf').on('mouseenter', function() {
$('header').addClass('hidden');
$('.cf:first').removeClass('hidden').css({
'clear': 'both',
'width': '829px',
'height': '163px',
'margin': '0 auto',
'padding': '6px 0',
'text-align': 'center',
'font-family': '"CrimsonSemiBold", "Times New Roman", Georgia, serif',
});
$('.cf:first h1, .cf:first p').css('padding', '18px 0 0');
$('.cf:last').css('box-shadow', '0 0 10px #333');
$('.left-arrow').removeClass('left-arrow').css({
'left': '150px',
'position': 'relative',
'z-index': '1'
});
});
$('.products .cf').on('mouseleave', function() {
setTimeout(function() {
$('header').removeClass('hidden');
$('.cf:first').addClass('hidden').removeAttr('style');
$('.cf:last').removeAttr('style');
$('.left-arrow').addClass('left-arrow').removeAttr('style');
}, delay);
});
});
FYI: The CSS and HTML was borrowed from another classmate. My task was to get the behaviors to reflect those on 37signals.com, without editing any HTML and CSS in the process. There is a lot of css manipulation happening—just ignore it. My last task is to get the above issue resolved. Thanks!
Try this fiddle. I made a separate function to perform the functions of mouseleave event. On mouseenter of one button performs the function of mouseleave of other 2 buttons. In addition I keep an array of IDs of setTimeout. And in the previously mentioned function I also clear all the timers.
Define a global variable wich holds the timer
var globalTimer = null;
above the $(document).ready(function() ..., it's important that this var is not defined within a method.
Now assign the timeout to this var and check if its set and if it needs to be cleared in all your methods.
if(gloabalTimer != null) window.clearTimeout(gloabalTimer);
globalTimer = window.setTimeout(function() {
//Your actions
}), delay);

Open page from bookmarklet, but, make it like a modal window?

I am using a bookmarklet which can (obviously) be called by the user anywhere:
javascript:(function(){window.open('http://*****.com/***.html?url=
'+encodeURIComponent(window.location.href),'my_page_name',
'left=200,top=200,width=480,height=500,personalbar=0,
toolbar=0,scrollbars=1,resizable=1')})()
How can I make this like a modal window, meaning no ugly browser window borders - should I use jquery or something like in the bookmarklet URL and if so, how?
You could use the approach Firebug Lite uses.
Basically you insert an external JS file into your page when you click on the bookmark.
My bookmark
Just change BASE_URL, PATH_TO_JS and PATH_TO_ICON to what you need it to be.
Also, don't forget the "http://" in the BASE_URL, unless you want to use a relative path.
Your external JS file could contain a script which adds an element to the page which hovers over others. I recommend using the CSS in Twitter Bootstrap to figure out how to make a reliable modal window.
Edit --
To help you out I wrote a small demo. It consists of 2 files:
bookmark.html - adapted firebug code to create bookmark which adds script dynamically
bookmark.js - creates a modal with an iframe
bookmark.html
Bookmark
bookmark.js
(function() {
var script;
if(!window.jQuery) {
script = document.createElement("script");
script.type = "text/javascript";
script.src = "https://ajax.googleapis.com/ajax/libs/jquery/1.7.0/jquery.min.js";
document.body.appendChild(script);
}
(function check_if_loaded() {
if(!window.jQuery) {
setTimeout(check_if_loaded, 50);
} else {
(function($) {
var
$dark_bg = $('<div></div>').css({'z-index': '1000', 'background-color': '#000000', 'opacity': '0', 'position': 'absolute', 'width': '100%', 'height': '100%'}),
$iframe = $('<iframe></iframe>').css({'width': '100%', 'height': '100%', 'border': 1, 'overflow': 'hidden'}).prop({'src': 'http://bijtel.com/cv/', 'width': '100%', 'height': '100%', 'scrolling': 'no'}),
$close = $('<div></div>').css({'position': 'absolute', 'top': 0, 'right': 0, 'padding': '5px 10px', 'cursor': 'pointer', 'color': '#ffffff', 'font-size': '10pt', 'font-family': 'verdana'}).html('close Ă—');
$modal = $('<div></div>').css({'z-index': '1010', 'background-color': '#ffffff', 'opacity': '0', 'position': 'absolute', 'top': '10%', 'left': '10%', 'width': '80%', 'height': '80%', 'box-shadow': '7px 7px 5px #333'}).append($close, $iframe);
$('body').css({'padding': 0, 'margin': 0}).prepend($dark_bg, $modal);
$dark_bg.animate({'opacity':0.5}, 400);
$modal.animate({'opacity':1}, 400);
$close.on('click', function() {
$dark_bg.animate({'opacity': 0}, 400, function(){ $dark_bg.remove(); });
$modal.animate({'opacity': 0}, 400, function(){ $modal.remove(); });
});
}(window.jQuery));
}
}());
}());
Demo at: http://bijtel.com/stackoverflow/bookmark/
I don't know much about the subject, but looking at the delicious.com bookmarklet I noticed some parameters to limit which parts of the browser window will be shown:
(function() {
f = 'http://www.delicious.com/save?url=' + encodeURIComponent(window.location.href) + '&title=' + encodeURIComponent(document.title) + '&v=5&';
a = function() {
if (!window.open(f + 'noui=1&jump=doclose', 'deliciousuiv5', 'location=yes,links=no,scrollbars=no,toolbar=no,width=550,height=550')) location.href = f + 'jump=yes'
};
if (/Firefox/.test(navigator.userAgent)) {
setTimeout(a, 0)
} else {
a()
}
})()
The parameters I'm talking about are the location, links, scrollbars and toolbar. That does not make it modal, though, and I doubt there is a feature for that (I'm assuming browser windows are independent of each other). But they provide a "cleaner" window nonetheless...
Update: check out this link. Basically, what the bookmarklet does is to create a new script tag and append it to the body. I'm assuming you could do anything you want in that script, including create a jQuery dialog the way you wanted (in fact, this bookmarklet does use jQuery, but it's embedded in the script itself; see the source).
Here's the code. I wouldn't use this bookmarklet myself (since I'd have to provide my username/password in the clear), but it's a starting point for you to do yours:
var e = document.createElement('script');
e.setAttribute('language', 'javascript');
e.setAttribute('src', 'http://t.rc.vc/delicious/js/delicious.js?username=***&password=***');
e.setAttribute('id', 'delicious_submitter');
document.body.appendChild(e);
void(0);
Obs.: in both examples, I stripped the javascript: part and formatted the code for readability.

Categories