height is not a function - javascript

Im trying to build a little jQuery plugin, but im getting an error that group.height() is not a function?
(function( $ ) {
$.fn.equalHeight = function(group) {
group = $.extend(group);
var tallest = 0;
group.each(function () {
var thisHeight = $(this).height();
if (thisHeight > tallest) {
tallest = thisHeight;
}
});
group.height(tallest);
// allow jQuery chaining
return this;
};
}( jQuery ));
Usage example would be like this:
<script>
// Usage example:
$( ".boxes section.box" ).equalHeight();
</script>

Use this?
In your declaration, your equalHeight takes a parameter, but you are not passing anything through. Note that in a custom jQuery function you don't have to pass in group, because the this identifier already refers to your group.
So, either do group = this, or replace it completely

Try
(function ($) {
$.fn.equalHeight = function () {
var tallest = 0;
this.each(function () {
var thisHeight = $(this).height();
if (thisHeight > tallest) {
tallest = thisHeight;
}
});
// allow jQuery chaining
return this.height(tallest);
};
}(jQuery));
Demo: Fiddle

Related

Can I use nested jquery.proxy

Can I use nested jquery.proxy?
var obj = {
init: function(element){
element.on('click.mynamespace',$.proxy(function (event) {
$(event.currentTarget).animate({
scrollLeft: scrollPos
}, width, $.proxy(this.myFunction,this));
},this))
},
myFunction: function(){
/*some code*/
}
}
This is what I need for my project. I have used the nested $.proxy to make the code work. Because I need this context in myFunction which is a callback function for jquery animate api.
Can I use in this way?
It should work, however I'd suggest that storing a reference to the object in the outer scope would be a more elegant solution. Note the definition and use of _obj in this example:
var scrollPos = 10;
var width = 20;
var obj = {
init: function($element) {
var _obj = this;
$element.on('click.mynamespace', function(e) {
$(this).animate({
scrollLeft: scrollPos
}, width, _obj.myFunction.call(this));
});
},
myFunction: function() {
// this function now executes within the context of the
// element which has been animated in the click handler
console.log(this.id);
}
}
var $foo = $('#foo');
obj.init($foo);
$foo.trigger('click.mynamespace');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="foo"></div>

is it possible to set $(this) in function?

I want to set #first and #second as $(this) to use element id only when function is calling.
is it possible?or any other way?
(function( $ ){
$.fn.showCircle = function(top,right) {
$timeout(function () {
$(this).css({
right:right,
top:top,
});
});
};
})( jQuery );
$('#first').showCircle(300,200);
$('#second').showCircle(800,200);
You can use jQuery.proxy() to set this at a function call
$timeout($.proxy(function () {
$(this).css({
right:right,
top:top,
});
}, this));
thanks to #panther comment inside $timeout this refer to window so as #panther said I changed the function :
(function ($) {
$.fn.showCircle = function (top, right) {
var self = this;
$timeout(function () {
$(self.selector).css({
right: right,
top: top,
});
});
};
})(jQuery);

Display read more button

I want to use a read more button after a text is larger than 300 characters.
I use this jQuery to fix this, but it is not working as I want.
var $j = jQuery.noConflict();
$j('.reviewtekst').each(function() {
var $pTag = $j(this).find('p');
if($pTag.text().length > 300){
var shortText = $pTag.text();
shortText = shortText.substring(0, 300);
$pTag.addClass('fullArticle').hide();
$pTag.append('<a class="read-less-link">Lees minder</a>');
$j(this).append('<p class="preview">'+shortText+'</p><div class="curtain-shadow"></div><a class="read-more-link">Read more</a>');
}
});
$j(document).on('click', '.read-more-link', function () {
$j(this).parent().hide().prev().show();
});
$j(document).on('click', '.read-less-link', function () {
$j(this).parent().hide().next().show();
});
See this JSFiddle: https://jsfiddle.net/8cm67cun/1/
How can I make this work, to display the <a> class outside the <p> class.
Here is updated version https://jsfiddle.net/8cm67cun/2/ now it works fine with a tag outside the p
$j(document).on('click', '.read-more-link', function () {
$j(this).hide().parent().find('.preview').hide().prev().show();
});
$j(document).on('click', '.read-less-link', function () {
$j(this).parent().hide().next().show();
$j(this).parents('.reviewtekst').find('.read-more-link').show();
});

setInterval() inside plugin function not being called

