position() being treated as a function - javascript

I am working on a slider, here is the code for it:
$(document).ready(function() {
// MAKE SLIDER WIDTH EQUAL TO ALL SLIDES WIDTH
var totalWidth = 0;
$('.slide').each(function() {
totalWidth = totalWidth + $(this).outerWidth(true);
});
var maxScrollPosition = totalWidth - $(".slider_wrap").outerWidth();
function slideMove($targetSlide) {
if ($targetSlide.length) {
var newPosition = $targetSlide.position().left;
if (newPosition <= maxScrollPosition ) {
$targetSlide.addClass('slide--active');
$targetSlide.siblings().removeClass("slide--active");
$(".slider").animate({
left : - newPosition
});
}
else {
$(".slider").animate({
left : - maxScrollPosition
});
};
};
};
$(".slide").width(totalWidth);
$(".slide:first").addClass("slide--active");
$(".next_post").click(function(){
var $targetItem = $(".slide--active").prev();
slideMove('.slide');
});
$(".prev_post").click(function(){
var $targetItem = $(".slide--active").next();
slideMove('.slide');
});
});
While I would expect this to work, I am getting an error that says: TypeError: $targetSlide.position is undefined. From the if statement in the function slideMove. Why doesn't this work? I am still learning jQuery so sorry if it is an obvious answer.

change this
slideMove('.slide');
to this
slideMove($('.slide'));
In your method slideMove you are expecting a JQUERY DOM ELEMENT where as you are giving it just a STRING which is class name of that particular DOM element

YO! you change it to this
...
$('.next_post').click(function(){
var $targetItem = $('.slide--active').prev();
slideMove($('.slide'));
});
$('.prev_post').click(function(){
var $targetItem = $('.slide--active').next();
slideMove($('.slide'));
});
...

Related

Call a function inside jQuery function

