How can I use constructor to write this code? - javascript

This is about ellipsis in multiple text in responsive design.
I use jQuery to do it, but I think it will be more easier to write this code, but I have no idea to do it. I need some advice.
if(responsive>1200 && responsive<1919){
$(".ellipsis-2").each(function(){
var maxwidth=15;
if($(this).text().length > maxwidth){
$(this).text($(this).text().substring(0,maxwidth));
$(this).html($(this).html()+'...');
}
console.log($(this).text().length);
});
$(".ellipsis-3").each(function(){
var maxwidth=40;
if($(this).text().length > maxwidth){
$(this).text($(this).text().substring(0,maxwidth));
$(this).html($(this).html()+'...');
}
console.log($(this).text().length);
});
}else{
$(".ellipsis-2").each(function(){
var maxwidth=23;
if($(this).text().length > maxwidth){
$(this).text($(this).text().substring(0,maxwidth));
$(this).html($(this).html()+'...');
}
console.log($(this).text().length);
});
$(".ellipsis-3").each(function(){
var maxwidth=53;
if($(this).text().length > maxwidth){
$(this).text($(this).text().substring(0,maxwidth));
$(this).html($(this).html()+'...');
}
console.log($(this).text().length);
});
}

You just need a function to simplify your code, not really a constructor. Create one for the ellipsis logic receiving the selector for the elements to be applied as well as the max width:
function applyEllipsis(selector, maxWidth){
$(selector).each(function(){
if($(this).text().length > maxWidth){
$(this).text($(this).text().substring(0,maxWidth));
$(this).html($(this).html()+'...');
}
console.log($(this).text().length);
});
}
Now you can call it inside your if statements passing the selector and max width that you need for each case:
if(responsive>1200 && responsive<1919){
applyEllipsis(".ellipsis-2",15);
applyEllipsis(".ellipsis-3",40);
}else{
applyEllipsis(".ellipsis-2",23);
applyEllipsis(".ellipsis-3",53);
}

Depending on what else is after this code you might find some use in storing your class/width values in an object array:
var ellipsisData = [
{
className: 'ellipses-2',
smallWidth: 15,
bigWidth: 23
},{
className: 'ellipses-3',
smallWidth: 23,
bigWidth: 53
}
]
Then declare your function like the other answer:
var truncateText = function(className, maxWidth) {
$("." + className).each(function() {
if($(this).text().length > maxWidth) {
$(this).text($(this).text().substring(0,maxWidth));
$(this).html($(this).html()+'...');
}
console.log($(this).text().length);
});
};
Now decide which width you want to use:
var widthKey = (responsive > 1200 && responsive < 1919) ? 'smallWidth' : 'bigWidth';
And finally iterate over your data elements and perform the function on each:
ellipsisData.forEach(function(ellipsis) {
truncateText(ellipsis.className, ellipsis[widthKey]);
});
Unnecessary probably, but I'd already written it up so I figured I'd post it.

Related

How to shorten these jQuery functions?

