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');
Related
I have a function that dynamically creates div elements based upon whatever input is given, and lets them choose certain items by clicking on each div. I have it so that if the div is clicked, a function (named checkToggle) is called that makes it looks like it is selected and adjusts some related variables. There is a checkbox in the div element that is toggled by this function (hence its name). Long story short, I had to jump through some hoops to get it to work, most of which I don't even remember. Please don't ask me about that.
The point of this question is this. I initially used the following JavaScript code to run the function when the checkbox was clicked. It was assigned by the main function, which created these div elements using a for loop.
document.getElementById(`${itemID}-checkbox`).onclick = function() {
checkToggle(`${itemID}-checkbox`);
};
This works, but I wanted to try to convert all of my onClick functions to JQuery. Here is the JQuery alternative I created.
$(`${itemID}-checkbox`).on(`click`, function() {
checkToggle(`${itemID}-checkbox`);
});
While the code itself seems to be fine, it does not work. It seems as if JQuery functions cannot be created like this in a for loop or something. It is applied after the element is created and put in its place, so I don't think it has anything to do with the element not being ready. I am also having the same issue with 2 other similar cases. Any idea as of why this isn't working?
Let me know if more information is needed and if so, what kind of information is needed.
You need to update the selector to Target HTML id using the # character. Simply prepend the character to the query:
$(`#${itemID}-checkbox`).on(`click`, function() { checkToggle(`${itemID}-checkbox`); });
It would also apply to DOM methods querySelector or querySelectorAll as well.
Hopefully that helps!
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");
});
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.
I'm new to Protoype.JS and just testing it a bit because I heard it was good, but I'm stuck quite quickly.
As easy as this is with jQuery, it seems to be the end of the world to get the text in an element. I've tried innerHTML in multiple ways but the only thing I can get is "undefined".
alert($$('.mnu_item').innerHTML);
alert($('content').innerHTML);
None of these work.
Content is a div with id "content" and .mnu_item is an anchor tag with class ".mnu_item".
I don't get what the problem is, probably something stupid but it would be great if somebody could point me in the right direction!
EDIT: I've found that it isn't the innerHTML that doesn't work but it's the class selector. The second line in the code above does work. How can I select an element by its class in the latest Prototype version if this isn't the correct way?
Has the DOM loaded when you run your script? If you're not running this code in a window.onload or by placing it at the end of the body, then the elements by not exist when it runs.
Try placing your script just inside the closing </body> tag.
<body>
<!-- my content -->
<script type="text/javascript">
alert($('content').innerHTML);
</script>
</body>
Also, your first line is selecting correctly, but will return an Array of elements, so innerHTML will be undefined.
To iterate the Array, you can do this:
$$('.mnu_item').each(function(val,i) {
alert(val.innerHTML);
});
or if you want to end up with an Array of the innerHTML values, do this:
var values = $$('.mnu_item').map(function(val,i) {
return val.innerHTML;
});
Make sure the DOM is loaded before you run these tests:
$(document).on('dom:loaded', function () {
/* code to execute after dom has loaded */
})
The first line of code $$('.mne_item') doesn't work because $$ gives back an array of all elements matching the css rule. So $$('.mne_item') gives an array of all dom elements which has the class mne_item. You can ask the first one by using the first method or iterate over all items like this:
$$('.mne_item').each(function(elem) {
// elem is the li elements extended by all Element methods of prototype
});
If you use $ in jQuery, it actually uses a similar pattern but hides the each construct. It just applies the chained method to all elements or just the first.
The second line of code $('content').innerHTML should work. $ is a shortcut for document.getElementById so it should give you a DOM node back. The reason why this doesn't work is there is no node where id = content, probably because the dom isn't loaded yet.
For more info about the methods of prototype look at the api: http://api.prototypejs.org/
Also check the default DOM methods: http://quirksmode.org/dom/w3c_core.html
$('content').innerHTML should work. Check your HTML, ensure the ID is unique.
var text = $$('label[for="display_on_amazon"]').first().textContent;
Above code worked for me.
Regarding, $$('.mnu_item').innerHTML
When you are trying to fetch with class selector, prototype returns array of multiple elments, by using [0] or first() method system will point at the first element in that array, after that you can use innerHtml (to get html inside the element) or textContent (to get text content of that element, native javascript method)
I have written a Greasemonkey script which manipulates the contents of certain elements with the following selector:
$("span.relativetime").each(function() { $(this).html("TEST"); });
However, sometimes matching elements are added to the page through AJAX, and I don't know how to handle those new elements. I have tried this, but it doesn't work:
$("span.relativetime").live(function() { $(this).html("TEST"); });
The documentation for jQuery live() says that it wants an event (like "click"). But I don't have any event, I just want to know when something matching my selector has been created, and then I want to modify it.
Background: I am encountering this problem with a Greasemonkey script to display StackOverflow's relative timestamps as absolute local timestamps, which you can find on meta-SO. The problem is when you click "show all comments", the new comments are added by AJAX, and I don't know how to find and replace the timestamps in those scripts.
With StackOverflow's setup I find it annoying to handle stuff after the comments. What I've done is put a bind on the Add/Remove comments button that uses setTimeout to wait for the elements to be created, and then modify them.
One thing you could try (although I'm not sure if it would work) is to cache your selection in some global variable like so:
var $relativetime = $("span.relativetime");
Then you would have your .each function:
$relativetime.each(function() { $(this).html("TEST"); });
After your new elements were added to the DOM, you could reselect append to your cached object:
$relativetime.append("<my html>"); //or
$("<my html>").appendto($relativetime);
(P.s. .html() is for setting html. To set text, use .text()