I have the script
<input type="text" name="name" value="Joe Bloggs" onfocus="this.value=''"/>
Just like I am doing with the onfocus="this.value…" can I change the background of the field (+ change other things?)
Also, does anyone have a better idea of how to do the script above, but so that the text reappears when the deselect it?
It's considered best practice to leave styling to CSS and logic to JS.
You can do this in css using the :focus pseudo-class. (http://www.quirksmode.org/css/focus.html) Unfortunately, it doesn't work in IE7 or lower. For those browsers, you can use javascript to add a class to the <input> to do the same thing.
CSS
input:focus, input.focus {background:#ff0}
If you are using jQuery, here is how you would do that.
$('input').focus(function(){
$(this).addClass('focus');
});
$('input').blur(function(){
$(this).removeClass('focus');
});
Something along the lines of
onfocus="this.value=''; this.style.backgroundColor='#f00'" onblur="this.style.backgroundColor='white'"
will get approximately what you want done simply, although it would also be possible for it to interact badly with presentation defined elsewhere and as such is probably rather crude to be considered a best practise.
Alternatively, you could as suggested add / remove a specific class to the element onfocus / onblur. At this point I would also second the jQuery recommendation: although it's hardly necessary just for this, you will find that it makes life with Javascript in general much more pleasant.
If you use jQuery, something like
$('input').focus(function() { $(this).addClass('focus') });
$('input').blur(function() { $(this).removeClass('focus') });
would allow you to cleanly define the appearance of focussed inputs in CSS. Consult jQuery documentation for the surrounding context necessary to make this work.
...id="name" onfocus = "javascript:yourFunction();"...
Then, your js looks something like this:
var inputFld = document.getElementById('name');<br/>
var oldval = inputFld.value;<br/>
var tempval = "";<br/>
function yourFunction(){
inputFld.value = tempval;<br/>
inputFld.className = "test" //(building from the first answer)<br/>
//do other stuff...<br/>
}
Then, you can also add an onblur="javascript:anotherFunction();" where anotherFunction() resets inputFld.value to the original value.
Note, best practices advise you should avoid those global vars and that you attach event listeners for the onblur and onfocus events rather than inlining them. But, at least, initially, you can see if this code as it is written works for you...
On your event, append the class name...
el.className+= 'test'
then set a background on that class in your css.
Related
Right now, every text box I make looks like this:
<input type="text" class="disableHotkeys">
Elsewhere, I have code that disables hot keys whenever an element of class "disableHotkeys" is focused on, and enables when all are blurred.
This all works fine, but I'd rather input elements were of class "disableHotkeys" by default as to clean up the code, and be less repetitive.
What I want is something like this:
default.css:
//don't use this code
input
{ include .disableHotkeys; }
Is there a way of doing this in the css?
If not, I imagine there is a way to add the class to everything with JQuery after page load, but it seems like bad form to set the class outside of the places developers would usually look (the html/php file, and maybe the css).
P.S. if you have a better title, it would be appreciated
Unfortunately, with CSS only, you're not able to do it. You need to use JS. I am giving you a jQuery example -
$(document).ready(function(){
$('input').addClass('disableHotkeys');
});
or
$(document).ready(function(){
$('input').each(function(){
$(this).addClass('disableHotkeys');
});
});
And also if you need to add class to all input then why dont put disableHotkeys class code to input?
If you want to add a class to all the text inputs on DOM ready:
$(document).ready(function(){
$( ":text" ).addClass("yourclassname");
});
Here is a demo fiddle.
I know this is bad practice. Don't write code like this if at all possible.
Of course, we'll always find ourselves in situations where a clever snippet of inline Javascript can address an issue quickly.
I am pursuing this query in the interest of fully understanding what happens (and the potential pitfalls) when something like this is written:
Click Me
As far as I can tell this is functionally the same as
<script type="text/javascript">
$(function(){ // I use jQuery in this example
document.getElementById('click_me').onclick =
function () { alert('Hi'); };
});
</script>
Click Me
Extrapolating from this it seems that the string assigned to attribute onclick is inserted within an anonymous function which is assigned to the element's click handler. Is this actually the case?
Because I'm starting to do things like this:
Display my next sibling <!-- Return false in handler so as not to scroll to top of page! -->
Which works. But I don't know how much of a hack this is. It looks suspicious because there is no apparent function that is being returned from!
You might ask, why are you doing this, Steve? Inline JS is bad practice!
Well to be quite honest I'm tired of editing three different sections of code just to modify one section of a page, especially when I'm just prototyping something to see if it will work at all. It is so much easier and sometimes even makes sense for the code specifically related to this HTML element to be defined right within the element: When I decide 2 minutes later that this was a terrible, terrible idea I can nuke the entire div (or whatever) and I don't have a bunch of mysterious JS and CSS cruft hanging around in the rest of the page, slowing down rendering ever so slightly. This is similar to the concept of locality of reference but instead of cache misses we're looking at bugs and code bloat.
You've got it nearly correct, but you haven't accounted for the this value supplied to the inline code.
Click Me
is actually closer to:
Click Me
<script type="text/javascript">
document.getElementById('click_me').addEventListener("click", function(event) {
(function(event) {
alert(this);
}).call(document.getElementById('click_me'), event);
});
</script>
Inline event handlers set this equal to the target of the event.
You can also use anonymous function in inline script
Click Me
What the browser does when you've got
<a onclick="alert('Hi');" ... >
is to set the actual value of "onclick" to something effectively like:
new Function("event", "alert('Hi');");
That is, it creates a function that expects an "event" parameter. (Well, IE doesn't; it's more like a plain simple anonymous function.)
There seems to be a lot of bad practice being thrown around Event Handler Attributes. Bad practice is not knowing and using available features where it is most appropriate. The Event Attributes are fully W3C Documented standards and there is nothing bad practice about them. It's no different than placing inline styles, which is also W3C Documented and can be useful in times. Whether you place it wrapped in script tags or not, it's gonna be interpreted the same way.
https://www.w3.org/TR/html5/webappapis.html#event-handler-idl-attributes
The best way to answer your question is to see it in action.
<a id="test" onclick="alert('test')"> test </a>
In the js
var test = document.getElementById('test');
console.log( test.onclick );
As you see in the console, if you're using chrome it prints an anonymous function with the event object passed in, although it's a little different in IE.
function onclick(event) {
alert('test')
}
I agree with some of your points about inline event handlers. Yes they are easy to write, but i don't agree with your point about having to change code in multiple places, if you structure your code well, you shouldn't need to do this.
It looks suspicious because there is no apparent function that is being returned from!
It is an anonymous function that has been attached to the click event of the object.
why are you doing this, Steve?
Why on earth are you doi.....Ah nevermind, as you've mentioned, it really is widely adopted bad practice :)
Try this in the console:
var div = document.createElement('div');
div.setAttribute('onclick', 'alert(event)');
div.onclick
In Chrome, it shows this:
function onclick(event) {
alert(event)
}
...and the non-standard name property of div.onclick is "onclick".
So, whether or not this is anonymous depends your definition of "anonymous." Compare with something like var foo = new Function(), where foo.name is an empty string, and foo.toString() will produce something like
function anonymous() {
}
using javascript:
here input element is used
<input type="text" id="fname" onkeyup="javascript:console.log(window.event.key)">
if you want to use multiline code use curly braces after javascript:
<input type="text" id="fname" onkeyup="javascript:{ console.log(window.event.key); alert('hello'); }">
For example, for accessibility reasons I want my onfocus and onmouseover to have identical values. For the sake of maintainability I want to declare this once only.
What I'd like to be able to do is this:
<a onmouseover,onfocus="assist('hello');">linktext</a>
But, of course, that would be too easy, and doesn't work. What's the best way I can achieve this DRYing out of my tags?
The better way is to move all your event handlers out of the HTML and into javascript.
<a id="some_id">link text</a>
(You don't need to use an ID, it's just for ease of demonstration.)
var link = document.getElementById('some_id');
link.onmouseover = link.onfocus = function() {
assist('hello');
};
If you wanted to take it to the next level, you could generalise it across many links. This example uses jQuery.
link text
another link
Then you apply the event handler to all the links in one go (very dry!)
$('a.assist').bind('mouseover focus', function() {
assist(this.href); // you'd need to clean up the href here, but you get the picture
});
Best I can think of is to use a function, set both events to call the function and put the common code in there.
Is there a way to determine when the contents of a HTML tag has changed? I would prefer to catch an event rather than polling it.
My use case is I have text enclosed in span tags within a rich text editor, and I need to remove the span tags when the enclosing text is modified by the user.
Are you using one of the typical WYSIWYG editors, and don't want to update their code to break updatability? Then maybe you could listen to the onTextChange event (or something similar) that the WYSIWYG editor is sending, check the contents of the change, and react on that.
Just an idea, given that you give a bit too little information in your question.
I don't think there is an event available (except for input elements), however you could poll it.
$element = $('#my-element');
var originalHtml = $element.html();
var pollHtml = setInterval(function() {
if (originalHtml !== $element.html()) {
alert('HTML changed!');
clearInterval(pollHtml);
};
}, 100);
I can't add a comment so I'm putting my suggestion here,
#Justin Johnson
$("#close-question-2114317").change(function() {alert(1);});
$("#close-question-2114317").text( function(){
$(this).trigger('change');
return "Close!!!";
});
I believe we can call the trigger if that's the case...
You must be using JavaScript to modify the DOM in some way. Polling is in most cases a bad idea. I have set up a demo here that gives you a good idea on how you might want to check the HTML for changes. Just call that function when needed... even if it is just polling.
To be specific, I'm talking about avoiding this type of code:
<input type='text' id='title_33' class='title'
onfocus='updateCharsLeft(33);'
onkeypress='updateCharsLeft(33);' />
Here I would like to put the onfocus and onkeypress event handles separately, i.e in a .js file. Like this:
$(document).ready(function()
{
$(".title").focus(updateCharsLeft);
$(".title").keypress(updateCharsLeft);
);
However here the problem is that the ID of the textbox needs to be passed onto the function updateCharsLeft(). It would suck to have to extract out the id from the ID of the textbox in that function, so it would actually be cleaner to just put in the event handlers within the HTML code.
Thoughts?
Can't you do this:
$(document).ready(function()
{
$(".title").focus(function() {
updateCharsLeft(this.id);
});
$(".title").keypress(function() {
updateCharsLeft(this.id);
});
);
or more neatly:
$(document).ready(function()
{
$(".title .another .someother .andAnother").focus(function() {
updateCharsLeft(this.id);
}).keypress(function() {
updateCharsLeft(this.id);
});
);
I've had to do something similar before and also wasn't happy with parsing the value out the ID attribute. The best thing I can suggest is that you use another attribute for the value you need, like the rel attribute:
<input type='text' id='title_33' class='title' rel='33' />
Or depending on how religious you are about validation, just use a custom attribute:
<input type='text' id='title_33' class='title' myval='33' />
I definitely think you should separate your JavaScript and HTML. It will be easier to find/maintain, and you can edit one place rather than 10. Don't repeat yourself.
I would look into using jQuery's live functionality. If you have 10 text input's, your adding 20 event handlers this way as opposed to 2 (one for EVERY focus handler on the page and one for EVERY keypress handler on the page).
Also re your comment to karim, I don't see why you would be duplicating yourself. It should be trivial to pass the id or transform it with a regular expression if necessary as long as your consistent in your naming convention For example, this.id.replace(/.*(\d+)$/,''). However, it would probably even be better to pass the direct DOM element reference instead, and work with that in your function.
Lastly, you seem to think that some aspect of this will suck. Maybe I'm missing the point, but can you clarify what's so difficult about mainupaliting the id or the DOM reference or whatever else that you need to do? Maybe post a longer code sample of what you're doing next.
If you really don’t want to pass this.Id then you could add a custom attribute to the input tag...
<input type='text' id='title_33' idSuffix='33' class='title'/>
You then set the event handlers like this...
$(document).ready(function()
{
$(".title").focus(function() {
updateCharsLeft(this.idSuffix);
});
$(".title").keypress(function() {
updateCharsLeft(this.idSuffix);
});
);
I personally like custom attributes. They provide a way to give Html tags custom metadata and keep it all in the markup. Html validators don’t like them though :-(
I would try to manage the all events from a single JavaScript block. As long as you are able to reference elements on the page, this should be possible.
You could always use the string functions to parse out the value and pass it along, e.g.
$(".title").focus(function() {
var thisid = this.id;
updateCharsLeft(thisid.substring(thisid.indexOf("_") + 1));
});
I'm not sure what the performance implications would be if you had to do this for a lot of elements though.
$(document).ready(function(){
var update = function(){ updateCharsLeft(this.id.split("_")[1]); };
$("input.title")
.focus(update)
.keypress(update);
});
This is exactly what Unobtrusive Javascript technique focuses on.