jQuery Waypoints add class when element is scrolled into view - javascript

I'm using the Waypoints plugin to check if an element is scrolled into view. I have multiple divs with class item as the user scrolls down the page, I want to add a class "viewed" to each.
$(".item").waypoint(function(){
$(this).addClass("viewed");
console.log("yey");
});
The console.log works, but the .addClass doesn't. Does the plugin not support $(this)?

I finally got it working.
$(".item").waypoint(function(){
$(this[0,'element']).addClass("viewed");
});
The this wasn't pointed at the element, so I needed to target it.

You have to be careful when calling these callback functions, and what this really means. In this instance, its probably referring to your function.
Doesn't the event trigger pass the target in the function as an argument? Try using that. If you want to know what your nested this really is, console.log it.
$(".item").waypoint(function(thing){
$(thing).addClass("viewed");
console.log("yey");
});

The checked answer caused loads of errors in newer version of this plugin.
This is what works for me:
$(".item").waypoint(function() {
$(this.element).addClass("viewed");
});

Related

Jquery .remove() only acts on second click

I'm building out a notifications feature with bootstrap popover. A notification should be removed after a user clicks on it, which is intuitive. However, it takes two clicks to make it work -- the first time, nothing seems to happen. The click listener is firing both times as discovered through alert().
I've simplified my problem to its most basic reproducible form in this fiddle js:
https://jsfiddle.net/ksun78/758n1azu/36/
$('body').on("click", ".popover-body .notif-popup-container", function() {
$("#" + $(this).attr("id")).remove();
})
Placing code above because it won't let me submit without code snippet, though the fiddle js should have all you need.
Can someone explain what the issue might be and how to fix it? Thanks!
I think the problem is that the popover library clones your elements so there are two elements with the same Ids. You can modify your code like this so it will work but better to avoid same Ids
$('body').on("click", ".popover-body .notif-popup-container", function() {
$(`[id="${$(this).attr("id")}"]`).remove();
})
If you simply want to delete that div you can use following code:
$(document).on("click", ".notif-popup-container", function() {
$(this).remove();
});
It turns out that behind the scenes, popover will make a copy of the elements and display them. This means that using ONLY the ID to remove the elements won't work, because it will first remove the display:none element on the page, then the copy of that shown in the popover. Thanks to #Gabriel for pointing that out.
The solution here was just to not use the id attribute of the element as it was unnecessary. A simple $(this).remove() will do the trick.
As for the issue of duplicate id's: I was originally intending on storing the notification id inside a "data-id" attribute. However, retrieving "data-id" using jquery was returning undefined, so I opted for the "id" attribute instead. Maybe #Gabriel can provide some insight into the issue of "data-id" being undefined, as it seems like a popover related issue as well.

jQuery: Refreshing an element

