I have found various scripts and put together to try and achieve this.
The script below should register event listeners on load, but I am trying to do it for when I need multiple items with the same class name, e.g. a tooltip, or to ensure every button on the site had an Ajax loading image applied.
I believe I have everything sorted except ‘the add_event_multiple_classes’ function in my script.
Please help complete this and is this the best way to do it? It seem a lot easy to just use inline JS considering how much code this is taking.
if (typeof getElementsByClassName !== "function") {
function getElementsByClassName(findClass, parent) {
parent = parent || document;
var elements = parent.getElementsByTagName('*');
var matching = [];
for(var i = 0, elementsLength = elements.length; i < elementsLength; i++){
var regex = new RegExp('\\b' + findClass + '\\b')
if (elements[i].className.match(regex)) {
matching.push(elements[i]);
}
}
return matching;
}
}
if (window.addEventListener)
addEvent = function(ob, type, fn ) {
**ob.addEventListener(type, fn, false );
};
else if (document.attachEvent)
addEvent = function(ob, type, fn ) {
**var eProp = type + fn;
**ob['e'+eProp] = fn;
**ob[eProp] = function(){ob['e'+eProp]( window.event );};
**ob.attachEvent( 'on'+type, ob[eProp]);
};
function on_load_scripts() {
//set some event listeners
addEvent(document.getElementById('an-id'), 'click', some_javascript);
add_event_multiple_classes ( 'submit-button', 'click', button_loading_image );
}
function add_event_multiple_classes(class, action, fn) {
// THIS IS THE AREA I AM STRUGGLING ON
//somehow get hold of all the classes with the provided class name and convert so
//they can all be referenced and have an event listener registered to them.
// What about searching for all matching class names and adding a unique id next to it (how would I do this?)
/// ??????????????????????????
for/foreach() { // for every class with the 'class' name
addEvent(xxxxxxxxxxx, action, fn);
}
}
function some_javascript() {
//perform action
}
function button_loading_image() {
//perform action
}
addEvent(window, 'load', on_load_scripts);
The add_event_multiple_classes function can make good use of the getElementsByClassName function, wich will give you an array of elements that match the class name. YOu can then loop through those elements applying the event function to them.
The problem is I want to use a variable instead of your_function.
Somehow I need the value in a variable to be the function name (so I have: var $a = “my_function”; and I want to execute the function named ‘my_function’ from this)
(2) I also understand the mouse event is passed automatically to the function.
So in this: document.addEventListener(‘load’, your_function, false);
…it’s automatically passed to ‘your_function’.
I need to get the div/tag anything that was clicked on so I can then go and do:
x.className = ‘new_class_name’; (with x being the reference to what was clicked on).
As for the first one, I don;t really want to do it as a variable it’s just that my script ended up that way.
This is what I have:
var events_list = new Array();
events_list['click'] = "perform_action";
events_list['mouseover'] = "something_else";
add_event_multiple_classes ( 'class-name', 'new-id-name', events_list );
function add_event_multiple_classes(classNm, new_id_name, events_list) {
counter = 1;
var elements = getElementsByClassName(document, classNm),
n = elements.length;
for (var i = 0; i < n; i++) {
var e = elements[i];
this_new_id_name = new_id_name + "_" + counter++;
//add id element to it
e.id = this_new_id_name;
//add events
for (action in events_list) {
fn = events_list[action];
addEvent(document.getElementById(this_new_id_name), action, **** THIS NEEDS TO BE THE VALUE IN VARIABLE fn *****);
}
}
}
function perform_action() {
}
function addEventsToElement(el, eventsList) {
var action;
for (action in eventsList) {
if (eventsList.hasOwnProperty(action)) {
addEvent(el, action, eventsList[action]);
}
}
}
function addEventMultipleClasses(className, eventsList) {
var elements = getElementsByClassName(document, className),
elementsLength = elements.length,
i;
for (i = 0; i < elementsLength; i += 1) {
addEventsToElement(elements[i], eventsList);
}
}
function performAction() {
}
function somethingElse() {
}
addEventMultipleClasses('class-name', {
click: performAction,
mouseover: somethingElse
});
As an example of one of the changes, you shouldn’t declare variables in the middle of a function. Even when they’re declared in the middle, their declaration is automatically hoisted to the top of the function. So to reduce confusion, always declare variables in one block at the start of the function.
I thought it best to continue this thread as my new question partly relates to this.
I simply want to create a standard HTML link but also append JS functionality.
<a href=“?page=2”>Show More</a>
I want to use the code above to append a simple show_more() function, which I can do but it always fires the ?page=2 part after running the JS. I know a simple onclick=“return false” sorts this out but considering I’m trying to do this properly that obviously should;t be used.
If I do this:
function show_more() {
//the show more code
return false;
}
…then the return false in the function does nothing.
Where do I put the return false to prevent the HTML hyperlink from firing if JS is enabled?
That depends on how you are attaching the show_more function to the event.
The most appropriate way is to attach it to the onclick event of the link itself. Not via an inline HTML event attribute, but via scripting instead.
<a id="showmore" href="?page=2">Show More</a>
function show_more() {
...
}
document.getElementById('showmore').onclick = show_more;
Notice that it’s show_more without parenthesis that is assigned to the onclick event.
If it were show_more() with the parenthesis, then you would be assigning to the event the returned value from the function, that being undefined or false, depending on if the function returns nothing or false.
So instead, by assigning just a reference to the function itself to the onclick event, the function can return false to prevent the default behaviour (of the web browser following the link) from occurring.
I am hoping to use the code you posted on Dec 23, 2011 at 20:24 in this topic.
Hopefully, I can just add this to the set of code:
<script>
addEventsToElement ('js-show-more', {click: show_more} ); // note, I definitely use show_more and not show_more()
function show_more() {
// do the show more stuff
return false;
}
</script>
<a href="?pg=2" class="js-show-more">SHOW MORE</a>
…If I do this, the JS runs, but it also fires the ?pg=2 part. Is it possible to do this with the set of code you provided rather than using document.getElementById(‘showmore’).onclick = show_more; (although I would guess both should do the same thing, so I’m a little confused there)?
Can you put up a sample page so that some testing can occur? There is a jsfiddle.net. If you do, in the choose framework part on the left, change onload to no wrap (body) and change mootools to be instead no library.
Oh that’s right, you’re using the advanced event registration technique here, which is hampered by a Microsoft problem.
On Internet Explorer when attachEvent is used, the this keyword becomes broken and points to the window object, instead of the element that triggered the event.
So, we can make use of either the preventDefault() method from the event, or for IE we can set the returnValue property on the event itself.
It would be, yes. Although you may want to change the function name from return_false to prevent_default, or some other name that more appropriately describes the purpose of the function.
That way, you’ll have a better way to understand what the code is doing, without needing to track down and study the function, when you see:
The only way I can think of is to include values from PHP in a hidden text field and call them from the function that the above snippet runs (so in this case the function is called ‘run_test’).