I'm working in a little app, mostly using jquery, everything is working fine but I'd like to rewrite every jquery part with plain javascript to fully understand what I'm doing.
I've read this previus post, and everything makes perfect sense but I can't get any code to run in my browser.
How to select all <a> tag and register onclick event?
This is my code:
<html>
<head>
<script type="text/javascript">
var a = document.getElementsByTagName('a');
var f = function () {alert('ok');}
for (var i = a.length - 1; i >= 0; i--) {
a[i].onClick = f;
}
</script>
</head>
<body>
test1
test2
</body>
</html>
In jquery I'd simply use this to find all anchors and run my function when clicked:
$('a').on('click',function (){
alert('ok');
});
Any thoughts?
thanks in advance, Gustavo
This is how I would do it:
var anchors = document.querySelectorAll("a"),
i;
for (i=0; i<anchors.length; i+=1) {
anchors[i].addEventListener("click", function() {
alert("triggered!");
});
}
test1
test2
Here's a shorter version if browser supports Array.prototype.forEach (most modern browsers do)
var anchors = document.querySelectorAll("a");
anchors.forEach(function(a) {
a.addEventListener("click", function() {
alert("triggered!");
});
});
test1
test2
Related
This question already has answers here:
JavaScript closure inside loops – simple practical example
(44 answers)
Closed 7 years ago.
I'm using a plugin that uses jQuery(document).on() to activate a modal. I have a bunch of modals on the page.
If I manually create an .on for each modal opening/closing everything works as
jQuery(document).on('opened', '[data-remodal-id=modal-1]',
function() {
player1.api('play')
});
jQuery(document).on('closed', '[data-remodal-id=modal-1]',
function(e) {
player1.api('unload')
});
jQuery(document).on('opened', '[data-remodal-id=modal-2]',
function() {
player2.api('play');
});
jQuery(document).on('closed', '[data-remodal-id=modal-2]',
function(e) {
player2.api('unload');
});
However this is a managed page, that could need 2,3 or 10 modals with their own content. I'm trying to do what I did above, only dynamically. Here's my attempt, and I can see why it doesn't work, but I have no idea how to approach this properly.
var countPlusOne;
for (i=0;i<players.length;i++){
countPlusOne=i+1;
var dataSelector = '[data-remodal-id=modal-'+countPlusOne+']';
jQuery(document).on('opened', dataSelector, function () {
players[i].api('play');
});
jQuery(document).on('closed', dataSelector, function (e) {
players[i].api('unload');
});
}
Hopefully it gives you some idea of what i'm trying to do? Is it even possible?
Per my understanding, you have dynamic elements and have to bind events to them.
You can try something like this:
var count = 1;
function addInput(){
var content = document.getElementById("content");
var input = "<input id='txt_"+count+"' class='input'>";
count++;
content.innerHTML+=input;
}
function registerEvents(){
$(document).on("blur", ".input", function(){
console.log($(this).attr("id"));
})
}
registerEvents();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<div id="content"></div>
<button onclick="addInput()">Add input</button>
If playerX are global vars, you could refactorize your code to this:
jQuery(document).on('opened closed', '[data-remodal-id]', function (e) {
window["player" + $(this).data("remodalId").replace('modal-' ,'')].api(e.type === "opened" ? 'play' : 'unload');
});
But i guess you don't need all this different playerX variables anyway.
Ultimately, your api() should handle player id and it would be called like that e.g:
player.api(1, 'play');
EDIT: Ok i'm miss this part in OP
I'm using a plugin
So you shouldn't override api() method.
EDIT2: to answer your question, using closure, you could use:
var countPlusOne;
for (i = 0; i < players.length; i++) {
(function(i) {
countPlusOne = i + 1;
var dataSelector = '[data-remodal-id=modal-' + countPlusOne + ']';
jQuery(document).on('opened', dataSelector, function() {
players[i].api('play');
});
jQuery(document).on('closed', dataSelector, function(e) {
players[i].api('unload');
});
})(i);
}
<p>Success login. You will be redirected in <span class="counter">10</span> second(s).</p>
<p>Wrong username/password. You will be redirected in <span class="counter">10</span> second(s).</p>
<script type="text/javascript">
function countdown() {
var i = document.getElementByClassName('counter');
if (parseInt(i.innerHTML)<=0) {
location.href = 'login.php';
}
i.innerHTML = parseInt(i.innerHTML)-1;
}
setInterval(function(){ countdown(); },1000);
</script>
Before it was id=counter, and it works for one span tag. But I want two tags to share the same function. I tried changing it to getElementByClassName but it doesn't work. Can anyone tell me why?
There is no function getElementByClassName(), but just getElementsByClassName() (Note the plural for element*s*!). This returns a NodeList, which you then have to traverse:
function countdown() {
var i = document.getElementsByClassName('counter');
for( var j=0; j<i.length; j++ ) {
if (parseInt(i[j].innerHTML)<=0) {
location.href = 'login.php';
}
i[j].innerHTML = parseInt(i[j].innerHTML)-1;
}
}
setInterval( countdown,1000);
PS: In your setInterval() you do not need a function expression - just give it a reference to the function itself (without calling it!).
document.getElementsByClassName('counter') will return an array.
'getElements' - So to target an element in that array would be like :
document.getElementsByClassName('counter')[0]
or loop through them :
var counters = document.getElementsByClassName('counter');
for(var i=0, len=counters.length; i<len; ++i) {
counters[i].innerHTML = 'I am content ' +i;
}
Edit : - note the 'getElement s ByClassName' ( plural elements ) as others have pointed out
There's no getElementByClassName(); in Javascript. You should use getElementsByTagName();
Or, use jQuery selector $('.counter'); (need jQuery library).
For more information, look at [this][1].
window.onload = init;
function init(){
var allSelect = document.getElementsByTagName("option");
for (var i = 0; i < allSelect.length; i++){
allSelect[i].onchange = loadLink;
}
}
function loadLink(){
alert("TEST");
}
So I'm working on this problem for a class and the functions are incredibly simple. I replaced the code needed with a simple alert because even tracking break point by point it doesn't run the loadLink() function. AllSelect is populated and are all have the onchange value with the specified code in the {}.
I have also tried putting it into the html element by hand and it still doesn't work.
Any Ideas? I'm running locally on my computer with both IE and Chrome if anyone cares to know. Thanks ahead of time.
The onchange event belongs on the select element, not the option elements. So:
window.onload = init;
function init(){
var allSelect = document.getElementsByTagName("select");
for (var i = 0; i < allSelect.length; i++){
allSelect[i].onchange = loadLink;
}
}
function loadLink(){
alert("TEST");
}
I think you want
var allSelect = document.getElementsByTagName("select");
You are instead querying the option elements within selects in the DOM.
I have in Javascript:
for ( i=0; i < parseInt(ids); i++){
var vst = '#'+String(img_arr[i]);
var dst = '#'+String(div_arr[i]);
}
How can I continue in jQuery like:
$(function() {
$(vst).'click': function() {
....
}
}
NO, like this instead
$(function() {
$(vst).click(function() {
....
});
});
There are other ways depending on your version of jquery library
regarding to this, your vst must need to be an object which allow you to click on it, and you assign a class or id to the object in order to trigger the function and runs the for...loop
correct me if I am wrong, cause this is what I get from your question.
$(function() {
$(vst).click(function() {
....
}
})
You can use any string as element selector param for jQuery.
Read the docs for more information.
http://api.jquery.com/click/
http://api.jquery.com/
You can pass a String in a variable to the $() just the way you want to do it.
For example you can do:
var id = 'banner';
var sel = '#'+id;
$(sel).doSomething(); //will select '#banner'
What's wrong is the syntax you are using when binding the click handler. This would usually work like:
$(sel).click(function(){
//here goes what you want to do in the handler
});
See the docs for .click()
Your syntax is wrong, but other than that you will have no problem with that. To specify a click:
$(function() {
for ( i=0; i < parseInt(ids); i++){
var vst = '#'+String(img_arr[i]);
var dst = '#'+String(div_arr[i]);
$(vst).click(function (evt) {
...
});
}
})
Note that since vst is changing in the loop, your event code should also be placed in the loop.
EDIT: Assuming you want the same thing to happen for each image and each div, you could also do something like this:
$(function () {
function imgEventSpec($evt) {
// image clicked.
}
function divEventSpec($evt) {
// div clicked.
}
for (var idx = 0; idx < img_arr.length && idx < div_arr.length; idx ++) {
$("#" + img_arr[idx]).click(imgEventSpec);
$("#" + div_arr[idx]).click(divEventSpec);
}
});
I am searching for a way where I can list all event-listener bindings that are made with JS (or other scripts as well) on a website. Mainly I want to find out double bindings (for debug reason), but I guess there are other issues for it as well.
Brilliant would be a plugin for the browser, where you can see on the website which elements have which kinds of eventlisteners bound. You know, some visualization of the event-listeners...
Visual Event (http://www.sprymedia.co.uk/article/Visual+Event+2) is very helpful. Go to this page and just drag the "Visual Event" link into your bookmark bar. When you want to check a page, just click it, wait a second, and the events for each element will be overlaid on the page.
There's only one type of event declaration that you get it, I don't know if this will help you:
// Can't get
myDiv.attachEvent ("onclick", function () {alert (1)});
// Can't get
myDiv.addEventListener ("click", function () {alert (1)}, false);
// Can't get
<div onclick = "alert (1)"></div>
// Can get
myDiv.onclick = function () {alert (1)}
You may look this answer too. Anyway I made a function for you:
<!DOCTYPE html>
<html>
<head>
<script>
function getAllEvents () {
var all = document.getElementsByTagName ("*");
var _return = "";
for (var i = 0; i < all.length; i ++) {
for (var ii in all[i]) {
if (typeof all[i][ii] === "function" && /^on.+/.test (ii)) { // Unreliable
_return += all[i].nodeName + " -> " + ii + "\n";
}
}
}
return _return;
}
document.addEventListener ("DOMContentLoaded", function () {
var div = this.getElementsByTagName ("div")[0];
div.onclick = function () {
alert (1);
}
div.onmouseout = function () {
alert (2);
}
alert (getAllEvents ());
}, false);
</script>
<style>
div {
border: 1px solid black;
padding: 10px;
}
</style>
</head>
<body>
<div></div>
</body>
</html>
I just wrote a script that lets you achieve this. It gives you two global functions: hasEvent(Node elm, String event) and getEvents(Node elm) which you can utilize. Be aware that it modifies the EventTarget prototype method add/RemoveEventListener, and does not work for events added through HTML markup or javascript syntax of elm.on_event = ..., works only for add/RemoveEventListener.
More info at GitHub
Live Demo
Script:
var hasEvent,getEvents;!function(){function b(a,b,c){c?a.dataset.events+=","+b:a.dataset.events=a.dataset.events.replace(new RegExp(b),"")}function c(a,c){var d=EventTarget.prototype[a+"EventListener"];return function(a,e,f,g,h){this.dataset.events||(this.dataset.events="");var i=hasEvent(this,a);return c&&i||!c&&!i?(h&&h(),!1):(d.call(this,a,e,f),b(this,a,c),g&&g(),!0)}}hasEvent=function(a,b){var c=a.dataset.events;return c?new RegExp(b).test(c):!1},getEvents=function(a){return a.dataset.events.replace(/(^,+)|(,+$)/g,"").split(",").filter(function(a){return""!==a})},EventTarget.prototype.addEventListener=c("add",!0),EventTarget.prototype.removeEventListener=c("remove",!1)}();