Add a second onChange event? - javascript

Hi I found this script online that adds an onChange event to an element and I would like to now add a second onChange event to the same element. Heres the script:
document.getElementById('piname').onchange =
function() {
removeChildren({
parentId: 'account_table',
childName: 'extraaccount'
});
}
And the onChange event i want to add is:
showAccount(this.value)

Use addEventListener() (and attachEvent as a fallback, if needed).
Example:
document.getElementById('piname').addEventListener("change", function(e){
e = e || event;
showAccount(e.target.value);
}, false);
Example, with fallback:
var element = document.getElementById('piname');
if(element.addEventListener){
element.addEventListener("change", function(e){
e = e || event;
showAccount(e.target.value);
}, false);
}
else if(element.attachEvent){
element.attachEvent("onchange", function(e){
e = e || event;
showAccount(e.target.value);
});
}

The simplest way is to cache the old function and call it from the new one:
var el = document.getElementById('piname'),
old = el.onchange;
el.onchange = function () {
old.call(el);
showAccount(this.value);
}
Other than that, you could use addEventListener (W3C standards) and attachEvent (IE8 and lower):
var el = document.getElementById('piname'),
fn = function (e) {
e = e || window.event;
showAccount((e.target || e.srcElement).value);
};
if ("addEventListener" in el) {
el.addEventListener("change", fn, false);
}
else {
el.attachEvent("onchange", fn);
}
Those methods allow you to attach as many handlers to events as you like.

Related

Javascript interrupt normal behavior on link click momentarily

I want to do something before my page unloads so I'm trying to interrupt normal behaviour momentarily. I tried this but it doesn't seem to work:
document.onclick = function (e) {
e = e || window.event;
var element = e.target || e.srcElement;
if (element.tagName == `a`) {
document.body.classList.remove(`ready`);
document.body.classList.add(`leaving`);
setTimeout(function () {
return true; // return false = prevent default action and stop event propagation
}, 500);
}
}
0.5s is the time I need to display a short css animation before leaving the page.
You can try the following code:
document.onclick = function (e) {
e = e || window.event;
var element = e.target || e.srcElement;
if (element.tagName == `A`) { // !uppercased
e.preventDefault(); // prevent default anchor behavior
var goTo = element.href; // store target url
document.body.classList.remove(`ready`);
document.body.classList.add(`leaving`);
setTimeout(function () {
window.location = goTo; // navigate to destination
}, 500);
}
}

How to add multiple event listeners with selectors in one element?

Here is What I have now
I was trying to make an existing Jquery code into plain JS
var todoList = document.getElementById('todo-list');
todoList.addEventListener('change',this.toggle.bind(this),true);
todoList.getAttribute('.toggle');
todoList.addEventListener('dblclick', this.edit.bind(this),true);
todoList.getAttribute('label');
todoList.addEventListener('keyup', this.editKeyup.bind(this),true);
todoList.getAttribute('.edit');
todoList.addEventListener('focusout', this.update.bind(this),true);
todoList.getAttribute('.edit');
todoList.addEventListener('click', this.destroyCompleted.bind(this),true);
todoList.getAttribute('.destroy');
I think what you are trying to do is event delegation, to have this work in vanilla JS you need to write up a little function by yourself.
HTMLElement.prototype.on = function(event, selector, handler) {
this.addEventListener(event, function(e) {
let target = e.target;
if (typeof(selector) === 'string') {
while (!target.matches(selector) && target !== this) {
target = target.parentElement;
}
if (target.matches(selector))
handler.call(target, e);
} else {
selector.call(this, e);
}
});
};
You can then use this to handle your events. I don't have your Markup or the functions you are calling, but this should do the trick!
HTMLElement.prototype.on = function(event, selector, handler) {
this.addEventListener(event, function(e) {
let target = e.target;
if (typeof(selector) === 'string') {
while (!target.matches(selector) && target !== this) {
target = target.parentElement;
}
if (target.matches(selector))
handler.call(target, e);
} else {
selector.call(this, e);
}
});
};
const todoList = document.getElementById('todo-list');
todoList.on('change', '.toggle', this.toggle.bind(this));
todoList.on('dblclick', 'label', this.edit.bind(this));
todoList.on('keyup', '.edit', this.editKeyup.bind(this));
todoList.addEventListener('focusout', '.edit', this.update.bind(this));
todoList.addEventListener('click', '.destroy', this.destroyCompleted.bind(this));
This works fine, you can run and check it here.
mousemove = () => console.log('mousemove');
dblclick = () => console.log('dblclick');
click = () => console.log('click');
var todoList = document.getElementById('todo-list');
todoList.addEventListener('dblclick', dblclick.bind(this), true);
todoList.addEventListener('click', click.bind(this), true);
todoList.addEventListener('mousemove', mousemove.bind(this), true);
<div id="todo-list" style="height: 100px; width: 100px; background: yellow;"></div>

Event capturing jQuery