I have these 3 jQuery functions that basically do the same thing, but they are a tiny bit different (width of window, and class that is removed/toggled)
I need the functionality of all these 3 functions, but want to somehow combine them/shorten them into one function. I've tried to but my code keeps breaking
Can anyone help to shorten them?
Here are the 3 functions
jQuery(document).ready(function($) {
$('.exampleimg').click(function() {
$('.about').hide(600);
if (($(window).width() > 670) && ($(this).hasClass('exampleimgopen'))) {
$(this).removeClass('exampleimgopen');
} else if ($(window).width() > 670) {
$('.exampleimg').removeClass('exampleimgopen');
$(this).addClass('exampleimgopen');
}
});
});
jQuery(document).ready(function($) {
$('.exampleimg').click(function() {
$('.about').hide(600);
if (($(window).width() < 670) && ($(this).hasClass('exampleimgopen2'))) {
$(this).removeClass('exampleimgopen2');
} else if ($(window).width() < 670) {
$('.exampleimg').removeClass('exampleimgopen2');
$(this).addClass('exampleimgopen2');
}
});
});
jQuery(document).ready(function($) {
$('.exampleimg').click(function() {
$('.about').hide(600);
if (($(window).width() < 540) && ($(this).hasClass('exampleimgopen3'))) {
$(this).removeClass('exampleimgopen3');
} else if ($(window).width() < 540) {
$('.exampleimg').removeClass('exampleimgopen3');
$(this).addClass('exampleimgopen3');
}
});
});
I need the functionality of all these 3 functions, but want to somehow combine them/shorten them into one function.
Generally, a good approach when refactoring similar functions is to create a single factory function that will take your variable data as arguments and return a function that has access to that data via its closure.
function myFactory(conditionFunc, windowWidth, cssClass) {
return function() {
$('.about').hide(600);
var windowCondition = conditionFunc($(window).width(), windowWidth);
if (windowCondition && ($(this).hasClass(cssClass))) {
$(this).removeClass(cssClass);
} else if (windowCondition) {
$('.exampleimg').removeClass(cssClass);
$(this).addClass(cssClass);
}
}
}
Then you can call this function 3 times to build your functions:
// helper methods that will perform '<' or '>' on window width
var lessThan = function(a, b) { return a < b; };
var greaterThan = function(a, b) { return a > b; };
var func1 = myFactory(greaterThan, 670, 'exampleimgopen');
var func2 = myFactory(lessThan, 670, 'exampleimgopen2');
var func3 = myFactory(lessThan, 540, 'exampleimgopen3');
Which you can then pass each into their corresponding listeners.
$('.exampleimg').click(func1);
$('.exampleimg').click(func2);
$('.exampleimg').click(func3);
The advantage of doing things this way is that you only write a single function which then creates different versions of your listener callback functions, based on the data you give to it.
I think is maybe closer to what you wanted, although it's unclear what you wanted to have happen when the width was < 540. Might want to use if .. then ... else instead
jQuery(document).ready(function($) {
$('.exampleimg').click(function() {
var width = $(window).width();
var classes = [];
if (width < 540) {
classes.push('exampleimgopen3');
}
if ($(window).width() < 670) {
classes.push('exampleimgopen2');
}
if ($(window).width() >= 670) {
classes.push('exampleimgopen');
}
classes.forEach(function(class) {
$('.exampleimg').removeClass(class);
if (!$(this).hasClass(class)) {
$(this).addClass(class);
}
});
});
});

function to determine the height

Simple question
has the function:
var maxHeight = 0;
function calcHeight(el){
el.each(function(){
if(maxHeight < el.find('.products-title').outerHeight(true)){
maxHeight = el.find('.products-title').height();
}
});
el.find('.products-title').css('height',maxHeight);
}
calcHeight($('.mini-products-list > li'));
but the record is not found the maximum height,but this function works:
$('.mini-products-list > li').each(function(){
if(maxHeight < $(this).find('.products-title').outerHeight(true)){
maxHeight = $(this).find('.products-title').height();
}
});
$('.mini-products-list > li').find('.products-title').css('height',maxHeight);
The question is why is this happening and what record is correct using the function?
You are not using this to refer current element in function. There you are referring with el, so every time it will just determine for first element.
Use this there also like bellow.
el.each(function(){
if(maxHeight < $(this).find('.products-title').outerHeight(true)){
maxHeight = $(this).find('.products-title').height();
}
});

Javascript parameter help needed

