I have an table, which is contructed in js and then appended to div on the page.
Each line has an inline event listener onclick()
var table = '<table>';
for (var i =0; i< 10; i++) {
table += '<tr onclick="myfunction()"><td></td></tr>'
}
table += '</table>'
$('#myDiv').html(table);
How can I use doulbe click event instead of single click in this construction?
EDIT:
I don't use delegation in this case because I have lot's of arguments (uniq for each row) which also constructed inline on each row. Table refreshes about 50 times a second, so it much easier to once construct inline function with all arguments, then setting noumerous listeners after table was appended to DOM.
I've tried both ways and inline in my case works much faster and is much cleaner to inderstand what should happen onclick.
Just change onclick to ondblclick.
But, using inline js is a bad idea.
Since you are using jquery, you can use event delegations.
Since one of the tags in your question is jQuery, I would resort to use jQuery for this task and would not hook up your event handlers directly in your DOM element.
$('#generatedTable').on('dblclick', 'tr', function() {
alert('tr is clicked');
});
Where generatedTable is the id of your table.
Using on will allow to respond to all double click of the generated trs
FIDDLE
The attribute you're looking for is called ondblclick, however do allow me to point out that it's bad to use event attributes like this, to quote MDN:
This way should be avoided. This makes the markup bigger and less readable. Concerns of content/structure and behavior are not well-separated, making a bug harder to find.
Source: https://developer.mozilla.org/en/docs/Web/API/Event#HTML_attribute
Related
EDIT #2:
Made a JS Fiddle... http://jsfiddle.net/N2p6G/ (I hardcoded some stuff that I'm certain works correctly, but the problem is still there)
Original:
So, I have written tens of thousands of lines of javascript, and used code that look like this a hundreds of times and I don't understand what's going on.
blacklistitembutton.onclick = function() {
console.log("clicked.");
}
The above code does not seem to be working... and I can't figure out why
In fact, I use the same method earlier in the same file... and it works fine!
settings.onclick = function() {
settings_popup.toggle();
}
EDIT:
Might it have something to do with the fact that it's being executed in a for loop?
Here is the code...
var blacklistButton = document.createElement('input');
blacklistButton.type = 'button';
blacklistButton.value = "Add Current Site to Blacklist";
blacklistButton.onclick = function() {
console.log('blacklistButton clicked');
}
for (var i=0;i<blacklist.length;i++) {
var blacklistitembutton = document.createElement('div');
blacklistitembutton.type = 'button';
blacklistitembutton.blacklistValue = blacklist[i];
blacklistitembutton.value = "X";
blacklistitembutton.onclick = function() {
console.log("clicked.");
}
}
Then both blacklistButton and all of the blacklistitembuttons are put into the document through element.appendChild (and they all show up successfully!)
The blacklistButton onclick fires just fine, and the blacklistitembutton onclick does not.
document.addEventListener('click', function(){
console.log('clicked');
}, false);
Edit:
Here is a re-write of your code in a fiddle: http://jsfiddle.net/N2p6G/1/
There are a lot of things in your code that worry me. Hopefully from my re-write you can see there are better ways to handle some things.
1) I'm not sure why you are using document.write() at the beginning. That has very little purpose.
2) You are modifying the DOM way too much. Some of the DOM elements you are creating in code are better-served as just being target locations in html. Only the dynamically-created input button elements need to be done in javascript. Remember, modifying the DOM should be done as little as possible.
3) Don't assign events using the onclick, onsubmit, onhover, etc syntax. Events should only be bound to DOM elements using addEventListener. The other benefit of doing it the proper way is that you can assign multiple events of the same type, if need be, to the same element. Also, with some extra state code that I haven't included, you can selectively remove particular events later if you need to.
4) There was a debate several years ago about whether using innerHTML and string templates was faster/better than using DOM creation methods. For a while, the best solution was to use documentFragments and a combination of the two methods. These days, it doesn't really matter anymore since all browsers are pretty damn fast, so for simplicity's sake is good to just go with innerHTML.
This also goes back to the rule of "don't touch the DOM too much". If you look at my code, you can see that I'm assembling the final html simply as an array of elements that gets joined as a single string at the end. Its then rendered to the DOM with a single innerHTML statement. I'm only touching the DOM one time, instead of multiple times.
5) The last bit goes into events again. At the beginning and end of the code you can see where and how I've added the events for the DOM elements. Indeed, the addEventListener at the beginning could be moved to the end to group all the event declarations together, but it doesn't really matter. I left it at the top to help you understand what's going on better.
Hope this helps.
For unlimited event bindings, either use addEventListener or attachEvent method. You cannot add more than one event of the same type using that traditional method.
I don't know if it's a typo in what you put here, but in the loop you are creating a "div" and then assigning it a type of "button". Does that work or is it throwing an error? If it is then that explains why the event handler is not getting the function. Try making it an "input" and see if it now works.
Fixed it!
blacklistitem.innerHTML += blacklist[i];
^ was messing it up, at this point in the code blacklistitem is still a javascript item, not yet appended to its to-be parent element in the document
So I just stuck blacklist[i] into a span tag and appended as a child and now it works fine :)
I have some html that is generated programmatically using javascript at runtime.
I want to be able to dynamically change the css properties of this html
e.g.
$(".pointsbox").css("background-color","green");
but it appears to not work as those html elements are not available at the time that the css change is called.
I am pretty sure I have managed to do this before but I've forgotten what the function is called.
Any help much appreciated!
You haven't posted code on how exactly you create your HTML elements, but it can be something as simple as this:
You can create an HTML element by passing HTML into the jQuery function right?
var new_element = $('<div>');
Well, you can treat that like any other jQuery object, and just manipulate its CSS right then and there.
var new_element = $('<div>').css('background-color', 'green');
Heck, you can even chain the create, the css change and the DOM insert in one call.
var new_element = $('<div>')
.css('background-color', 'green')
.appendTo('#container')
;
There are the Mutation events - specifically the DOMNodeInserted event - that you could bind an event handler to. However, as the page I linked states, it's recommended that you don't because it has a serious negative effect on the performance of your page and the cross-browser support isn't particularly good.
An alternative is to simulate your own DOMNodeInserted event using a custom event. Essentially you bind a handler for a custom event (say nodeinserted) on the document, then trigger that event whenever you have code that dynamically modifies the structure of your page. Code might look something like the following:
$(document).on('nodeinserted', function() {
$('.pointsbox').css('background-color', 'green');
});
function modifyPage() {
// code to modify your page here
$(document).trigger('nodeinserted');
}
Note that, with this approach, you'll need to modify all functions that add elements to the page to trigger that nodeinserted custom event.
I use this. It ensures the DOM has loaded.
$(document).ready(function(){
//code here
$(".pointsbox").css("background-color","green");
});
When appending HTML from a JSON reply, the event handlers appear to lose their event bindings. In using the .live() function the handler now appears to work.
$.each(result[0], function(i,wellList) {
$jsonResult = wellList["#name"];
$uid = wellList["#uid"];
$dynamicCheckBoxDiv += '<input type="checkbox" name="checkbox-1" value="'+ $uid
+ '" class="wellCheck" id="checkbox-'+i+'" />' +
'<label for="checkbox-'+i+'">' + $jsonResult + '</label>';
});
$dynamicCheckBoxDiv += '</fieldset></div>';
//Append results to div
$("#dynamicCheck").append($dynamicCheckBoxDiv).page();
$(".wellCheck").live('click', (function() {
This event now fires when the click function is run. However, after clicking the checkbox a few times, it randomly associates the checks with the wrong boxes and starts to fire the click event fire on a single click. Has anyone seen this before?
Also: How could I add a method to check all the boxes in a separate button? Since they are being added dynamically it seems to just bypass this function:
// When select No wells is clicked this method is run
$('#selectNone').click(function() {
$('#dynamicCheck .wellCheck').find(':checkbox').attr('checked', 'checked');
});
It enters the method, but doesnt seem to check any of the boxes. I have jQuery and jQuery mobile added to this page and both methods exist under document.ready.
You don't need to find(":checkbox") since the .wellCheck element is the checkbox. Just do this:
$("#selectNone").click(function(){
$("#dynamicCheck .wellCheck").prop("checked", true);
});
Demo.
Explanation of the first bit is that the written-into-HTML listeners only apply on page load. Any time you're adding raw HTML to the page, you have to set any listeners specifically. Similarly, just changing the "onclick" attribute does nothing to the listeners.
I suspect your problem with the second bit has something to do with the fact that, at least by my reading, '$(".wellCheck").live(...)' is going to affect every box you've created thus far each time. You might be better served by something like '$dynamicCheckBoxDiv.live(...)'
I'm not entirely clear on the precise syntax - I worked more with cloned HTML rather than manually constructed, so you may need an intervening step to render it into a DOM object or something (if it's not one already) - but I suspect something like this will help.
Also, you might wish to use '.click(...)', rather than '.live("click", ...)'.
You should use delegate not live:
$("#dynamicCheck").delegate('.wellcheck','click', function(){
//stuff on click
});
This would be better bound at that scope than at the body which is what live does.
EDIT: See this for some examples of checkbox management: http://jsfiddle.net/h682v/3/
That uses older attr() and should use prop() instead but the principle remains.
I've a web page fulfilled by a JS script that creates a lot of HTML tables.
Number of <table> created can vary between 1 and 1000 with 100 cells in each of it.
My question is : how to bind efficiently the click on theses tables? Should I bind the click on each cell of the <table> or directly to the <table> itself and retrieve the cell clicked in the bind function?
Or have you another idea?
P.S: I'm using IE6+
I suggest you use delegate.
$("table").delegate("td", "click", function(){
alert($(this).text()); // alert td's text.
});
delegate will just bind one event, and that is to the context(in this example, the <table>).
As it seems that you use jQuery, you should use the delegate() method on the table, e.g.:
$('table').delegate('td', 'click', function() {
// $(this) refers the the clicked cell
});
This will bind one event handler to the table and capture the bubbled up click events.
Binding so many event handlers, i.e. an event handler to every cell, is indeed not a good idea, especially not in IE (for performance reasons).
bind event on table for faster execution and get cell details inside that function.
you can find a similar toppic here:
large table with lots of events, is using event bubbling more effecient?
i would use this way:
$("table#yourTable").click(function(evt){
if($(evt.target).is('td')) {
//do whatever you want to do
}
})
I was wondering if there was a way of adding JavaScript in every occurrence of a certain HTML tag, e.g.
<td onmousedown="">
At the moment I just have it in every single one of my td tags in my table, but there must be a cleaner way. Something like adding JavaScript in the way CSS adds formatting.
What your looking for is most likely "event binding." This can be done via your script rather than embedded in the HTML code. There are lots of different ways to accomplish such a task, here is one of them using "td" as in your example.
var items = document.getElementsByTagName("td");
for (var i=0; i<items.length; i++) {
items[i].onmousedown = YourMouseDownFunction;
}
You want jQuery. See http://jQuery.org This can be accomplished using a "selector" (jquery term)
Add an event listener (See also: Quirks Mode on events and on event listeners) to your document looking for mousedown events and filter it on the basis of the originating element.
There is a good answer here on Stackoverflow as well.