I need to capture an event instead of letting it bubble. This is what I want:
<body>
<div>
</div>
</body>
From this sample code I have a click event bounded on the div and the body. I want the body event to be called first. How do I go about this?
Use event capturing instead:-
$("body").get(0).addEventListener("click", function(){}, true);
Check the last argument to "addEventListener" by default it is false and is in event bubbling mode. If set to true will work as capturing event.
For cross browser implementation.
var bodyEle = $("body").get(0);
if(bodyEle.addEventListener){
bodyEle.addEventListener("click", function(){}, true);
}else if(bodyEle.attachEvent){
document.attachEvent("onclick", function(){
var event = window.event;
});
}
IE8 and prior by default use event bubbling. So I attached the event on document instead of body, so you need to use event object to get the target object. For IE you need to be very tricky.
I'd do it like this:
$("body").click(function (event) {
// Do body action
var target = $(event.target);
if (target.is($("#myDiv"))) {
// Do div action
}
});
More generally than #pvnarula's answer:
var global_handler = function(name, handler) {
var bodyEle = $("body").get(0);
if(bodyEle.addEventListener) {
bodyEle.addEventListener(name, handler, true);
} else if(bodyEle.attachEvent) {
handler = function(){
var event = window.event;
handler(event)
};
document.attachEvent("on" + name, handler)
}
return handler
}
var global_handler_off = function(name, handler) {
var bodyEle = $("body").get(0);
if(bodyEle.removeEventListener) {
bodyEle.removeEventListener(name, handler, true);
} else if(bodyEle.detachEvent) {
document.detachEvent("on" + name, handler);
}
}
Then to use:
shield_handler = global_handler("click", function(ev) {
console.log("poof")
})
// disable
global_handler_off("click", shield_handler)
shield_handler = null;

Making a JavaScript code works with any element

document.getElementById("but").onclick = showDropDown;
function showDropDown(e) {
document.getElementById("but").onclick = function() {};
if (e.stopPropagation) e.stopPropagation(); // W3C model
else e.cancelBubble = true; // IE model
document.getElementById("window").style.display = "inline-block";
document.onclick = function(e) {
var ele = document.elementFromPoint(e.clientX, e.clientY);
if (ele == document.getElementById("but")) {
hideDropDown();
return;
}
do {
if (ele == document.getElementById("window")) return;
} while (ele = ele.parentNode);
hideDropDown();
};
}
function hideDropDown() {
document.onclick = function() {};
document.getElementById("window").style.display = "none";
document.getElementById("but").onclick = showDropDown;
}​
<input id="but" type="button" value="pressMe" />
<div id="window" style="display:none">popup</div>
Demo: http://jsfiddle.net/nazym/
I was trying to make the JavaScript code dynamic using variables instead of the specified elements' names but I could not. It always returns errors. I want to link it with different elements.
update
I want to replace the ids of the elements in the JavaScript code with variables so I can use it with any element.I tried to do it but failed. Basically, I want to use variables instead of the ids of the element and link it to the elements somehow again.
Use arguments instead:
function showDropDown(element, e) {
element.onclick = function() {};
// ....
hideDropDown(element);
}
And you would give the element it's onclick event handler like this:
document.getElementById('but').onclick = function(event) {
showDropDown(this, event);
};
Demo: http://jsfiddle.net/xNSZm/
Change the code to
var showDropdown = function(e) { ... };
document.getElementById("but").onclick = showDropDown;
In other words, store the function in a variable before assigning it.
In your code:
> document.onclick = function(e){
In browsers that support the IE event model, e will be undefined. To accommodate those browsers, you can use:
e = e || window.event;
To find the element that was clicked on, instead of:
> var ele = document.elementFromPoint(e.clientX, e.clientY);
you can do:
var ele = e.target || e.srcElement;
which will work in very many more browsers than elementFromPoint so should be more reliable and faster.

Is there a way to pass a variable to keypressed function?

I am trying to send the document and the control that the key was pressed in to the keypressed function.
Here is my code:
//Namespace
MyExt.BrowserOverlay = {
init: function() {
var appcontent = document.getElementById("appcontent"); // browser
if(appcontent)
appcontent.addEventListener("DOMContentLoaded", MyExt.BrowserOverlay.onPageLoad, true);
},
onPageLoad: function(aEvent) {
var doc = aEvent.originalTarget;
if (doc.location.href == "http://something.com"){
var txtBox = doc.getElementById('txtBox');
txtBox.addEventListener('keypress', keypressed, false); //Error Line
}
},
…
something like:
txtBox.addEventListener('keypress', keypressed(?,doc), false);
function keypressed(a,doc){
alert(a); //a relates to keypress
alert(doc.innerHTML);
}
Easiest way to pass variable is to attach it to Element that will trigger event, but you can access document by using global variable document.
As for event listeners, browsers handle events differently:
txtBox.someVar = "foobar"; // Any variable you want to pass
if(window.addEventListener){ // Firefox, Chrome...
txtBox.addEventListener('keypress', keypressed, false);
} else { // IE
txtBox.attachEvent('onkeypress', keypressed);
}
function keypressed(event){
// find event object
var e = event || window.event;
// find target object
var target = e.currentTarget;
if (e.target) target = e.target;
else if (e.srcElement) target = e.srcElement;
if (target.nodeType == 3) target = targ.parentNode;
// find key code
var code = e.charCode || e.keyCode;
alert(String.fromCharCode(code));
alert(target.someVar);
alert(document.body.innerHTML);
}
You can use gBrowser.contentDocument to get the document of the currently selected tab. See this article on the tabbed browser control for more info.

Categories

Resources