I've this function:
$(function() {
$(window).scroll(function(e) {
var sl = $(this).scrollLeft();
var lbl = $("#waypoints");
if (sl > 0) {
lbl.show('');
}
else {
lbl.hide();
}
if (sl > 750) {
lbl.html("<p>now passed 750</p>");
}
if (sl > 1000) {
lbl.html("<p>now passed 1000</p>");
}
});
});
Which work when i scroll the browser window. But I need to adjust it, so that it is set for a div (#main) which scrolls inside another div (.content) which has a fixed width and css overflow enabled.
I've tried $(#main).scroll(function(e) { no joy ...
thanks for reading, any help would be awesome.
Try to change to class:
$(function() {
$('.content').scroll(function(e) {
var sl = $(this).scrollLeft();
var lbl = $("#waypoints");
if (sl > 0) {
lbl.show();
}
else {
lbl.hide();
}
if (sl > 750) {
lbl.html("<p>now passed 750</p>");
}
if (sl > 1000) {
lbl.html("<p>now passed 1000</p>");
}
});
});​
Here's a JSFiddle
I don't see what's the problem here - it's working (I mean the scroll events are fired, as you can see by scrollLeft value that is changing) http://jsfiddle.net/DTKeX/2/

How can I say "if width > height" then "do this" with jQuery?

I have a few elements. The number of them on the page changes constantly, keep that in mind.
The element is called .portalimg. I need to say if the width > height, set it's width to 125px. If the height > width, set the height to 125px.
Here's what I have:
$('.portalimg').each(function() {
var pimgw = $(this).width();
var pimgh = $(this).height();
if (pimgw > pimgh) {
$(this).css('width','125px')
} else {
$(this).css('height','125px')
}
});
EDIT: It alerts success but doesn't apply the width & height.
Where did I go wrong?
EDIT 2: Updated code with cleanest from below. That still only constrains the height property, even if the images is taller then it is wide. Take a look:
http://jacksongariety.com/gundoglabs/
EDIT 3: The issue is they all return 0. If I have an alert say the value of pimgw or pimgh, it's always 0.
EDIT 4: Finally got the best, cleanest code possible with caching and it'll always load correctly, even if it draws images form the cache:
$(function(){
$('.portalimg').ready(function(){
$('.portalimg').fadeTo(0,1).each(function(index) {
var a = $(this);
if (img.width() > a.height()) {
a.css('width','135px')
} else {
a.css('height','125px')
}
});
});
});
If there are multiple elements of class portalimg you could simply use a .each iterator: http://api.jquery.com/each/
$(function() {
$('.portalimg').each(function(index) {
var img = $(this);
if (img.width() > img.height()) {
img.css('width','125px')
} else {
img.css('height','125px')
}
});
}
$('.portalimg').each(function() {
var pimgw = $(this).width();
var pimgh = $(this).height();
if (pimgw > pimgh) {
$(this).css('width','125px')
} else {
$(this).css('height','125px')
}
});
How about this:
$('.portalimg').each(function() {
(($(this).width() > $(this).height())
&& ($(this).css('width','125px')) )
|| ($(this).css('height','125px'))
});
http://jsfiddle.net/DerekL/Qx4jF/
Your loop is wrong you should use
pimg = $('.portalimg').each( function() {;
alert("success")
var pimgw = $(this).width();
var pimgh = $(this).height();
if (pimgw > pimgh) {
$(this).css('width','125px')
} else {
$(this).css('height','125px')
}
});
This call a function on all find object with the class '.portalimg' in your document.
$('.portalimg').each(function() { var
img = $(this),
w = img.width(),
h = img.height(),
toModify = w > h ? 'width' : 'height';
img.css(toModify, '125px');
}
Might try this. Other answers are excellent to. You went wrong with the syntax of for and with body. Did you mean #body or .body?
$(".portalimg").each(function(){
var pimgw = $(this).width(),
pimgh = $(this).height();
if (pimgw > pimgh) {
$(this).css('width','125px')
}else{
$(this).css('height','125px')
}
});

How to check if a DIV is scrolled all the way to the bottom with jQuery

I have a div with overflow:scroll.
I want to know if it's currently scrolled all the way down. How, using JQuery?
This one doesn't work: How can I determine if a div is scrolled to the bottom?
Here is the correct solution (jsfiddle). A brief look at the code:
$(document).ready(function () {
$('div').on('scroll', chk_scroll);
});
function chk_scroll(e) {
var elem = $(e.currentTarget);
if (elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight()) {
console.log("bottom");
}
}
See this for more info.
function isScrolledToBottom(el) {
var $el = $(el);
return el.scrollHeight - $el.scrollTop() - $el.outerHeight() < 1;
}
This is variation of #samccone's answer that incorporates #HenrikChristensen's comment regarding subpixel measurements.
Since it works without jQuery like that :
var isBottom = node.scrollTop + node.offsetHeight === node.scrollHeight;
I do :
var node = $('#mydiv')[0]; // gets the html element
if(node) {
var isBottom = node.scrollTop + node.offsetHeight === node.scrollHeight;
}
You can do that by
(scrollHeight - scrollTop()) == outerHeight()
Apply required jQuery syntax, of course...
Here is the code:
$("#div_Id").scroll(function (e) {
e.preventDefault();
var elem = $(this);
if (elem.scrollTop() > 0 &&
(elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight())) {
alert("At the bottom");
}
});
Since 2012 Firefox contains the scrollTopMax property. If scrollTop === scrollTopMax you're at the bottom of the element.
Without jquery, for onScroll event
var scrollDiv = event.srcElement.body
window.innerHeight + scrollDiv.scrollTop == scrollDiv.scrollHeight
For me $el.outerHeight() gives the wrong value (due to the border width), whereas $el.innerHeight() gives the correct one, so I use
function isAtBottom($el){
return ($el[0].scrollHeight - $el.scrollTop()) == $el.innerHeight();
}

Categories