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.
Related
I'm used to writing in jQuery for selecting by class, however the following I can't quite get the code right. This lives on every page and should just intercept links with the class 'download-link'. The following works for all links. But i want to target it just for download-link css.
document.onclick = function (e) {
e = e || window.event;
var element = e.target || e.srcElement;
if (element.tagName == 'A') {
window.open(element.href, "_blank", "location=yes,toolbar=yes,toolbarposition=top");
return false;
}
};
I can't quite work out the selector for my if statement to change element.tagName to be element.class or similar.
Heres the last thing I tried
document.getElementById("download-link").addEventListener("click", function(e) {
window.open(e.href, "_blank", "location=yes,toolbar=yes,toolbarposition=top");
return false;
e.preventDefault();
});
You mention
should just intercept links with the class 'download-link'
though use .getElementById(). You can use .querySelectorAll() with selector ".download-link" and NodeList.prototype.forEach() to perform a task, see forEach method of Node.childNodes?. For example, attach an event listener, to each ".download-link" element
document.querySelectorAll(".download-link")
.forEach(function(element) {
element.addEventListener("click", function(event) {
// do stuff
})
})
If NodeList.prototype.forEach() is not defined at browser you can use for loop to achieve same result
for (var i = 0, nodes = document.querySelectorAll(".download-link");
nodes && i < nodes.length; i++) {
nodes[i].addEventListener("click", function(event) {
// do stuff
})
}
I am stuck on problem where I try to utilies the addEventListener.
I did try to find solutions on the web but I think my knowledge is to limited to pick the suitable answer.
What I tried is to invoke a function "addFile()" when a key is pressed in this example enter(13) unfortunatly nothing happens. I could add the onkeypress attribute to the input "add-file" with a slightly edited addFileOnKeyEvent(event) but I'm trying to understand what is wrong with my eventListener.
I hope you could follow my explanation, as this is my first question. :)
function addFile() {
var x = document.getElementById("add-file").value;
x = x + ".xml";
var lbl = document.createElement("label");
var node = document.createTextNode(x);
lbl.appendChild(node);
var element = document.getElementById("appendable");
element.appendChild(lbl);
}
function addFileOnKeyEvent(event) {
var evt = event.keyCode;
var textField = document.getElementById("add-file").addEventListener("keypress", function() {
if (evt == 13) {
addFile();
}
});
}
<label>Dateien</label>
<input id="add-file" type="text" onclick="this.select();">
<button type="submit" onclick="addFile()">Hinzufügen</button>
<div class="data-display">
<span id="appendable"></span>
</div>
At first, addFileOnKeyEvent() is never called before anywhere. So you must call it when you try to add file. Or you must bind the event to the text field by default.
Also need not pass event object to addFileOnKeyEvent(). The event must be captured in the addEventListener callback function.
function addFile() {
var x = document.getElementById("add-file").value;
x = x + ".xml";
var lbl = document.createElement("label");
var node = document.createTextNode(x);
lbl.appendChild(node);
var element = document.getElementById("appendable");
element.appendChild(lbl);
}
function addFileOnKeyEvent() {
document.getElementById("add-file").addEventListener("keypress", function(event) {
var evt = event.keyCode;
if (evt == 13) {
addFile();
}
});
}
// call the function here
addFileOnKeyEvent();
// else just put the event handler part alone. The function is unnecessary here.
<label>Dateien</label>
<input id="add-file" type="text" onclick="this.select();">
<button type="submit" onclick="addFile()">Hinzufügen</button>
<div class="data-display">
<span id="appendable"></span>
</div>
That's not how events work. Try this...
document.getElementById("add-file").addEventListener(
"keypress",
function(event) {
if (event.keyCode == 13) {
addFile();
}
});
Instead of...
function addFileOnKeyEvent(event) {
var evt = event.keyCode;
var textField = document.getElementById("add-file").addEventListener("keypress", function() {
if (evt == 13) {
addFile();
}
});
}
I've been playing with javascript to create a drop down list that shows a div depending on which option is selected.
All the code can be seen here:
http://jsfiddle.net/nmdTy/
var select = document.getElementById('test'),
onChange = function(event) {
var shown = this.options[this.selectedIndex].value == 1;
document.getElementById('hidden_div').style.display = shown ? 'block' : 'none';
};
I want to know how do I streamline this code and remove repetition - maybe some kind of loop?
Another code :
var select = document.getElementById('test'),
nbItems = 2,
onChange = function (event) {
var val = this.options[this.selectedIndex].value;
for (var i = 1; i <= nbItems; i++) {
document.getElementById('hidden_div' + i).style.display = val == i ? 'block' : 'none';
}
};
http://jsfiddle.net/nmdTy/11/
You don't need two event handlers, you can use variables (shown below) to determine which div needs to be displayed or hidden.
var select = document.getElementById('test'), onChange = function(event) {
var div1 = 'hidden_div';
var div2 = 'hidden_div2';
var index1 = this.options[this.selectedIndex].value == 1;
var index2 = this.options[this.selectedIndex].value == 2;
if(index1 || index2){
document.getElementById(div1).style.display = index1 ? 'block' : 'none';
document.getElementById(div2).style.display = index2 ? 'block' : 'none';
}
else{
document.getElementById(div1).style.display = 'none';
document.getElementById(div2).style.display = 'none';
}
};
// attach event handler
if (window.addEventListener) {
select.addEventListener('change', onChange, false);
} else {
// of course, IE < 9 needs special treatment
select.attachEvent('onchange', function() {
onChange.apply(select, arguments);
});
}
Working Fiddle
I'm not really sure what do you mean by "repetition" but my guess is, that you don't want to type every each of the divs to be hidden/shown.
There could be multiple approaches to such task. The most universal is to have the div id's in a separate array. Then you can hide all but the selected div.
var divs = ["hidden_div1", "special_hidden", "one_more_hidden"];
var select = document.getElementById('test');
var onchange = function(event) { //Use var!
var shown = this.options[this.selectedIndex].value;
for(var i=0; i<window.divs.length; i++) { //It would be more effective to save last shown div in a variable, but I've chosen this aproach with loop
var div = document.getElementById(window.divs[i]);
if(div!=null) {
if(i==shown)
div.style.display="block";
else
div.style.display="none";
}
}
};
select.addEventListener("change", onchange); //Could type the function right here, without using "onchange" variable
In my code, <option> value represents index in the array. Here is jsFiddle.
Delegating a change event in IE<9 is a pain. It is possible, check this question to see how it's done, but it's not what you call elegant.
But your code doesn't delegate the event, so just attaching the handler directly at the onload event should do the trick (and it's X-browser compatible):
document.getElementById('test').onchange = function(e)
{
e = e || window.event;//the only IE headache
var shown = this.options[this.selectedIndex].value == 1;
document.getElementById('hidden_div').style.display = shown ? 'block' : 'none';
//^^ could keep a reference to this in a closure
};
The full code (with onload and closure reference to hidden div and preventing memory leaks in ie) should look like this:
var winLoad = function(e)
{
var hiddenDiv = document.getElementById('hidden_div');
document.getElementById('test').onchange = function(e)
{
var shown = !!(this.option[this.selectedIndex].value == 1);//to be safe, coerce to bool
hiddenDiv.style.display = shown ? 'block' : 'none';
};
if (window.addEventListener)
{
return window.removeEventListener('load',winLoad,false);
}
return window.detachEvent('onload',winLoad);
};
if (window.addEventListener)
{
window.addEventListener('load',winLoad,false);
}
else
{
window.attachEvent('onload',winLoad);
}
that should work fine on all major browsers, even IE7 (probably IE6, too)
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.
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.