Adding multiple javascript events programmatically
I have successfully added a form submit event code using the following:
if (window.addEventListener){
window.addEventListener('load', attachFormSubmit, false);
}else if (window.attachEvent){
window.attachEvent('onload', attachFormSubmit );
}
Now I have a textbox on the page text1 and I want to clear the value of it when it takes focus.
I tried adding the following:
function attachFocus()
{
var txt = document.getElementById("text1");
if (txt.addEventListener){
txt.addEventListener('focus', ClearText(txt.id), false);
}else if (txt.attachEvent){
txt.attachEvent('focus', ClearText(this.id));
}
}
function ClearText(id)
{
var obj = document.getElementById(id);
obj.value='';
}
And I added a call to attachFocus to the window load event:
if (window.addEventListener){
window.addEventListener('load', attachFormSubmit, false);
window.addEventListener('load', attachFocus, false);
}else if (window.attachEvent){
window.attachEvent('onload', attachFormSubmit );
window.attachEvent('onload', attachFocus );
}
So the code I added for the textbox focus event does not work. Can someone point out to me what am I doing wrong and also recommend a better way to add events via javascript. I do not want to use inline javascript
when you write ClearText(txt.id)
you are not passing the function
you are calling the function
You should write:
txt.attachEvent('focus', function() {clearText(txt.id);});
Or:
txt.addEventListener('focus', ClearText.bind(txt), false);
function ClearText() {
var obj = document.getElementById(this.id);
obj.value = '';
}
Related
I have a listener for keyup which will unload my javascript slideshow if an escape key is pressed.
window.addEventListener("keyup", this.escapekeyfn, false);
However, within the slideshow is the option to print an image using window.print()- but if the user presses escape while in that dialog, it is passed down to my listener and the slideshow exits.
Any way to prevent this in pure js? I've tried to find any event properties which can help me determine where the escape came from. originalTarget looked promising, but once a dialog is called, the originalTarget is changed to BODY ever more.
The Listeners
The escape key handling (the essential code for this)
slideshow.prototype.initslideshow = function(){
_this = this
....
this.escapekeyfn = function(e){ _this.escapekeycheck(e, _this)};
window.addEventListener("keyup", this.escapekeyfn, false);
....
}
The print button:
slideshow.prototype.printlink = function(){
var _this = this;
var a = document.createElement("a");
var img = document.createElement("img");
a.onclick = function(e){e.stopPropagation();window.print();return false};
....
}
slideshow.prototype.escapekeycheck = function(e, _this){
if (e.stopPropagation) e.stopPropagation();
if (e.keyCode == 27){
_this.ssclose(e);
}
}
The close function:
slideshow.prototype.ssclose = function(e) {
if (e.stopPropagation) e.stopPropagation();
// stop listening for escape key
window.removeEventListener("keyup", this.escapekeyfn);
return false;
}
I finally came across a way to solve this problem. I changed keyup to keypress
window.addEventListener("keypress", keypressFn, false);
For some reason, the keypress event is not sent to the window object whereas the keyup one is while the print dialog is open.
I want a function to be called whenever there is any change within my text area, i.e. char typed, removed, cut, pasted etc.
Currently I am using:
onkeyup || onmousemove = function();
This seems to only be calling onmousemove, what can I use to call my function on ANY change to the textarea.
I am creating this JS as a string to add it as a parameter to the creation of a text_area using codeigniteras described here at form_input section
e.g:
$js= 'onkeyup || onmousemove = "function()"';
echo text_area('name', " ", $js);
There's no way to combine multiple HTML attribute assignment, you have to do them separately. Try:
text_input('name', ' ', 'onkeyup="function()" onmousemove="function()"');
try this :
$('#element').on('keyup keypress blur change', function() {
...
});
Just give textarea an id say myId and bind events to it to trigger handler.
var element = document.getElementById("myId");
var myEvents = "oninput onchange onkeyup onpaste".split(" ");
var handler = function (e) {
};
for (var i=0, len = myEvents.length; i < len; i++) {
element.addEventListener(myEvents[i], handler, false);
}
Try something like below
Example
<textarea id='textarea1'>data</textarea>
//....................
$("textarea").bind('input propertychange', function(){
alert($(this).val());
});
Note: Use jquery plugin
DEMO
If you want to prevent simultaneous triggers then use the below code
<textarea id="textarea"></textarea>
//.......
var text = "";
$("#textarea").on("change keyup paste", function() {
var Val = $(this).val();
if(Val == text) {
return; //prevent multiple simultaneous triggers
}
text = Val;
alert("changed!");
});
DEMO2
This is really straight forward but I'm still fairly new to JavaScript and just found JSFiddle. I'm trying to find the element with the getElementById() to disable and enable a button. What am I missing?
<form name="frm" >
<div id="chkObj">
<input type="checkbox" name="setChkBx" onclick="basicList.modifyAndEnableButton(this)"></input>
</div>
<div id="Hello">
<input type="button" name="btn" value="Hello"></input>
</div>
</form>
This is a list that I am using to add checkboxes because there is going to be more than one:
var basicList = {
'items': {},
'modifyAndEnableButton': function(obj1) {
var element = document.getElementsByName("btn");
if (obj1.checked == true && element.getAttribute('disabled') == false) {
element.getAttribute('disabled') = true;
this.addRecord(obj2);
} else if (element.getAttribute('disabled') == true) {
if (hasItems == false) {
element.getAttribute('disabled') = false;
}
}
}
};
http://jsfiddle.net/Arandolph0/E9zvc/3/
All browsers support this (see example here):
mySelectedElement.onclick = function(e){
//your handler here
}
However, sometimes you want to add a handler (and not change the same one), and more generally when available you should use addEventListener (needs shim for IE8-)
mySelectedElement.addEventListener("click",function(e){
//your handler here
},false);
Here is a working example:
var button = document.getElementById("myButton");
button.addEventListener("click",function(e){
button.disabled = "true";
},false);
And html:
<button id='myButton'>Hello</button>
(fiddle)
Here are some useful resources:
addEventListener on mdn
The click event in the DOM specification
Click example in the MDN JavaScript tutorial
Benjamin's answer covers quite everything. However you need a delegation model to handle events on elements that were added dynamically then
document.addEventListener("click", function (e) {
if (e.target.id == "abc") {
alert("Clicked");
}
});
For IE7/IE8
document.attachEvent('onclick', function (e) {
if (window.event.srcElement == "abc") {
alert("Clicked");
}
});
You have a Error here
btnRush should be Rushbtn
This is a example of cross browser event's I just made (not tested) )
var addEvent = function( element, type, callback, bubble ) { // 1
if(document.addEventListener) { // 2
return element.addEventListener( type, callback, bubble || false ); // 3
}
return element.attachEvent('on' + type, callback ); // 4
};
var onEvent = function( element, type, callback, bubble) { // 1
if(document.addEventListener) { // 2
document.addEventListener( type, function( event ){ // 3
if(event.target === element || event.target.id === element) { // 5
callback.apply(event.target, [event]); // 6
}
}, bubble || false);
} else {
document.attachEvent( 'on' + type, function( event ){ // 4
if(event.srcElement === element || event.srcElement.id === element) { // 5
callback.apply(event.target, [event]); // 6
}
});
}
};
Steps
Create a function that accepts 4 values ( self explaining )
Check if the browser supports addEventListener
Add event on the element
else add event on the element for older IE
Check that the (clicked) element is = to the passed element
call the callback function pass the element as this and pass the event
The onEvent is used for event delegation.
The addEvent is for your standard event.
here's how you can use them
The first 2 are for dynamically added elements
onEvent('rushBtn', 'click', function(){
alert('click')
});
var rush = document.getElementById('rushBtn');
onEvent(rush, 'click', function(){
alert('click');
});
// Standard Event
addEvent(rush, 'click', function(){
alert('click');
});
Event Delegation is this basically.
Add a click event to the document so the event will fire whenever & wherever then you check the element that was clicked on to see if it matches the element you need. this way it will always work.
Demo
I need to temporarily change the click event for an element as follows:
var originalEvent = '';
$("#helpMode").click(function (e) {
originalEvent = $("#element").getCurrentClickEventHandler();
$("#element").click(function (e) {
//Do something else
});
});
//Later in the code
$("#helpModeOff").click(function (e) {
$("#element").click(originalEvent);
});
How would I store the current function that is an event handler in a global variable for later reuse?
EDIT: Here's what im trying to do:
var evnt = '';
$("#helpTool").click(function (e) {
if(!this.isOn){
evnt = $("#Browse").data('events').click;
$("#ele").unbind('click');
$("#ele").click(function (e) {
alert('dd');
});
this.isOn=true;
}else{
this.isOn = false;
alert('off');
$("#ele").unblind('click');
$("#ele").click(evnt);
}
});
Here you go, figured it out:
Now with e.srcElement.id you can get either HelpMode or HelpModeOff and then can turn on/off your help stuff!
http://jsfiddle.net/zcDQ9/1/
var originalEvent = '';
$('#element').on('yourCustomEvent', function (e) {
// do stuff
alert(originalEvent);
$(this).toggleClass('toggleThing');
//test for helpMode or helpModeOff here now...
});
$("#helpMode").on('click', function (e) {
originalEvent = e.srcElement.id;
$("#element").trigger('yourCustomEvent');
});
//Later in the code
$("#helpModeOff").on('click', function (e) {
originalEvent = e.srcElement.id;
$("#element").trigger('yourCustomEvent');
});
Okay. In jQuery 1.7 I guess it's a little different.
//get the handler from data('events')
$.each($("#element").data("events"), function(i, event) {
if (i === "click") {
$.each(event, function(j, h) {
alert(h.handler);
});
}
});
http://jsfiddle.net/yQwZU/
This is the reference.
Not sure if the following works with 1.7.
originalEvent = $('#element').data('events').click;
jQuery stored all the handlers in data. See here to learn more about data('events').
Personally, I think I would avoid manually binding and unbinding handlers.
Another way to approach this is to bind click events to classes, then all you need to do is add and remove classes from the appropriate elements when switching to/from help mode.
Here's a jsfiddle illustrating what I mean.
Switching to and from help mode then just involves adding removing classes:
$('#btnhelpmode').click(function(){
if(!helpMode){
helpMode = true;
$('.normalmode').addClass('helpmode').removeClass('normalmode');
$(this).val('Switch to normal mode...');
}else{
helpMode = false;
$('.helpmode').addClass('normalmode').removeClass('helpmode');
$(this).val('Switch to help mode...');
}
});
and you just create the handlers required, binding them to the appropriate classes:
$('#pagecontent').on('click', '#element1.normalmode', function(){
alert('element1 normal mode');
});
$('#pagecontent').on('click', '#element1.helpmode', function(){
alert('element1 help mode');
});
$('#pagecontent').on('click', '#element2.normalmode', function(){
alert('element2 normal mode');
});
$('#pagecontent').on('click', '#element2.helpmode', function(){
alert('element2 help mode');
});
Can somebody tell me what I am doing wrong?
window.onload = initForm;
function initForm() {
var allTags = document.getElementsByTagName("*");
for(i=0; i<allTags.length; i++) {
if (allTags[i].className.indexOf("textbox") > -1) {
allTags[i].onFocus = fieldSelect;
allTags[i].onBlur = fieldDeSelect;
}
}
}
function fieldSelect() {
this.style.backgroundImage = "url('inputBackSelected.png')";
}
function fieldDeSelect() {
this.style.backgroundImage = "url('inputBack.png')";
}
I am a beginner at JavaScript so I am not used to debugging code yet.
Thanks
Luke
Your problem lies in attaching your event handlers. You should bind to onfocus and onblur (note the lowercase event name).
As a suggestion, you may want to look at a very simple cross browser addEvent() with a quick line of code added to ensure the proper this pointer:
function addEvent(obj, evType, fn, useCapture){
if (obj.addEventListener){
obj.addEventListener(evType, fn, useCapture);
return true;
} else if (obj.attachEvent){
// fix added by me to handle the `this` issue
var r = obj.attachEvent("on"+evType, function(){
retrun fn.apply(obj, arguments);
});
return r;
} else {
alert("Handler could not be attached");
}
}
And then use the addEvent function instead of allTags[i].onfocus = you will probably have better mileage in the future binding events.
addEvent(allTags[i], 'focus', fieldSelect);
addEvent(allTags[i], 'blur', fieldDeSelect);
jsfiddle demonstration
The problem is that when fieldSelect and fieldDeselect are getting called, this refers to the window object, not to the element that fired the event. You might want to consider using jQuery:
$(document).ready(function() {
$('.textbox').focus(fieldSelect).blur(fieldDeselect);
});
function fieldSelect() {
$(this).css('background-image', 'url("inputBackSelected.png")');
}
function fieldDeselect() {
$(this).css('background-image', 'url("inputBack.png")');
}
jQuery takes care of making sure that when your event handlers are getting called, this refers to the element that fired the event.
Two things, the events should be all lower case (onfocus, onblur) and this doesn't point to the object that triggered the event in IE. Try this:
function fieldSelect(e) {
var event;
if(!e) {
event = window.event;
} else {
event = e;
}
event.target.style.backgroundImage = "url('inputBackSelected.png')";
}
function fieldDeSelect(e) {
var event;
if(!e) {
event = window.event;
} else {
event = e;
}
event.target.style.backgroundImage = "url('inputBack.png')";
}
Standards complient browsers will pass an event object to the event handler. IE uses a global window.event object instead. Either way you can use that object to get the target of the event that triggered the handler.
Another, probably preferable option would be to have your functions set and remove a className instead of directly changing the style. Then put a style called maybe selected in your stylesheet that overrides the background image. That way you keep style info and behavior separate.
Instead of window.onload=initform try window.onload=function(){/the init function/}
Also when refering to a function you should use () even if there are no arguments.