I have a jQuery slideshow plugin that I am making though it has a setInterval() inside it which is not being called though if I move the contents of the setInterval() outside of the it then it works though it only runs once.
var gap = 3;
var duration = 0.5;
(function ($) {
$.fn.slideshow = function () {
return this.each(function () {
g = gap * 1000;
d = duration * 1000;
$(this).children().css({
'position': 'absolute',
'display': 'none'
});
$(this).children().eq(0).css({
'display': 'block'
});
setInterval(function () {
slide();
}, g);
function slide() {
$(this)
.children()
.eq(0)
.fadeOut(d)
.next()
.fadeIn()
.end()
.appendTo($(this).children().eq(0).parent());
}
});
};
})(jQuery);
$('.slideshow').slideshow();
HTML:
<div class='slideshow'>
<a>1</a>
<a>2</a>
<a>3</a>
<a>4</a>
</div>
Here is a fiddle with my plugin:
http://jsfiddle.net/Hive7/GrtLC/
The problem is this inside the slider function does not point to the object you think it points to.
setInterval($.proxy(function () {
slide.call(this);
}, this), g);
Demo: Fiddle
or better
setInterval($.proxy(slide, this), g);
Demo: Fiddle
Your problem is that this is always locally defined; by the time you get into the setInterval(), you've lost your original this (it's reset to the window object).
There are a few ways to get around this; the simplest is probably to copy this into a local variable.
http://jsfiddle.net/mblase75/GrtLC/5/
var gap = 3;
var duration = 0.5;
(function ($) {
$.fn.slideshow = function () {
return this.each(function () {
g = gap * 1000;
d = duration * 1000;
$this = $(this); // caches the jQuery object as a further optimization
$this.children().css({
'position': 'absolute',
'display': 'none'
});
$this.children().eq(0).css({
'display': 'block'
});
setInterval(function () {
slide($this); // pass $this into the function
}, g);
function slide($obj) {
$obj.children()
.eq(0)
.fadeOut(d)
.next()
.fadeIn()
.end()
.appendTo($obj.children().eq(0).parent());
}
});
};
})(jQuery);
$('.slideshow').slideshow();
Your code cannot work, because your callback is not bound to the this; try instead
var that = this;
setInterval(function () {
slide();
}, g);
function slide() {
$(that) ....
this inside slide function is not the slideshow. I make it work caching the object inside the each loop: http://jsfiddle.net/x7Jk8/

Get and set the height and width of elements on hover only once

On hover, the following code gets the tallest column in a submenu panel and sets all columns to the same height. It also gets the sum of the width of all columns and sets the column container width to the sum:
$(function()
{
$("#menu> li").hover(function () {
var tallestColumnHeight = 0, submenuPanelTotalWidth = 0;
$("ul.sub-menu-1 > li", this).each(function () {
tallestColumnHeight = Math.max(tallestColumnHeight, $(this).height());
submenuPanelTotalWidth += parseInt($(this).outerWidth(), 10);
}).height(tallestColumnHeight);
$("ul.sub-menu-1 > li", this).parent().width( submenuPanelTotalWidth );
});
});
Right now the code above has a lot of overhead as it gets and sets the height and width twice on each hover. I want to set some kind of flag so that the calculations only run once.
Any ideas? Is it wise to use jQuery .data() here to store the initial values once and then check if the data is set?
Any suggestions or help with this is much appreciated!
UPDATE
Replacing hover() with the mouseenter() event and using one() was the best solution.
Here is the updated code:
$(function()
{
$("#menu > li").one('mouseenter', function(e)
{
var tallestColumnHeight = 0,
submenuPanelTotalWidth = 0;
$("ul.sub-menu-1 > li", this).each(function ()
{
tallestColumnHeight = Math.max(tallestColumnHeight, $(this).height());
submenuPanelTotalWidth += parseInt($(this).outerWidth(true), 10);
}).height(tallestColumnHeight);
$("ul.sub-menu-1 > li", this).parent().width( submenuPanelTotalWidth );
});
});
You can use .one() function of jquery. Unfortunately, hover is not a real event. Instead it should be replaced as .one("mouseenter mouseleave",function()...
$("#menu> li").hover(function (){
//your code
$("#menu> li").unbind('hover')
});
Use this code, provided you dont have any other function bound to hover function. This unbind technique removes the function associated with the hover event.
You could save your eventHandler function in a variable and call unbind on the element with the saved variable. This would be more performant as the handler function won´t get executed anymore.
$(function() {
var hoverFunction = function () {
var tallestColumnHeight = 0,
submenuPanelTotalWidth = 0;
$("ul.sub-menu-1 > li", this).each(function () {
tallestColumnHeight = Math.max(tallestColumnHeight, $(this).height());
submenuPanelTotalWidth += parseInt($(this).outerWidth(), 10);
}).height(tallestColumnHeight);
$("ul.sub-menu-1 > li", this).parent().width( submenuPanelTotalWidth );
$("#menu> li").unbind('hover', hoverFunction);
};
$("#menu> li").hover();
});

Categories