I want to execute an exeternal function inside the JQuery method. The problem appear when I try to call the method, the one looks undefined. How could I solve this? I amb using Typescript with Angular 2
ngAfterViewInit() {
jQuery(".mo-table").scroll(function () {
var trueDiveHeight = jQuery(".mo-table")[0].scrollHeight;
var divHeight = jQuery(".mo-table").height();
var scrollLeft = trueDiveHeight - divHeight;
if (jQuery(".mo-table").scrollTop() >= scrollLeft - 150) {
this.onSearch();
console.log("new bottom")
}
});
}
The method onSearch is an external function, and is Undefined.
onSearch(): void {
this.updateTableReport(this.scrollId, this.buildParams())
}
Any help would be appreciated.
Change
jQuery(".mo-table").scroll(function () {
to
jQuery(".mo-table").scroll( ()=> {
your this is not refering to your component
or the old js way:
ngAfterViewInit() {
var self = this; //<-- assign this to self here
jQuery(".mo-table").scroll(function () {
var trueDiveHeight = jQuery(".mo-table")[0].scrollHeight;
var divHeight = jQuery(".mo-table").height();
var scrollLeft = trueDiveHeight - divHeight;
if (jQuery(".mo-table").scrollTop() >= scrollLeft - 150) {
self.onSearch(); //<-- use self here
console.log("new bottom")
}
});
}

Jquery typing effect on scroll bug

Hi I have some js code that do typing effect on my web page it start typing when you scroll down end of page. For first it work normally but when you start scroll faster down to up the typing effect goes crazy how can I fix that
demo page
code
$(window).scroll(function (e) {
var elem = $(".hello-page");
var scrollTop = $(window).scrollTop();
var blockTop = elem.offset().top;
var docHeight = $(document).height();
var windowH = $(window).height();
if (scrollTop >= blockTop) {
var helloPageA = $(".hello-page").find("a");
var text = helloPageA.attr("data-text");
helloPageA.text('');
$.each(text.split(''), function (i, letter) {
setTimeout(function () {
helloPageA.html(helloPageA.html() + letter);
}, 150 * i);
});
} else {
elem.find("a").text('');
}
});
jsfiddle example
Thanks for your help
So, here is the solution - http://jsfiddle.net/u3ojjx8r/1/
I borrowed initial structure of the code from previous answer here and it was removed unfortunately, therefore I can't mention one of the co-authors. Though the code looked quite similar to topic-starter's one.
The idea of the code below is to separate the queuing of characters to render and the actual rendering. Another important improvement is always have control over timeouts, i.e. never schedule more than one timeout. That allows you to cancel them any time without unpredicted/uncontrolled behavior.
var timeoutVar;
var queue = [];
var drawQueueTimeout = -1;
var helloPageA = $(".hello-page").find("a");
function pushQueue (element) {
console.log('pushQUeue', element.char);
queue.push(element);
checkQueue();
}
function flushQueue () {
console.log('flushQueue');
queue = [];
clearTimeout(drawQueueTimeout);
drawQueueTimeout = -1;
}
function checkQueue () {
console.log('checkQueue', queue.length, drawQueueTimeout);
if (queue.length > 0 && drawQueueTimeout < 0) {
console.log('schedule drawQueue');
drawQueueTimeout = setTimeout(drawQueue, 150);
}
}
function drawQueue () {
drawQueueTimeout = -1;
console.log('draw queue');
if (queue.length > 0) {
var element = queue.shift();
console.log('drawQueue', element.char);
helloPageA.html(helloPageA.html() + element.char);
}
checkQueue();
}
$(window).scroll(function (e) {
var elem = $(".hello-page");
var scrollTop = $(window).scrollTop();
var blockTop = elem.offset().top;
var docHeight = $(document).height();
var windowH = $(window).height();
if (scrollTop + windowH == docHeight) {
// Empty anything typed so far
helloPageA.empty();
flushQueue();
var text = helloPageA.attr("data-text");
helloPageA.text('');
$.each(text.split(''), function (i, letter) {
pushQueue({
char: letter,
index: i
});
});
} else {
helloPageA.empty();
flushQueue();
}
});

Jquery function should also work with other elements

I'm trying to make this function working multiple times:
Currently works only with the h1 tag
how can I make it working for the <div class="logo"> as well? I don't want to repeat the function, I need a way to make the function working for various elements.
demo: http://jsfiddle.net/33Ec8/4/
JS:
// Get the divs that should change
function displayThese() {
var $heading = $('h1');
var h1top = $heading.position().top;
var h1bottom = h1top + $heading.height();
var h1left = $heading.position().left;
var h1right = h1top + $heading.width();
var divs = $('li').filter(function () {
var $e = $(this);
var top = $e.position().top;
var bottom = top + $e.height();
var left = $e.position().left;
var right = left + $e.width();
return top > h1bottom || bottom < h1top || left > h1right || right < h1left;
});
return divs;
}
(function fadeInDiv() {
var divs = displayThese();
var elem = divs.eq(Math.floor(Math.random() * divs.length));
if (!elem.is(':visible')) {
elem.prev().remove();
elem.animate({
opacity: 1
}, Math.floor(Math.random() * 1000), fadeInDiv);
} else {
elem.animate({
opacity: (Math.random() * 1)
}, Math.floor(Math.random() * 1000), function () {
window.setTimeout(fadeInDiv);
});
}
})();
$(window).resize(function () {
// Get items that do not change
var divs = $('li').not(displayThese());
divs.css({
opacity: 0.3
});
});
Your question isn't stated very clearly, so I would strongly suggest describing what the code should do vs what it does.
That said, here is a half-blind attempt at answering what I think you want.
You could pass in the selector as a parameter to displayThese.
function displayThese(selectorString)
{
var $elementsUnderWhichNothingShouldFade = $(selectorString);
...
}
then when you call displayThese, you can pass in any complex selector you like.
var divsToChange = displayThese('h1, div.logo')
Of course, you would need to add extra logic to test whether the image elements were underneath any of the resulting $elementsUnderWhichNothingShouldFade (which is a list of elements).

JavaScript make value of variable public

Here is excerpt from my larger JavaScript file:
function dashboardConfig()
{
$(window).on('resize', function () {
var viewport = {
width : $(this).width(),
height : $(this).height()
};
el.siteContainer.css(
{
marginTop : (viewport.height - 652) / 2
});
el.dashboardSlide.css(
{
marginLeft : (viewport.width - 1024) / 2,
marginRight : (viewport.width - 1024) / 2
});
//Calculate how many nav elements
el.navElements.each(function(i)
{
el.dashboard.css(
{
width : viewport.width * (i + 1)
});
$(this).click(function()
{
//HERE IS THE VARIABLE I WOULD LIKE TO USE
var dashboardSlidePosition = viewport.width * i;
el.navElements.removeClass('active');
$(this).addClass('active');
el.dashboard.animate(
{
left : -dashboardSlidePosition
},500, function()
{
el.dashboard.css(
{
left : -dashboardSlidePosition
});
});
});
});
//I WANT TO PERFORM ANOTHER FUNCTION HERE AND HAVE IT USE THE VALUE OF dashboardSlidePosition
}).trigger('resize');
}
I want to know how I can pass the value of the variable, dashboardSlidePosition, to another function. Please can anyone explain how?
Many thanks in advance.
You can declare it at the outer edge of your scope. Make sure to give it an initial value so that you don't try to use it before it has been set properly.
function dashboardConfig()
{
var dashboardSlidePosition = null;
function anotherFunction() {
if (dashboardSlidePosition != null) {
// ...
}
}
$(this).click(function()
{
dashboardSlidePosition = viewport.width * i;
}
}
Put it into the proper scope:
function dashboardConfig()
{
var dashboardSlidePosition = 0;
Next, remove var when redefining it.
Now you can use it because it's in the scope of the function.

Calculate largest width of a set of elements using jQuery

I have made a quick Jsbin: http://jsbin.com/ujabew/edit#javascript,html,live
What i'm trying to achieve is to find out which is the largest <section> out of the 3 from the link. So what i'd like is to, after the loop runs, is to have var width set to the largest possible number that any of the widths could be.
Code in progress posted in link
Here:
var maxWidth = Math.max.apply( null, $( elems ).map( function () {
return $( this ).outerWidth( true );
}).get() );
Live demo: http://jsfiddle.net/rM4UG/
Fleshing out Marc B's comment, using Math.max():
$(document).ready(function(){
var maxWidth = 0;
$('.content ul li').each(function(){
var itemWidth = $(this).outerWidth(true);
maxWidth = Math.max(maxWidth, itemWidth)
});
});
I believe you want to look into the underscore library. Specifically, the max method
$(document).ready(function(){
var maxWidth = 0;
$('section').each(function(){
w = $(this).outerWidth(true);
if ( w > maxWidth)
maxWidth = w;
});
});
Change the .each() loop to this:
var thisWidth = $(this).outerWidth(true);
if (thisWidth > width) {
width = thisWidth;
}
I have just written a function regarding this. I thought it might help others. (jQuery)
$.fn.largerWidth = function () { //function(p)
// where 'p' can be clientWidth or offsetWidth
// or anything else related to width or height
var s = this,m;
for (var i = 0; i < s.length; i++) {
var w = s[i].offsetWidth; // s[i][p];
(!m || w > m) ? (m = w) : null
}
return m;
}
This was my idea:
$(document).ready(function () {
var elements = $(".content ul li");
var count = elements.length - 1;
var width = [];
elements.each(function (n) {
width.push($(this).outerWidth(true));
if (count == n) {
width = Math.max.apply(Math, width);
}
});
});
I added the count of the number of elements and then runs the Math.max to get the largest number when each loop is done.

Categories

Resources