-1
class_name = document.getElementsByClassName('image');
const map = fn => x => Array.prototype.map.call(x, fn);
map(img => {
console.log(img);
img.addEventListener('mouseover', (e) => {
global = e.target.src;
calledsomething(global);
     });
  })(class_name);

I'm trying to make a simple chrome extension but Array.prototype.map.call doesn't seems to be called. console.log(img) doesn't display anything. I tested my code using getElementsByTagName('img') instead of getElementsByClassName and it works.

What might be the problem?

EDIT: The whole code:

var isHovered = false;
var global;
const class_name = document.getElementsByClassName('photo_activity_item__img_wrapper');
const map = fn => x => Array.prototype.map.call(x, fn);
console.log(class_name);
map(img => {

    img.addEventListener('mouseover', (e) => {
        global = e.target.src;
        console.log(global);

        hoveredBox();
    });
    img.addEventListener('mouseleave', (e) => {
        isHovered = false;
    });


})(class_name);

document.addEventListener('keypress', keyDown);

function hoveredBox() {
    isHovered = true;
}

function keyDown(event) {
    if (!isHovered) return;
    var key = event.keyCode;
    if (key === 115) {
        saveFile(global);
    }

}

// Download a file form a url.
function saveFile(url) {
    // Get file name from url.
    filename = url;
    var xhr = new XMLHttpRequest();
    xhr.responseType = 'blob';
    xhr.onload = function () {
        var a = document.createElement('a');
        a.href = window.URL.createObjectURL(xhr.response); // xhr.response is a blob
        console.log(a.href);
        console.log(xhr.response);
        a.download = filename; // Set the file name.
        a.style.display = 'none';
        document.body.appendChild(a);
        a.click();
        delete a;
    };

    xhr.open('GET', url);
    xhr.send();
}
  • 1
    is there elements with class "image" on the page ? and are you sure they are img elements ? – Apolo Oct 12 '17 at 12:39
  • yeah, I used `console.log()` to check if there are class named "image". – Yunik Maharjan Oct 12 '17 at 12:44
  • The code looks as if it should work fine: [jsFiddle](https://jsfiddle.net/47sep3L9/) – CodingIntrigue Oct 12 '17 at 12:45
  • class "image" is not img element, its a anchor tag which has "image" as class name, which has img element as child – Yunik Maharjan Oct 12 '17 at 12:49
  • @jsFiddle – CodingIntrigue Code works fine for `getElementsByTagName('img')` but doesn't works for `getElementsByClassName('image') ` – Yunik Maharjan Oct 12 '17 at 12:50
  • 1
    @YunikMaharjan Works for me: https://jsfiddle.net/7o1dndoh/ – apsillers Oct 12 '17 at 12:55
  • odd! can you try this code for [500px.com](https://500px.com) website, for a class named, "photo_activity_item__img_wrapper" please. – Yunik Maharjan Oct 12 '17 at 13:10
  • @YunikMaharjan I don't see that code on the linked site anywhere. Can you post a [mcve], please? – Bergi Oct 12 '17 at 13:27
  • i have added the code above. please try to point out the problem – Yunik Maharjan Oct 12 '17 at 13:48
  • "*The whole code*" - what about the HTML markup? – Bergi Oct 12 '17 at 13:48
  • @JamesDonelly: I don't see how it's a duplicate of that question. The OP already is using `call`. I rather suspect https://stackoverflow.com/questions/14028959/why-does-jquery-or-a-dom-method-such-as-getelementbyid-not-find-the-element – Bergi Oct 12 '17 at 13:51
  • @Bergi i'm making an chrome extension, and I haven't used html for now. – Yunik Maharjan Oct 12 '17 at 13:53
  • @YunikMaharjan And when does that extension code run, before any html loads? – Bergi Oct 12 '17 at 13:54
  • yeah! using the following `"content_scripts": [ { "matches": [ "*://500px.com/*" ], "js": ["content.js"], "run_at" : "document_idle" }` – Yunik Maharjan Oct 12 '17 at 13:58
  • This scenario might simply be an exclusive issue with chrome dev tools. Tried this code snippet to get UTF-16 codes of input string's characters: ` let map = Array.prototype.map; let charCodes = ("Hello World", x => x.codePointAt(0)); console.log(charCodes); ` – Prashant Singhal Jul 28 '18 at 03:14
  • Above outputs `undefined`. But when I make another call to map i.e. insert the code `charCodes = ("Hello World", x => x.codePointAt(0));` at line 4, and now try to log `charCodes` into the console, it shows the expected output! i.e. `[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]`. My point being, perhaps this is related to how chrome dev tools (and a few other platform servers) interpret Javascript or how JS is polyfilled in user agents. Works fine with Firefox dev tools though. Tested on plnkr.co as well, works! – Prashant Singhal Jul 28 '18 at 03:24

1 Answers1

0

While the return of the getElementsByClassName() may be an array like object, it's quite possible it isn't a true Array. I ran into this this morning while attempting to call findIndex() on the Element.children object. Turns out that is a NodeList, and not an actual Array. I was able to get around it though, by using the new Array.from() method like this:

const index = Array.from(parent.children).findIndex(item => item.classList.contains('placeholder'));

Try that Array.from() and see if your issues are resolved.

Steve -Cutter- Blades
  • 3,323
  • 1
  • 20
  • 33
  • thanks, but it didn't work. I tried debugging and I see that the ` Array.prototype.map.call(x, fn);` is not even called. Here variable "x" is the `Array.from(class_name)` – Yunik Maharjan Oct 17 '17 at 04:42
  • Just did some testing, and document.getElementsByClass() does return an Array like object, but you can't run Array functions against it without first using Array.from(). I'm trying to understand what it is you're attempting to do with your map() function. Array.map() creates a new array based on a function processed on each element of an existing array, i.e. ```const map = Array.from(class_name).map(item => doit(item))```. – Steve -Cutter- Blades Oct 17 '17 at 13:23
  • Your code looks like you're just trying to setup an event listener on each of the items referenced, which wouldn't be the use of map(), but a good case for forEach() (after converting to a true Array). – Steve -Cutter- Blades Oct 17 '17 at 13:23
  • ```Array.from(class_name).forEach((el) => { el.addEventListener('mouseover', (evt) => dosomething(evt));});``` – Steve -Cutter- Blades Oct 17 '17 at 13:25