I need to find a good solution to the following problem. I see a lot of people asking about tracking if an element is in or outside of view Port for the page or browser window. I need to be able to replicate this action, but inside a DIV that scrolls, with overflow:scroll for example. Does anyone know of a good example, for this specific action?
Thanks in advance.
Here's a pure javascript version of the accepted answer without relying on jQuery and with some fixes to the partial in view detection and support for out of view on top.
function checkInView(container, element, partial) {
//Get container properties
let cTop = container.scrollTop;
let cBottom = cTop + container.clientHeight;
//Get element properties
let eTop = element.offsetTop;
let eBottom = eTop + element.clientHeight;
//Check if in view
let isTotal = (eTop >= cTop && eBottom <= cBottom);
let isPartial = partial && (
(eTop < cTop && eBottom > cTop) ||
(eBottom > cBottom && eTop < cBottom)
);
//Return outcome
return (isTotal || isPartial);
}
And as a bonus, this function ensures the element is in view if it's not (partial or full):
function ensureInView(container, element) {
//Determine container top and bottom
let cTop = container.scrollTop;
let cBottom = cTop + container.clientHeight;
//Determine element top and bottom
let eTop = element.offsetTop;
let eBottom = eTop + element.clientHeight;
//Check if out of view
if (eTop < cTop) {
container.scrollTop -= (cTop - eTop);
}
else if (eBottom > cBottom) {
container.scrollTop += (eBottom - cBottom);
}
}
i had the same problem before, i have ended up with the following function.the first parameter is for the element to check, the second is to check if the element is partially in-view.it is for vertical check only, you can extend it to check for horizontal scroll.
function checkInView(elem,partial)
{
var container = $(".scrollable");
var contHeight = container.height();
var contTop = container.scrollTop();
var contBottom = contTop + contHeight ;
var elemTop = $(elem).offset().top - container.offset().top;
var elemBottom = elemTop + $(elem).height();
var isTotal = (elemTop >= 0 && elemBottom <=contHeight);
var isPart = ((elemTop < 0 && elemBottom > 0 ) || (elemTop > 0 && elemTop <= container.height())) && partial ;
return isTotal || isPart ;
}
check it on jsFiddle .
Based of the best answer. Instead of just telling you if an element is partially visible or not. I added a little extra so you can pass in a percentage (0-100) that tells you if the element is more than x% visible.
function (container, element, partial) {
var cTop = container.scrollTop;
var cBottom = cTop + container.clientHeight;
var eTop = element.offsetTop;
var eBottom = eTop + element.clientHeight;
var isTotal = (eTop >= cTop && eBottom <= cBottom);
var isPartial;
if (partial === true) {
isPartial = (eTop < cTop && eBottom > cTop) || (eBottom > cBottom && eTop < cBottom);
} else if(typeof partial === "number"){
if (eTop < cTop && eBottom > cTop) {
isPartial = ((eBottom - cTop) * 100) / element.clientHeight > partial;
} else if (eBottom > cBottom && eTop < cBottom){
isPartial = ((cBottom - eTop) * 100) / element.clientHeight > partial;
}
}
return (isTotal || isPartial);
}
I was able to make this work by making a small change to the pure javascript version posted
function checkInView(container, element, partial) {
//Get container properties
let cTop = container.scrollTop;
let cBottom = cTop + container.clientHeight;
//Get element properties
let eTop = element.offsetTop - container.offsetTop; // change here
let eBottom = eTop + element.clientHeight;
//Check if in view
let isTotal = (eTop >= cTop && eBottom <= cBottom);
let isPartial = partial && (
(eTop < cTop && eBottom > cTop) ||
(eBottom > cBottom && eTop < cBottom)
);
//Return outcome
return (isTotal || isPartial);
}
Played around with it for my purposes. Here is my solution (vanilla)
Menu is the container, el is the active element.
const isVisible = (menu, el) => {
const menuHeight = menu.offsetHeight;
const menuScrollOffset = menu.scrollTop;
const elemTop = el.offsetTop - menu.offsetTop;
const elemBottom = elemTop + el.offsetHeight;
return (elemTop >= menuScrollOffset &&
elemBottom <= menuScrollOffset + menuHeight);
}
Here is a pure javascript solution.
function elementIsVisible(element, container, partial) {
var contHeight = container.offsetHeight,
elemTop = offset(element).top - offset(container).top,
elemBottom = elemTop + element.offsetHeight;
return (elemTop >= 0 && elemBottom <= contHeight) ||
(partial && ((elemTop < 0 && elemBottom > 0 ) || (elemTop > 0 && elemTop <= contHeight)))
}
// checks window
function isWindow( obj ) {
return obj != null && obj === obj.window;
}
// returns corresponding window
function getWindow( elem ) {
return isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;
}
// taken from jquery
// #returns {{top: number, left: number}}
function offset( elem ) {
var docElem, win,
box = { top: 0, left: 0 },
doc = elem && elem.ownerDocument;
docElem = doc.documentElement;
if ( typeof elem.getBoundingClientRect !== typeof undefined ) {
box = elem.getBoundingClientRect();
}
win = getWindow( doc );
return {
top: box.top + win.pageYOffset - docElem.clientTop,
left: box.left + win.pageXOffset - docElem.clientLeft
};
};
I made a jquery plugin with the last answer:
(function($) {
$.fn.reallyVisible = function(opt) {
var options = $.extend({
cssChanges:[
{ name : 'visibility', states : ['hidden','visible'] }
],
childrenClass:'mentioners2',
partialview : true
}, opt);
var container = $(this);
var contHeight;
var contTop;
var contBottom;
var _this = this;
var _children;
this.checkInView = function(elem,partial){
var elemTop = $(elem).offset().top - container.offset().top;
var elemBottom = elemTop + $(elem).height();
var isTotal = (elemTop >= 0 && elemBottom <=contHeight);
var isPart = ((elemTop < 0 && elemBottom > 0 ) || (elemTop > 0 && elemTop <= container.height())) && partial ;
return isTotal || isPart ;
}
this.bind('restoreProperties',function(){
$.each(_children,function(i,elem){
$.each(options.cssChanges,function(i,_property){
$(elem).css(_property.name,_property.states[1]);
});
});
_children = null;
});
return this.each(function(){
contHeight = container.height();
contTop = container.scrollTop();
contBottom = contTop + contHeight ;
_children = container.children("."+options.childrenClass);
$.each(_children,function(i,elem){
var res = _this.checkInView(elem,options.partialview);
if( !res ){
$.each(options.cssChanges,function(i,_property){
$(elem).css(_property.name,_property.states[0]);
});
}
});
});
}
})(jQuery);
You can try this
function isScrolledIntoView(elem) {
var docViewTop = $(window).scrollTop();
var docViewBottom = docViewTop + window.innerHeight;
var el = $(elem);
var elemTop = el.offset().top;
var elemBottom = elemTop + el.height();
var elemDisplayNotNone = el.css("display") !== "none";
return ((elemBottom <= docViewBottom) && (elemTop >= docViewTop) && elemDisplayNotNone);
}
eg:
isScrolledIntoView('#button')
Related
I need your help because I've been on a project for hours and can't make any headway. An "animated" counter is to be installed on our website. This shows, for example, the monthly cost savings. The following code works great so far.
<script>
/* <![CDATA[ */
var ersparnis = 4600;
var inv = setInterval(function() {
if(ersparnis < 4800)
document.getElementById("counter_ersparnis").innerHTML = ++ ersparnis;
else
clearInterval(inv);
}, 500 / 100);
/*]]>*/
</script>
<h2>
+ <span id="counter_ersparnis"></span> €
</h2>
But now I want the Javascript to start only when the user scrolls to the relevant point. I have now tried to do this with a jQuery code from the Internet, but without success!
<script>
/* <![CDATA[ */
jQuery.fn.isOnScreen = function()
{
var win = jQuery(window);
var viewport = {
top : win.scrollTop(),
left : win.scrollLeft()
};
viewport.right = viewport.left + win.width();
viewport.bottom = viewport.top + win.height();
var bounds = this.offset();
bounds.right = bounds.left + this.outerWidth();
bounds.bottom = bounds.top + this.outerHeight();
return (!(viewport.right < bounds.left || viewport.left > bounds.right || viewport.bottom < bounds.top || viewport.top > bounds.bottom));
};
jQuery(window).scroll(function()
{
if(jQuery('#element').isOnScreen())
{
var ersparnis = 4600;
var inv = setInterval(function() {
if(ersparnis < 4800)
document.getElementById("counter_ersparnis").innerHTML = ++ ersparnis;
else
clearInterval(inv);
}, 500 / 100);
/*]]>*/
</script>
<h2>
+ <span id="counter_ersparnis"></span> €
</h2>
} }
By the way, the whole thing should be implemented on a Jimdo site, so I also added the database with the following code in the head area.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js" type="text/javascript"></script>
You might hear it already, I'm not really familiar with CSS / HTML and Javascript. So it would be great if someone could offer me a plug and play solution. I usually get it rewritten, but not tinkered together (because I want three of these counters next to each other.
Try This im not a big proponent of jquery so its plain JavaScript.
const targetElement = document.querySelector('#element');
let isCounting = false;
var inv;
document.addEventListener('scroll', function(e) {
const bounding = targetElement.getBoundingClientRect();
if (
bounding.top >= 0 &&
bounding.left >= 0 &&
bounding.right <= (window.innerWidth || document.documentElement.clientWidth) &&
bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight)
) {
if(!isCounting ){
var ersparnis = 4600;
inv = setInterval(function() {
document.getElementById("counter_ersparnis").innerHTML = ++ ersparnis;
}, 500 / 100);
isCounting = true;
}
}else{
isCounting = false;
clearInterval(inv);
}
});
To make the code a bit cleaner and reuseable you could do this.
const targetElement = document.querySelector('#element');
let isCounting = false;
let inv;
const isVisible = function (elem) {
var bounding = elem.getBoundingClientRect();
return (
bounding.top >= 0 &&
bounding.left >= 0 &&
bounding.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
bounding.right <= (window.innerWidth || document.documentElement.clientWidth)
);
};
function startCounter(){
var ersparnis = 4600;
inv = setInterval(function() {
document.getElementById("counter_ersparnis").innerHTML = ++ ersparnis;
}, 500 / 100);
isCounting = true;
}
function stopCounter(){
clearInterval(inv);
isCounting = false;
}
document.addEventListener('scroll', function(e) {
const visible = isVisible( targetElement );
if( visible && !isCounting ){
startCounter();
}else if( !visible && isCounting ){
stopCounter();
}
});
You can use Intersection Observer API to observe changes in the intersection of a target element with an ancestor element or with a top-level document's viewport:
let options = {
root: null, //--> viewport if it is null
rootMargin: '0px',
threshold: 1.0
}
const callback = function(entries, observer) {
entries.forEach(entry => {
let ersparnis = 4600;
const inv = setInterval(function() {
if (ersparnis < 4800)
entry.target.innerHTML = ++ersparnis;
else
clearInterval(inv);
}, 500 / 100);
});
};
let observer = new IntersectionObserver(callback, options);
const target = document.querySelector('#counter_ersparnis');
observer.observe(target);
I was looking into one of the only few full page scroll codes which I have found so far, and wanted to somehow get the idea of what I should do by reversing the engineering but I'm noob and not good at understanding it pretty well, I don't understand it well and I get stock at every line, can you please explain to me what the guy has done? Whats the basics of what he is doing ..variables and functions and what they are in this case and why we need them? A summary on what is going on.
this is the link to the code
https://codepen.io/igstudio/pen/pbYOab
this is the JS code
(function() {
"use strict";
/*[pan and well CSS scrolls]*/
var pnls = document.querySelectorAll('.panel').length,
scdir, hold = false;
function _scrollY(obj) {
var slength, plength, pan, step = 100,
vh = window.innerHeight / 100,
vmin = Math.min(window.innerHeight, window.innerWidth) / 100;
if ((this !== undefined && this.id === 'well') || (obj !== undefined && obj.id === 'well')) {
pan = this || obj;
plength = parseInt(pan.offsetHeight / vh);
}
if (pan === undefined) {
return;
}
plength = plength || parseInt(pan.offsetHeight / vmin);
slength = parseInt(pan.style.transform.replace('translateY(', ''));
if (scdir === 'up' && Math.abs(slength) < (plength - plength / pnls)) {
slength = slength - step;
} else if (scdir === 'down' && slength < 0) {
slength = slength + step;
} else if (scdir === 'top') {
slength = 0;
}
if (hold === false) {
hold = true;
pan.style.transform = 'translateY(' + slength + 'vh)';
setTimeout(function() {
hold = false;
}, 1000);
}
console.log(scdir + ':' + slength + ':' + plength + ':' + (plength - plength / pnls));
}
/*[swipe detection on touchscreen devices]*/
function _swipe(obj) {
var swdir,
sX,
sY,
dX,
dY,
threshold = 100,
/*[min distance traveled to be considered swipe]*/
slack = 50,
/*[max distance allowed at the same time in perpendicular direction]*/
alT = 500,
/*[max time allowed to travel that distance]*/
elT, /*[elapsed time]*/
stT; /*[start time]*/
obj.addEventListener('touchstart', function(e) {
var tchs = e.changedTouches[0];
swdir = 'none';
sX = tchs.pageX;
sY = tchs.pageY;
stT = new Date().getTime();
//e.preventDefault();
}, false);
obj.addEventListener('touchmove', function(e) {
e.preventDefault(); /*[prevent scrolling when inside DIV]*/
}, false);
obj.addEventListener('touchend', function(e) {
var tchs = e.changedTouches[0];
dX = tchs.pageX - sX;
dY = tchs.pageY - sY;
elT = new Date().getTime() - stT;
if (elT <= alT) {
if (Math.abs(dX) >= threshold && Math.abs(dY) <= slack) {
swdir = (dX < 0) ? 'left' : 'right';
} else if (Math.abs(dY) >= threshold && Math.abs(dX) <= slack) {
swdir = (dY < 0) ? 'up' : 'down';
}
if (obj.id === 'well') {
if (swdir === 'up') {
scdir = swdir;
_scrollY(obj);
} else if (swdir === 'down' && obj.style.transform !== 'translateY(0)') {
scdir = swdir;
_scrollY(obj);
}
e.stopPropagation();
}
}
}, false);
}
/*[assignments]*/
var well = document.getElementById('well');
well.style.transform = 'translateY(0)';
well.addEventListener('wheel', function(e) {
if (e.deltaY < 0) {
scdir = 'down';
}
if (e.deltaY > 0) {
scdir = 'up';
}
e.stopPropagation();
});
well.addEventListener('wheel', _scrollY);
_swipe(well);
var tops = document.querySelectorAll('.top');
for (var i = 0; i < tops.length; i++) {
tops[i].addEventListener('click', function() {
scdir = 'top';
_scrollY(well);
});
}
})();
Thanks.
I was trying to do a full page scroll while using anchor links throughout the page but sometimes it won't scroll up anymore or the links stop working or go to the wrong places. It gets pushed down leaving strange white space after I scroll around an press on the links.
Link to code:
https://codepen.io/serelath/pen/NEzyxL
I appreciate it if anyone can look into this for me.
(function() {
"use strict";
/*[pan and well CSS scrolls]*/
var pnls = document.querySelectorAll('.panel').length,
scdir, hold = false;
function _scrollY(obj) {
var slength, plength, pan, step = 100,
vh = window.innerHeight / 100,
vmin = Math.min(window.innerHeight, window.innerWidth) / 100;
if ((this !== undefined && this.id === 'well') || (obj !== undefined && obj.id === 'well')) {
pan = this || obj;
plength = parseInt(pan.offsetHeight / vh);
}
if (pan === undefined) {
return;
}
plength = plength || parseInt(pan.offsetHeight / vmin);
slength = parseInt(pan.style.transform.replace('translateY(', ''));
if (scdir === 'up' && Math.abs(slength) < (plength - plength / pnls)) {
slength = slength - step;
} else if (scdir === 'down' && slength < 0) {
slength = slength + step;
} else if (scdir === 'top') {
slength = 0;
}
if (hold === false) {
hold = true;
pan.style.transform = 'translateY(' + slength + 'vh)';
setTimeout(function() {
hold = false;
}, 500);
}
console.log(scdir + ':' + slength + ':' + plength + ':' + (plength - plength / pnls));
}
/*[swipe detection on touchscreen devices]*/
function _swipe(obj) {
var swdir,
sX,
sY,
dX,
dY,
threshold = 100,
/*[min distance traveled to be considered swipe]*/
slack = 50,
/*[max distance allowed at the same time in perpendicular direction]*/
alT = 300,
/*[max time allowed to travel that distance]*/
elT, /*[elapsed time]*/
stT; /*[start time]*/
obj.addEventListener('touchstart', function(e) {
var tchs = e.changedTouches[0];
swdir = 'none';
sX = tchs.pageX;
sY = tchs.pageY;
stT = new Date().getTime();
//e.preventDefault();
}, false);
obj.addEventListener('touchmove', function(e) {
e.preventDefault(); /*[prevent scrolling when inside DIV]*/
}, false);
obj.addEventListener('touchend', function(e) {
var tchs = e.changedTouches[0];
dX = tchs.pageX - sX;
dY = tchs.pageY - sY;
elT = new Date().getTime() - stT;
if (elT <= alT) {
if (Math.abs(dX) >= threshold && Math.abs(dY) <= slack) {
swdir = (dX < 0) ? 'left' : 'right';
} else if (Math.abs(dY) >= threshold && Math.abs(dX) <= slack) {
swdir = (dY < 0) ? 'up' : 'down';
}
if (obj.id === 'well') {
if (swdir === 'up') {
scdir = swdir;
_scrollY(obj);
} else if (swdir === 'down' && obj.style.transform !== 'translateY(0)') {
scdir = swdir;
_scrollY(obj);
}
e.stopPropagation();
}
}
}, false);
}
/*[assignments]*/
var well = document.getElementById('well');
well.style.transform = 'translateY(0)';
well.addEventListener('wheel', function(e) {
if (e.deltaY < 0) {
scdir = 'down';
}
if (e.deltaY > 0) {
scdir = 'up';
}
e.stopPropagation();
});
well.addEventListener('wheel', _scrollY);
_swipe(well);
var tops = document.querySelectorAll('.top');
for (var i = 0; i < tops.length; i++) {
tops[i].addEventListener('click', function() {
scdir = 'top';
_scrollY(well);
});
}
})();
I have a page that uses the fullpage.js plugin. This plugin allows the user to scroll down and an entire 100%vh screen to appear.
My issue is that I have animations on different sections that I want to delay until that div is within the viewport. It took me a while to figure this out and was trying to do scroll functions, forgetting that fact I am not really scrolling. Before I was trying to do this:
<div id="section1-right-container">
<div id="think"></div>
</div>
$(window).on("scroll", function(){
// Determine if the element is in the viewport
if($('section1-right-container').visible(true)) {
$('section1-right-container').addClass("think");
}
});
I found the following code and modified it some, I am just unsure of how to elimate the scrolling part and to start the animation once the section1-right-container is in the viewport.
// Returns true if the specified element has been scrolled into the viewport.
/*function isElementInViewport(elem) {
var $elem = $(elem);
// Get the scroll position of the page.
var scrollElem = ((navigator.userAgent.toLowerCase().indexOf('webkit') != -1) ? 'body' : 'html');
var viewportTop = $(scrollElem).scrollTop();
var viewportBottom = viewportTop + $(window).height();
// Get the position of the element on the page.
var elemTop = Math.round( $elem.offset().top );
var elemBottom = elemTop + $elem.height();
return ((elemTop < viewportBottom) && (elemBottom > viewportTop));
}
// Check if it's time to start the animation.
/*function checkAnimation() {
var $elem = $('#think');
// If the animation has already been started
if ($elem.hasClass('start')) return;
if (isElementInViewport($elem)) {
// Start the animation
$elem.addClass('start');
}
}
Anyone know what I could do?
UPDATE - visible plugin
(function(e) {
e.fn.visible = function(t, n, r) {
var i = e(this).eq(0),
s = i.get(0),
o = e(window),
u = o.scrollTop(),
a = u + o.height(),
f = o.scrollLeft(),
l = f + o.width(),
c = i.offset().top,
h = c + i.height(),
p = i.offset().left,
d = p + i.width(),
v = t === true ? h : c,
m = t === true ? c : h,
g = t === true ? d : p,
y = t === true ? p : d,
b = n === true ? s.offsetWidth * s.offsetHeight : true,
r = r ? r : "both";
if (r === "both") return !!b && m <= a && v >= u && y <= l && g >= f;
else if (r === "vertical") return !!b && m <= a && v >= u;
else if (r === "horizontal") return !!b && y <= l && g >= f
}
})(jQuery)
Why don't you make use of the fullPage.js callbacks such as onLeave or afterLoad?
That's the purpose of them.
I had the following code for expanding textarea, i have no problem to expand the textarea base on text length,however, i need to execute a function when it expand. I don't know which term I should use to do that. Something like, if(this textarea expand){ alert('ok'); appreciate.
$.fn.TextAreaExpander = function(minHeight, maxHeight) {
var hCheck = !($.browser.msie || $.browser.opera);
// resize a textarea
function ResizeTextarea(e) {
// event or initialize element?
e = e.target || e;
// find content length and box width
var vlen = e.value.length, ewidth = e.offsetWidth;
if (vlen != e.valLength || ewidth != e.boxWidth) {
if (hCheck && (vlen < e.valLength || ewidth != e.boxWidth)) e.style.height = "0";
var h = Math.max(e.expandMin, Math.min(e.scrollHeight, e.expandMax));
e.style.overflow = (e.scrollHeight > h ? "auto" : "hidden");
e.style.height = h + "px";
e.valLength = vlen;
e.boxWidth = ewidth;
}
return true;
};
// initialize
this.each(function() {
// is a textarea?
if (this.nodeName.toLowerCase() != "textarea") return;
// set height restrictions
var p = this.className.match(/expand(\d+)\-*(\d+)*/i);
this.expandMin = minHeight || (p ? parseInt('0'+p[1], 10) : 0);
this.expandMax = maxHeight || (p ? parseInt('0'+p[2], 10) : 99999);
// initial resize
ResizeTextarea(this);
// zero vertical padding and add events
if (!this.Initialized) {
this.Initialized = true;
$(this).css("padding-top", 0).css("padding-bottom", 0);
$(this).bind("keyup", ResizeTextarea).bind("focus", ResizeTextarea);
}
});
return this;
};
jQuery("textarea[class*=expand9-999]").TextAreaExpander();//initialize the text expand
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea class="expand9-999">good</textarea>
You need to save the height and check the current height with the previously saved height.
FYI - You need to include jQuery Migrate library for $.browser.msie to work. Reference.
Working Code Snippet:
$.fn.TextAreaExpander = function(minHeight, maxHeight) {
var hCheck = !($.browser.msie || $.browser.opera);
var prevHeight;
// resize a textarea
function ResizeTextarea(e) {
// event or initialize element?
e = e.target || e;
// find content length and box width
var vlen = e.value.length, ewidth = e.offsetWidth;
if (vlen != e.valLength || ewidth != e.boxWidth) {
if (hCheck && (vlen < e.valLength || ewidth != e.boxWidth)) e.style.height = "0";
var h = Math.max(e.expandMin, Math.min(e.scrollHeight, e.expandMax));
e.style.overflow = (e.scrollHeight > h ? "auto" : "hidden");
e.style.height = h + "px"; // this is where you are actually resizing
if(e.style.height !== prevHeight) // throw the alert only if the height is not same as the previous one
alert("resized");
e.valLength = vlen;
e.boxWidth = ewidth;
prevHeight = e.style.height; // save the height
}
return true;
};
// initialize
this.each(function() {
// is a textarea?
if (this.nodeName.toLowerCase() != "textarea") return;
// set height restrictions
var p = this.className.match(/expand(\d+)\-*(\d+)*/i);
this.expandMin = minHeight || (p ? parseInt('0'+p[1], 10) : 0);
this.expandMax = maxHeight || (p ? parseInt('0'+p[2], 10) : 99999);
// initial resize
ResizeTextarea(this);
// zero vertical padding and add events
if (!this.Initialized) {
this.Initialized = true;
$(this).css("padding-top", 0).css("padding-bottom", 0);
$(this).bind("keyup", ResizeTextarea).bind("focus", ResizeTextarea);
}
});
return this;
};
jQuery("textarea[class*=expand9-999]").TextAreaExpander();//initialize the text expand
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="http://code.jquery.com/jquery-migrate-1.2.1.js"></script>
<textarea class="expand9-999">good</textarea>
<p>Check your console.</p>
Try following will help you.
$(document).ready(function () {
var $textareas = jQuery('textarea');
// set init (default) state
$textareas.data('x', $textareas.outerWidth());
$textareas.data('y', $textareas.outerHeight());
$textareas.mouseup(function () {
var $this = $(this);
if ($this.outerWidth() != $this.data('x') || $this.outerHeight() != $this.data('y')) {
alert("ok");
}
// set new height/width
});
});
textareaResize($(".expand9-999"));
$.fn.TextAreaExpander = function(minHeight, maxHeight) {
var hCheck = !($.browser.msie || $.browser.opera);
// resize a textarea
function ResizeTextarea(e) {
// event or initialize element?
e = e.target || e;
// find content length and box width
var vlen = e.value.length, ewidth = e.offsetWidth;
if (vlen != e.valLength || ewidth != e.boxWidth) {
if (hCheck && (vlen < e.valLength || ewidth != e.boxWidth)) e.style.height = "0";
var h = Math.max(e.expandMin, Math.min(e.scrollHeight, e.expandMax));
e.style.overflow = (e.scrollHeight > h ? "auto" : "hidden");
e.style.height = h + "px";
e.valLength = vlen;
e.boxWidth = ewidth;
}
return true;
};
// initialize
this.each(function() {
// is a textarea?
if (this.nodeName.toLowerCase() != "textarea") return;
// set height restrictions
var p = this.className.match(/expand(\d+)\-*(\d+)*/i);
this.expandMin = minHeight || (p ? parseInt('0'+p[1], 10) : 0);
this.expandMax = maxHeight || (p ? parseInt('0'+p[2], 10) : 99999);
// initial resize
ResizeTextarea(this);
// zero vertical padding and add events
if (!this.Initialized) {
this.Initialized = true;
$(this).css("padding-top", 0).css("padding-bottom", 0);
$(this).bind("keyup", ResizeTextarea).bind("focus", ResizeTextarea);
}
});
return this;
};
jQuery("textarea[class*=expand9-999]").TextAreaExpander();//initialize the text expand
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea class="expand9-999">good</textarea>