-2

Lately, I've been trying to use pure JavaScript instead of jQuery. As I've read more and more about pure JS, I didn't think it was that hard, or that much of a difference in the actual code, and of course it's a little bit faster.

This was until today, when I converted a whole 70-line script from jQuery to JavaScript, and although I've checked my new code for errors on jslint.com, it won't work. Before posting the code, and the difference, what I essentially did was to convert .on("change" with .addEventListener("change" along with replacing other jQuery functions and selectors.

Part of the working jQuery code:

jQuery("form.abo input").change(function() {
if(jQuery("#likerdudanse input[value='ja']").is(":checked") || jQuery("form input[value='Tilknyttet en danseklubb']").is(":checked")) {
    jQuery("#jeglikerdanse").removeAttr("style");
    if(jQuery("form input[value='Tilknyttet en danseklubb']").is(":checked")) {
        jQuery("#likerdudanse").hide();
    }
    else {
        jQuery("#likerdudanse").removeAttr("style");
    }
}
else {
    jQuery("#jeglikerdanse").hide();
    jQuery("#likerdudanse").removeAttr("style");
}
if(jQuery("form fieldset:first-child input[value='bestille et abonnement']").is(":checked")) {
    jQuery("#hardukode").removeAttr("style");
    jQuery("#tskjorte").removeAttr("style");
    if(jQuery("#hardukode input[value='ja']").is(":checked")) {
        jQuery("#hardukode label:last-of-type, #hardukode br, #hardukode > input:last-of-type").removeAttr("style");
        jQuery("#tskjorte").hide();
    }
    else {
        jQuery("#hardukode label:last-of-type, #hardukode br, #hardukode > input:last-of-type").hide();
        jQuery("#tskjorte").removeAttr("style");
    }
    if(jQuery("#tskjorte input[value='ja']").is(":checked")) {
        jQuery("#tskjorte #i, #tskjorte #j, #tskjorte label[for='i'], #tskjorte label[for='j'], #tskjorte br").removeAttr("style");
    }
    else {
        jQuery("#tskjorte #i, #tskjorte #j, #tskjorte label[for='i'], #tskjorte label[for='j'], #tskjorte br").hide();
    }
}
else {
    jQuery("#hardukode").hide();
    jQuery("#tskjorte").hide();
}
}).change();

My new trying-so-hard pure JavaScript code that doesn't work at all.

document.querySelector("form#abo input").addEventListener("change", function(){
if(document.querySelector("form fieldset:first-child input[value='bestille et abonnement']:checked")) {
    document.getElementById("hardukode").removeAttribute("style");
    document.getElementById("tskjorte").removeAttribute("style");
    if(document.querySelector("#hardukode input[value='ja']:checked")) {
        document.querySelectorAll("#hardukode label:last-of-type, #hardukode br, #hardukode > input:last-of-type").removeAttribute("style");
        document.getElementById("tskjorte").style.display = "none";
    }
    else {
        document.querySelectorAll("#hardukode label:last-of-type, #hardukode br, #hardukode > input:last-of-type").style.display = "none";
        document.getElementById("tskjorte").removeAttribute("style");
    }
    if(document.querySelector("#tskjorte input[value='ja']:checked")) {
        document.querySelectorAll("#tskjorte #i, #tskjorte #j, #tskjorte label[for='i'], #tskjorte label[for='j'], #tskjorte br").removeAttribute("style");
    }
    else {
        document.querySelectorAll("#tskjorte #i, #tskjorte #j, #tskjorte label[for='i'], #tskjorte label[for='j'], #tskjorte br").style.display = "none";
    }
}
else {
    document.getElementById("tskjorte").style.display = "none";
    document.getElementById("hardukode").style.display = "none";
}
if(document.querySelector("#likerdudanse input[value='ja']:checked") || document.querySelector("form input[value='Tilknyttet en danseklubb']:checked")) { 
    document.getElementById("jeglikerdanse").removeAttribute("style");
    if(document.querySelector("form input[value='Tilknyttet en danseklubb']:checked")) {
        document.getElementById("likerdudanse").style.display = "none";
    }
    else {
        document.getElementById("likerdudanse").removeAttribute("style");
    }
}
else {
    document.getElementById("jeglikerdanse").style.display = "none";
    document.getElementById("likerdudanse").removeAttribute("style");
}
});

Someone skilled at this, please help, that would be great.

jQuery fiddle (desired behaviour) // non-effecting JavaScript fiddle

mnsth
  • 2,169
  • 1
  • 18
  • 22

2 Answers2

2

I think I've got it mostly, maybe I'm missing some parts because your code is quite long. You should consider using ids and classes for better readability in all of this.

First, SLaks were right about querySelectorAll() returning a nodeList. To iterate through its items, you need to use a for loop, here I changed those parts to:

 var el = document.querySelectorAll("selectors");
 for (i = 0; i < el.length; i++) {
     el[i].style.display = "none";
     }
 document.getElementById("id").removeAttribute("style");

Then I changed the first selector to just check for the id, as ids must be unique: document.getElementById('abo').addEventListener("change", function () {

And finally I changed every
if(document.querySelector("#id input[value='ja']:checked"))
to
if (document.querySelector("#id input[value='ja']").checked)
as checked is a boolean property it can be used in an if statement.

You can see the whole changed code in updated fiddle.

PS: You're victim of learning web coding with jQuery, which makes you unable to understand what really happens. Please continue learning pure JavaScript.

halfer
  • 19,824
  • 17
  • 99
  • 186
Kaiido
  • 123,334
  • 13
  • 219
  • 285
  • Thank you so much for your help. I only have 3 questions or so: 1: I know that ids must be unique, but why doesn't `document.querySelector("#abo input").addEventListener` function at all? This is allowed in CSS. 2: How do you trigger the change event after the listener? I tried `dispatchEvent` but it didn't work the way I expected, thought I could chain it on the end like this like jQuery: `document.querySelector().addEventListener({}).dispatchEvent("change")`. 3: What do you do in this example `document.querySelectorAll().addEventListener`? Yes, I am a jQuery victim, thanks for your support. – mnsth Dec 10 '14 at 05:09
  • 1. Actually document.querySelector("#abo input") does work but returns the first radio element (try console.log(document.querySelector("#abo input") in your js console). You're not changing input's value property but the checked one, this means it doesn't trigger the onchange event. So you have to attach your function to the form containing this radio input ([check this answer](http://stackoverflow.com/questions/8838648/onchange-event-handler-for-radio-button-input-type-radio-doesnt-work-as-one/9025006#9025006)) – Kaiido Dec 10 '14 at 09:27
  • 2. check [this answer](http://stackoverflow.com/a/2490876/3702797) and [updated fiddle](http://jsfiddle.net/he798kct/4/) including it in a function. 3. What do you mean? Where did you found it? – Kaiido Dec 10 '14 at 09:28
  • Thanks for the updated fiddle! Wasn't able to make something like that myself. Regarding 3, it's a part of my code that I didn't post. Look here: http://jsfiddle.net/pef719qx/ – mnsth Dec 10 '14 at 13:08
  • well you need to do the same : `querySelectorAll()` returns a nodeList which doesn't have event handler. So you need to loop through those nodes to attach the event to each one. – Kaiido Dec 10 '14 at 13:25
0

querySelectorAll() returns an array (actually a NodeList), which doesn't have a style (or any other) property.

Either call querySelector() or loop through the array.

PS: This is why people use jQuery.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • I see now that my selectors with `querySelectorAll()` with a `.style` selector afterwards are the ones not working, thanks. There are other issues, too, but thanks for clearing that up. I will investigate more. I'm a newbie on pure JS, no need for those who did to downvote me 5 times, that's cruel. – mnsth Dec 09 '14 at 21:41
  • @mangseth: It's not that you're a newbie; it's that you made no effort to solve it on your own. – SLaks Dec 09 '14 at 21:44
  • Believe me, I've spend hours on this trying to figure it out. I think it's unfair, as I've read documentations, etc. That I missed the fact about a selector that didn't work the way I thought it would, is human error. I just didn't understand the console error about the undefined style element. – mnsth Dec 09 '14 at 21:51
  • @mangseth: No; why didn't you try the debugger? Those lines will throw JS errors. – SLaks Dec 09 '14 at 21:52