Jump to content

update content via eventlistener


antidot

Recommended Posts

Hi, i really don´t know how to solve this, or why it isn't working...

 

first i try to grab all elements havung a specified class. no matter if it's 1 or 1000 elements.

After that all of those elements will have assigned an eventListener which then calls the function to replace the content from the clicked element in another specified element. (by taking and replacing inner html).

Usually i had the targetcontainer as 2nd argument in the eventlistener, but that didn't work at all.

See for yourself what happens.

Funny that when using the displayDate function everything works fine...

var spieler = document.getElementsByClassName("smallCard");
var i;
for (i = 0; i < spieler.length; i++) {
    console.log(this.innerHTML);
    spieler[i].addEventListener("click", ReplaceContentInContainer(spieler[i].innerHTML));
    }


function ReplaceContentInContainer(content) {
var container = document.getElementById("fc");
container.innerHTML = content;
}

    

function displayDate() {
    document.getElementById("fc").innerHTML = Date();
}
But like this it's working:

{
var spieler = document.getElementsByClassName("smallCard");
var i;
for (i = 0; i < spieler.length; i++) {
    spieler[i].addEventListener("click", ReplaceContentInContainer);
    console.log(spieler[i]);
    }
}


function ReplaceContentInContainer() {
document.getElementById("fc").innerHTML = this.innerHTML;
}
But i don't understand why !

Maybe someone could help me ou by explaining this to me.

Edited by antidot
Link to comment
Share on other sites

The console.log(this.innerHTML); won't work because what does does 'this' refers to, 'spieler[i].innerHTML' will be undefined because it will referring to a listing and index ref it has no knowledge of, as it is separated outside from the for loop that created it.

 

Create anonymous function and add function ref to that, and since the click element is the innerHTML you wish to target use 'this'

            var spieler = document.getElementsByClassName("smallCard");
            var i;
            for (i = 0; i < spieler.length; i++) {
                //console.log(this.innerHTML); work only if placed in click event function
                spieler[i].addEventListener("click", function() {
                    ReplaceContentInContainer(this.innerHTML);
                });
            }
  • Like 1
Link to comment
Share on other sites

 

...which then calls the function to replace the content from the clicked element in another specified element. (by taking and replacing inner html)...

 

So you have elements that you click on which have content that you want to replace. That is a fairly vague description. Where does this new content come from? Is it unique for each clicked item or all the same?

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>title</title>
<style>
#wrapper{
text-align:center;
width: 300px;
}
#wrapper,h3 {
border:1px solid red;
border-radius:10px;
}
.highlight{
background-color: #ff0;
}
h3{
cursor:pointer;
}
</style>
<script>
window.onerror = function(a,b,c){
alert('Javascript Error: '+a+'\nURL: '+b+'\nLine Number: '+c);
return true;
}
</script>
<script>
'use strict';
window.onload = init;

function init() {
document.getElementById('wrapper').addEventListener("click", replaceContent);
// or document.getElementById('wrapper').onclick = replaceContent;
}

function replaceContent(evt){
var ele = evt.target;
var cla = ele.className;
if (cla.indexOf('clkchg') != -1 && cla.indexOf('highlight') == -1){
 var d = ele.getAttribute('data-new');
 ele.innerHTML = d;
 ele.className += ' highlight';
}
}

</script>
</head>

<body>

<div id="wrapper">

<h3 class="clkchg" data-new="This is the new content for A.">This is original content A.</h3>
<h3 class="clkchg" data-new="This is the new content for B.">This is original content B.</h3>
<h3 class="clkchg" data-new="This is the new content for C.">This is original content C.</h3>
<h3 class="clkchg" data-new="This is the new content for D.">This is original content D.</h3>

</div>

</body>    
</html>
  • Like 1
Link to comment
Share on other sites

The console.log(this.innerHTML); won't work because what does does 'this' refers to, 'spieler.innerHTML' will be undefined because it will referring to a listing and index ref it has no knowledge of, as it is separated outside from the for loop that created it.

 

Create anonymous function and add function ref to that, and since the click element is the innerHTML you wish to target use 'this'

Thx for the help!

 

So you are saying, i have to create an anonymous function if i want to execute another Function and passing arguments?

 

usually my function looks like this:

 

 
function ReplaceContentInContainer(id,content) {
var container = document.getElementById(id);
container.innerHTML = content;
}

so when calling like so, it should work?

