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.
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");
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.
Code: http://dpaste.org/Oerz/
The page looks as it should, with the title, 5 paragraphs and buttons all appearing. Each button is supposed to make a small alteration to a specific elements styling.
Currently no action occurs when any of the buttons are clicked.
I'm only claiming the above code is error free based on finding no errors in chrome's javascript console or firebug. Then again, I'm new to all this so I don't know if I'm using them correctly.
Any help would be appreciated.
If your going to use jQuery then bind to click events like this
$('#oneButton').click(boldTheText);
or
$('#oneButton').bind("click", boldTheText);
Reference
http://api.jquery.com/click/
http://api.jquery.com/bind
You're assigning to onClick when you add the event handlers to your buttons. Assign to onclick instead -- note the lowercase "C".
There are no errors in the console because it's perfectly valid to assign something to an object's onClick property; the browser just won't ever use it.
You're really not utilizing the potential of jQuery here... I'm not exactly sure why your code doesn't work, but instead of looking into that specifically, I'll give you some hints on how to improve it. Most likely, it will start working in the process =)
For one thing, you never need document.getElementById() anymore. jQuery's selectors are way more powerful, and to select a button with id="oneButton" you simply use $('#oneButton'). Most of them looks and works like css selectors, so you already know them.
Secondly, you don't have to define all your methods with names to hook them up - instead, use anonymous functions (and hook them up using jQuery's click or live):
$('#oneButton').click(function() {
// Assuming you've defined .bold{font-weight:bold;} in your stylesheet
$('.firstDiv').addClass('bold');
// Assuming you haven't
$('.firstDiv').css('font-weight','bold');
// You only need one of the two above!
});
Thus, the first two buttons could be hooked up to do exactly the same things using only these few lines of code:
$('#oneButton').click(function() {
$('div.firstDiv').css('font-weight', 'bold');
});
$('#twoButton').click(function() {
alert('There are ' + $('p').size() + ' paragraphs.');
});
Edit: As Mark Bridges noted in a comment to another answer, changing onClick to onclick (with a lowercase c) solves your immediate problem. I wouldn't be satisfied with that though, since you have jQuery at your disposal.
I've simplified your code a little bit here to better take advantage of jquery's syntax:
<title>jQuery Example</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
window.onload = function() {
$('#one').click(function() {
$('#first').css('font-weight', 'bold');
});
};
</script>
</head>
<body>
<div class="firstDiv">
<p id="first">I should be bold.</p>
</div>
<button type="button" id="one">Bold</button>
</body>
</html>
Most importantly:
Use of $('#foo') instead of document.getElementById('foo') returns you jQuery objects with richer interaction semantics.
Use of the .click() method on a jquery object to define a click handler.
Use of the .css() method on a jquery object to make style changes.
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.
Can I add a custom JavaScript as some DOM node attribute to perform when it's ready like JavaScript added as "onClick" attribute performed when you click on it?
Suppose i need to process a div element with some funcMyTransform function.
I think it'll be more elegant to write smth like this
<div onReady=funcMyTransform(this)>...</div>
Instead of
<div id="MyElement">...</div>
<script type="text/javascript">
$(document).ready(function(){$("#MyElement").funcMyTransform()});
</script>
Is there such "onReady" attribute or something?
There is no onReady event. Depending on the functionality, you may want to abstract funcMyTransform out to a jQuery plugin. E.g.
jQuery.fn.funcMyTransform = function() {
alert(this.id);
};
jQuery(document).ready(function(){
jQuery("#MyElement").funcMyTransform(); // Alerts => "MyElement"
});
If you want access to the element as soon as its "ready", then placing your script at the bottom the document (before </body>) would probably be a better idea, and is definitely faster (albeit slightly) to initiate than jQuery's pseudo "ready" event.
As others have said, onWhatever attributes are "like so 1999" ;-). The general consensus among the modern Javascript community is that you should avoid using them as much as possible (for maintainability and other reasons).
That being said, there is a way to get something very similar to what you want in a much more maintainable fashion:
<div class="onReadyDoMyTransform">...</div>
<script type="text/javascript">
$(function(){$(".onReadyDoMyTransform").funcMyTransform()});
// $(someFunction) == $(document).ready(someFunction);
</script>
This approach will give you all the benefits of being able to decide what "transforms onReady" in your HTML layer, but without all the failings of an "onReady" attribute. The script part can just go in to a common JS include that you use throughout your site, so you don't have to worry about adding it along with every DIV.onReadyDoMyTransform.
Have you tried the jQuery ready?
$("#MyElement").ready(function(){$(this).funcMyTransform()});
I'm guessing this won't work but worth a shot?
Your suggestion that mixing code with the HTML as ... more elegant is arguable.
<div onReady=funcMyTransform(this)>...</div>
In general this is discouraged as it leads to maintenance problems. If I understood you correctly, on the onReady event being activated you want to call all these functions. One way to do it actually is to use a REL or anything else you might want to use as an expando attribute.
On document ready capture all the elements and read the attribute's value, then eval(). (People will tell you eval() is evil, but is quite harmless here).
$(document).ready(function(){
var v= $('.class_name').attr('rel');
eval(v);
})
It will actually eval() and activate all your javascript within your REL attributes.
I have used er (element-ready) by Stuart Colville before that is somewhat similar to what you are talking about, except for it's not an element attribute.
http://muffinresearch.co.uk/archives/2006/04/12/element-ready/
I have used this in an instance where I was returning some html via an XHR request and I wanted it to execute some javascript, but the dom had to be finished loading before I could execute it. Of course document ready didn't work, since the main document was already loaded.