I'm using this accordion-like script:
jQuery(document).ready(function () {
jQuery(".content").hide();
jQuery(".heading").click(function () {
jQuery(this).next(".content").slideToggle(500)
});
});
But then I add this line in order to reload the element after the content div toggles...
document.getElementsByClassName(transition current).reload();
and as a result, the accordion no longer works... The content class is always being displayed.
Why is this line affecting the behavior of the accordion?
I'm trying to refresh the element while retaining the accordion style divs...
Any ideas?
You need to use event delegation since the elements are created dynamically
jQuery(function ($) {
$(".content").hide();
$(document).on('click', ".heading", function () {
$(this).next(".content").stop(true, true).slideToggle(500)
});
});
Still you might have a problem of all content element getting displayed once the element is reloaded, for hiding those elements you need to use any load callback system provided by the reloader you are using
You've got a syntax error here:
document.getElementsByClassName(transition current).reload();
getElementsByClassName expects a string to be passed (not to mention that the above isn't syntactically correct even if it did expect two arguments). You're trying to pass two variables (which you haven't defined). Pass a string:
document.getElementsByClassName('transition current').reload();
Blast. That doesn't work either! Reading the docs informs us that getElementsByClassName returns an HTMLCollection, which doesn't have the method reload(), resulting in another error. Are you even looking at the console?
You may be assuming that getElementsByClassName returns a jQuery object, in which case you can replace the above with $('.transistion, .current').reload();
Again, let's note that reload() isn't a native jQuery method either. I'm assuming you're bringing it in via a plugin. If I'm wrong, comment below and I'll update the answer.
I was using the isotype jQuery plugin, so the issue was resolved by adding this one line as a callback to "relayout" any changes that were loaded into the DOM.
$('#blog-list').isotope('reLayout');

Jquery remove function follow up

I submitted this question last week:
chrome not working with jquery remove
and was able to resolve it (stupidity on my part really), however my example was very simple. Currently I'm trying to use .remove to eliminate a complete div from a page before sending an array of inputs to an ajax function. However, I am not able to get .remove to work at all.
Here's my latest try:
http://jsfiddle.net/CJ2r9/2/
I get function not defined on the jsfiddle on multiple browsers. On my application I get absolutely no errors, but nothing works either.
I'm relatively new to javascript scopes, so if the problem is scope-wise then please let me know how I'm screwing up.
I have also tried using the .on jquery function, but it's a bit more confusing considering my div ids are dynamically loaded from the server (jstl, spring MVC, etc). If that's a solution please let me know how I can get on the right track.
Thank you!
The two problems in your jsFiddle are:
Scope: removeElem is not in global scope, since you left the default configuration option to execute the code on DOM ready. You can change it to "no wrap" to make the funciton global.
The elements you want to remove don't exist. The div elements have IDs like "removeXXXp" and in your event handlers you pass "removeXXXs".
Here is an other, simpler solution (in my opinion) for element removal. Given your markup:
<div class="scheduleSet" id="remove315p">
<!-- ... -->
Remove
</div>
You can use .on like so:
$('.schduleSet a.optionHide').on('click', function() {
// traverses up the DOM tree and finds the enclosing .schduleSet element
$(this).closest('.scheduleSet').remove();
});
You don't even need IDs at all.
I made a simple fiddle, the inline onclick doesn't see the function defined in javascript so I get a ReferenceError: myRemove is not defined.
By adding the listener in js, .remove() works fine.
Sorry I don't know what causes the difference in behavior though.
Test it out: http://jsfiddle.net/xTv5M/1/
// HTML5
<div id="removeme">foo bar</div>
<button onclick="myRemove('removeme')">Go</button><br>
<div id="removeMe2">foo bar</div>
<button id="go2">Go Again</button>
// js
function myRemove(name){
$('#'+name).remove()
};
$('#go2').click(function(){ myRemove('removeMe2') });
I see that you are already using jquery. Why dont you do it this way:
<div id="foo">This needs to be removed</div>
Remove
function removeElem(element){
$('#'+element).remove();
}
$(function(){
$("#remove").click(function(){
removeElem($(this).data('remove'));
});
})
Fiddle here: http://jsfiddle.net/vLgpk/
They way this works is, using data-remove (can be anything like data-xyz btw), binds the remove link with the div. You can then read this binding later when remove is clicked.
If you are new to jQuery, and wondering what data-remove is, its just custom attribute that you can add to you code which can be later retrieved using the data() call on the element. Many great frameworks like Bootstrap use this approach.
Advantage of using this approach in my opinion is you can have the remove links anywhere in your UI and they don't need to be related structurally to your divs by siting inside them.

Javascript call function when html inject finished onclick

I've got this situation:
There is a calendar script to pick a date. When the date is picked a function called onclick to make a select box available for time pick. Now its not like its display:none-->display:block, the select being generated by JS. My goal is to customize this select. For that I got a jquery script "custom.select" which just turns the select to spans. The problem is that if I add the call for this script to the onclick right after the calendar call it does not take. I am pretty sure its because at that stage the html for the select is not injected yet. If I call the custom.select function from the firebug console after the select is visible - it works just fine.
So the question is: how do I call it so it will do its magic on select box?
Thanks
Use delegation with .on():
$(function(){
$(document).on('click','.classdynamic',function(){
//do stuff here
});
});
You should delegate event to the closest static container of your target element. This means changing $(document).on('click','.classdynamic',function(){...});
by something like: $('#staticContainer').on('click','.classdynamic',function(){...});
Figuring out when elements are added is not an easy task. I answered a similar question here.
The best way would be to have some control on the script that creates the select, and append your code to it. One way to achieve this is with Aspect Oriented Programming (AOP) - not easy either.
With current browsers, the most straightforward way is to use setTimeout in a loop and poll the page until the element exists.
Ok I got this thanks to Christophe! I used the Selector Listeners script from here: http://www.backalleycoder.com/2012/08/06/css-selector-listeners/
It was even more complicated coz the parent was not present either )). So what I did was that I attached the listener to the onclick just after the calendar call lol. I needed to make another function though to make it work with the script, here is the code:
var doSelect = function(){
jQuery('#timeslots').customSelect();
};
jQuery(document).ready(function(){
jQuery('.td_calendar').on('click','#anchor1',function(){
cal.select(document.forms['frmRequest'].startdate,'anchor1','yyyy-MM-dd');
document.getElementById('slots').addSelectorListener('#timeslots', doSelect);
});
});

JQuery event selector

Say i have 10 small images that i want to use as tooltips.
Im assinging them all the same class, '.helper'
Im selecting helper, then calling
mouseenter(function() { $(".helper").stop(false,true).fadeIn(); })
I then want a div to popup, containing some text. This works fine if there's only one tooltip on the page, but as soon as there is more than one, whenever i hover over one, they all appear at the same time.
Have i got something fundamentally wrong?
Comments appreciated.
Thx
Use this as the selector inside instead of the .helper selector again:
$('.helper').mouseenter(function() {
// "this" now refers to the image that is being hovered...
$(this).stop(false, true).fadeIn();
});
If you're wondering what the problem was, it was that when you called
$(".helper")
within your function, you were getting all the elements with class helper, in stead of just the single element you wanted.

Categories