So I have the small code snippet below, which I would ideally like to call the function to alert me with hello when the #results_more element is clicked...
$('results_more').observe('click', function(evt) {
alert('hello');
});
However, I think I'm doing something terribly wrong if something this easy doesn't work. Anything I may be overlooking with the Prototype library, or Javascript in general?
At face value, there shouldn't be anything wrong with your code, but you aren't giving enough information.
Does exactly one element with id="results_more" exist? What is the result if you alert($('results_more'))?
Has the element been created already at the point you are trying to register the event listener? You cannot register events on (or for that matter collect) elements that have not yet been added to the DOM. You can get around this by moving your code to after the element is created in your HTML or put it within a dom:loaded event listener.
Take a look at jsfiddle.net/zDa7m for a simple example.
Related
What's the cleanest way of executing something on an element that is dynamically loaded through js/jQuery? Basically the user adds a form that potentially has a wysiwyg editor in it (depending on the context); this is a textarea that needs to have something like $(".wysiwygTA").editor(); called on it. Of course I could do something like:
var newForm = 'some_form_loaded_via_ajax_with_a <textarea class="wysiwygTA"> in_it';
$(".formWrapper").append(newForm);
$(newForm).find(".wysiwygTA").each(function(){ $(this}.editor(); });
But that doesnt seem very clean to me. Ideally I want to do something in the fashion of
$(document).listenForAddedTextarea(function(textarea){textarea.edtior();});
So that I could add the form from multiple places. I could isolate the editor-invoke in a seperate function and just call that, but that still leaves me with an extra line of code each time I want to add an element.
So: what would be the best way around this? :o)
Best Regards,
Rasmus Dencker
There is no such thing as elementAdded event in JS. Your only option is the 1st one you mentioned. Adding scripts in HTML you are returning from the server is a bad idea IMO.
Use Bind method for binding dynamically:
$( document ).bind( "listenForAddedTextarea", function(textarea) {
textarea.edtior();
});
you can do one thing. Create an event and trigger that event whenever you want.
Create an 'listenForAddedTextarea' event like
$(document).on("listenForAddedTextarea", function(textarea) {
textarea.edtior();
});
Trigger the event
$(document).trigger("listenForAddedTextarea");
I have code like this
<a id="id101" href="javascript:func1();" onclick="return func2();">Link</a>
func2 returns true or false. Then, func1 is called only when function2 returns true. Right ?
In learning jquery, I found out that onclick is not good and depreciated, so I modified above code to
<a id="id101" href="javascript:func1();">Link</a>
jquery
$("#id101").click(func2() {
//same stuffs from before which was in func2
});
Now, my question is:
after click handler is taken care of, what can I do with JavaScript inside href? Should I call func1 inside func2 in jQuery click handler of func2, when condition inside func2 is true?
Or is there some elegant solution?
Also, Separating html and events code is good, but here this element with id id101can have many events associated with it, and in a large file, there might be so many html elements with many events. So, when I have a large page with many event handlers, then how can I better know which html element has which and how many events associated with it?
More explanation to above question as requested,
I meant id101 can have onclick, onmouseover, onmouseout and many other such events. There can be many such elements with many such event handlers. How do I better spot them ? In old style, all such event handlers are all placed together, like this
<a id="id101" href="javascript:func1();" onclick="return func2();">Link</a>.
I am not saying this is good, but atleast I can see that it has this onclick event. But now when separting this into jquery file, I have to search first this jquery file for id101 and then check events associated with it, which can be problem with html file having many elements and associated event handlers. Is there any better way to to find that information ?
If I understand correctly, you want to avoid the inline Javascript, but you also want to be able to glance at an a and know if it has an event bound to it. Unfortunately, there isn't an acceptable way to denote this, as inline Javascript is bad news. Perhaps you can just give your element a dummy class to aid your future readability. Other than that, forget the whole func1 and func2 thing. Just use an anonymous function inside of your click binding.
<a id="some_id" class="optional_has_click">Click Me</a>
<script type="text/javascript">
$(document).ready(function(){
$("#some_id").click(function(){
// do something
alert( $(this).attr("id") );
});
});
</script>
EDIT: Also, removing the href will remove the visual cue, so you can use your dummy class to make it look like an a.
Here is a fiddle for you: http://jsfiddle.net/zzTSt/1/
The best I can tell you is that this is "smelly" code--you don't want your javascript all over the place like this. I would recommend you spend a few more hours learning some jQuery fundamentals and move on from there. I know it can be frustrating, especially if you are working with legacy javascript.
Yes, I recommend you to write func1 inside func2.
HTML:
<a id="id101" href="#" >Link</a>
jQuery
$("#id101").click(func2() {
var status = false;
//func2 goes here and modifies status value.
if (status) {
// func1 goes here
} else {
// in case if status is false.
}
});
Also I didn't get what you mean in second part of your question, could you please be more specific.
I got following problem: I generate a div with "jQuery-Load" links. Theese links inside the div should reload the same div with different parameters. I found a working solution, which generates theese links, which are clickable and... ...trigger the chosen event once. So clicking the same link inside the generated div, after it has been regenerated, doesnt work anymore. Tried a lot of things...
It looks like that now:
click
<div id="aaa0"> I'm the div - level1! </div>
div gets filled - beautyful.
It now contains this: (actually its generated what is why wrote [time] wich is time(); generated in php. as a changing parameter
[...] Link inside Updated Div [...]
when i click the link inside the div it works. when i click it again, it wont...
I want to generate a nice 'click deeper inside the data'-thing, which would be amazing getting this thing work and is the reason why everything must be as best as possible inside the "onclick" event :|
Sorry btw. for the a bit confusing post-style, its a confusing topic, and im not native speaking :)
Thanks for any help or hint in advance,
Harry
Maybe you're missing the concepts between bind and live. In bind, jQuery scans the document and attach a function direct to the element. In live, jQuery attach the function to the document, along with the event and the element as parameters. Once a event bubbles, jQuery check the event and the element, and if it match, then a function executes.
After the first run, the dom has changed, and its gonna work using live.
something like that should work:
click
<div id="aaa0"> I'm the div - level1! </div>
<script>
$('a').live('click', function (e) {
e.preventDefault();
var id = this.id;
$(this).next('div').load('getdetails.php?fNumber=36&env=fun&id=' + id);
});
</script>
basically, what is done is a generic rule, which gives all tags the same behavior. (load next div content). ".live()" is used so that loaded tags work (check the jquery documentation for .live(), or event delegation in general).
I'm not certain about the preventDefault stuff. You might want to use somehting else than tag for the link.
click
made the day :) I don't know exactly why, but maybe its possible preventDefault made the bind and live thing for me. Its working fine, so ...
thanks for the hints! :D
For example i'm using append, and for example i'm appendig button in to a div, and i have function $('button_id').click(... etc to work affter i append the div, how can i do that.I mean i get no errors, but the function is not starting, it's because i append and then i want to use the function but how to do that, i tryed with delegate, but same thing.I tryed with function in the button tag , onmouseover and then the function thing, but nothing it gives me function not found.What is the solution ?
I have two events, one event is click event that appends button, the other event is click event that does something if the button that was appended is clicked, but that second event is not working ?
Try using :
$(elem).live(...)
It will bind event for now and in the future.
Firstly, it always helps if you show us the exact source code. $('button_id') is the incorrect selector to start with, try something more along the lines of $('#button_id') as your selector. Also, are you appending dynamic content? Anyways, I've always used the delegate() function quite successfully, but have you tried using the live() function? Also, one more thing to make sure of is that you have the newest version of jQuery as your source.
As was stated as well, you can not have duplicate ids, if you want to have a pointer, use class, instead of id="some_id" use class="appended". To select those using jQuery, use the selector like this $('.appended').
Try something like this it will work as per your expectations.
$("#button_id").click(function(){
//On click code goes here
}).appendTo($("#div_id"));
It's difficult to determine the problem you're having without seeing your code, but delegate (or live) should be perfect for what you're trying to do:
$("body").delegate("#b", "click", function() {
alert("ok");
});
$("#example").append('<input type="button" id="b" value="Click" />');
The click handler above will fire when an element with id="b" is clicked, whether or not that element happens to be in the DOM right now or not.
However, as others have noted, it's important to remember that IDs need to be unique within a document, so by the sounds of it you may be better of using classes instead.
You can see an example of the above code running here.
I would really like a way to observe changes to a node and trigger functions based on those changes.
I'm going to define "changes" as:
Attribute edits/additions/deletions to a node and all descendants.
Text node edits/additions/deletions inside a node and all descendants.
Events bound/unbound to a node and all descendents.
The addition/deletion of a descendant.
CSS changes to a node and all descendents.
The deletion of a node.
Now maybe I'm going about this the wrong way, but my thought was to doctor the pre-existing jQuery methods that are responsible for modifications like those listed above, and add some code that triggers an event on all of the nodes in the set, and their ancestors (simulating a bubbling event).
Something like this:
$.fn.attrMOD = $.fn.attr;
$.fn.attr = function() {
this.each(function(){
$.fn.trigger.call($(this).parents().add(this), 'modify', { changeType: 'attr', originalTarget: $(this) });
});
return $.fn.attrMOD.apply(this, arguments);
};
And I would do this for many of the methods (css, bind, unbind, etc).
So to subscribe to this "modify" event, you would do something like:
$('div').bind('modify', function() { console.log('Div was modified') })
//this would trigger it
$('div').attr('hello', 'world');
So a couple of questions:
Am I crazy to try this?
Am I going about this the right way? Keep in mind the code above isn't close to final, but that is my general idea.
Thanks for reading!
It looks like it would work to me... however it might be worth noting to anyone who reads this thread (as I'm sure the asker is aware), that modify event would only be triggered if an attribute was modified via jQuery's attr(key,val) method. Any attempt to alter an attribute otherwise wouldn't kick it off.
Also... you'll want to be sure to add one to .css(x,y) and .width(val), .height(val), as well as .addClass(val), .removeClass(val) off the top of my head... and probably more. There's probably a lot you'll want to do.
I'm more curious about the "why?" you want to do this... lol.