spieler[i].addEventListener("click", function() {
                    ReplaceContentInContainer("anyID", this.innerHTML);
}

I'm reading on mdn about addEventLister, but i still don't get it. Personally the "HOW" is very important to me.

Link to comment
Share on other sites

So you have elements that you click on which have content that you want to replace. That is a fairly vague description. Where does this new content come from? Is it unique for each clicked item or all the same?

 

I want to grab the content from an element i am clicking on to be displayed in another element.

Have to dig through your example...

appreciate the help

Link to comment
Share on other sites

Then maybe...

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>title</title>
<style>
#wrapper{
text-align:center;
width: 300px;
}
#wrapper,h3 {
border:1px solid red;
border-radius:10px;
}
.highlight{
background-color: #ff0;
}
h3{
cursor:pointer;
}
.clkchg:hover{
background-color:yellow;
}
</style>
<script>
window.onerror = function(a,b,c){
alert('Javascript Error: '+a+'\nURL: '+b+'\nLine Number: '+c);
return true;
}
</script>
<script>
'use strict';
window.onload = init;

function init() {
//document.getElementById('wrapper').onclick = replaceContent;
document.getElementById('wrapper').addEventListener("click", replaceContent);
}

function replaceContent(evt){
var ele = evt.target;
var cla = ele.className;
if (cla.indexOf('clkchg') != -1){
 document.getElementById('main').innerHTML = ele.innerHTML;
}
}
</script>
</head>

<body>

<div id="wrapper">

<h1 id="main">Hello</h1>

<h3 class="clkchg">This is item A.</h3>
<h3 class="clkchg">This is item B.</h3>
<h3 class="clkchg">This is item C.</h3>
<h3 class="clkchg">This is item D.</h3>

</div>

</body>    
</html>
  • Like 1
Link to comment
Share on other sites

Check out http://www.w3schools.com/jsref/met_document_addeventlistener.asp

 

under

 

'When passing parameter values, use an "anonymous function" that calls the specified function with the parameters:'

 

If you use function name with braces, with or without parameters it runs the function instantly, causing a 'undefined' error because it is referencing object.innerHTML, and not the object itself, but with a function name only it runs on actual click event only, and you add required parameters using a anonymous function.

Link to comment
Share on other sites

You can also use Function.bind:

 

spieler[i].addEventListener("click", ReplaceContentInContainer.bind(spieler[i], "anyID"));
The first parameter to bind is the object that you want to set to this, so when that functions runs this will be set to spieler.

 

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind

  • Like 1
Link to comment
Share on other sites

  • 3 weeks later...

Thx alot for all the help.
I am quite busy so i don`t have as much time as i would like to...

So far i am going with this solution:

function ReplaceContentInContainer(content, id) {
 
    var container = content.innerHTML;
    this.className = 'smallCard.current';
    document.getElementById(id).innerHTML = container;
       // console.log("CONSOLE TEST");
    }
{
var spieler = document.getElementsByClassName("smallCard");
for (var i = 0; i < spieler.length; i++) {
    spieler[i].addEventListener("click", (function(){ReplaceContentInContainer(this, "fc")}));
 
    }
}

while changing of the class for the clicked element isn`t aproblem, it appears to be much harder to change the class of another element...

 

All i want to do here is to set focus and remove the focus class from the element that had it before. So very common but i'm doing something wrong. I tried it with a for in loop, but as i read on mdn it seems to cause the problems i experience when iterrating over an array.

Would be great if anybody could help me out here too.

 

I removed the not working code already from my snippet... only the change of the classe is still there.

Link to comment
Share on other sites

Use classList to see if class exist, add or remove, it also shows fallback for crappy IE and its older crappy versions http://www.w3schools.com/jsref/prop_element_classlist.asp

 

Possible classList example

            function ReplaceContentInContainer(elem) {
                
                var container = document.getElementById("fc");
                container.innerHTML = elem.innerHTML;

                if (elem.classList.contains('current')) {
                    elem.classList.remove('current');

                }
                else {
                    for (var i = 0; i < spieler.length; i++) {
                        spieler[i].classList.remove('current');
                    }
                    elem.classList.add('current');
                }


            }
var spieler = document.getElementsByClassName("smallCard"); 
for (var i = 0; i < spieler.length; i++) 
{ 
spieler[i].addEventListener("click", function() { ReplaceContentInContainer(this); }); 
}
Edited by dsonesuk
  • Like 1
Link to comment
Share on other sites

Use classList to see if class exist, add or remove, it also shows fallback for crappy IE and its older crappy versions http://www.w3schools.com/jsref/prop_element_classlist.asp

@dsonesuk

 

thx alot for your help. Sometimes it's just hard to find the correct function, method or whatever...

 

if i would want to have the var spieler not as global, would it be better to construct the whole thing as an object so i have the methods present on any object or is there another way? (I'm sure there is)

 

kr

 

ps

if i get it right, your example isn't with fallback?

and is the IF statement necesary in this case? I understand it that if the class is present on the

actual element it gets removed and added again. So the work for removing on all other elemts is done by the ELSE part.

Edited by antidot
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...