简体   繁体   中英

Use of Call method on document.querySelector in JavaScript

This is the sample code I am working on:

var DomClass = {
    Eprcent: ".item__percentage"
};
var EPrsent = function (prcent) {
    prcent.forEach(function (cur) {
    var ele = document.getElementById("exp-" + cur.id).innerHTML;
    var S = document.querySelector.call(ele, 'DomStrings.Eprcent'); //Uncaught TypeError: Illegal invocation 
    S.innerText = cur.prcnt + "%";
    });
}

I am getting this exception: Uncaught TypeError: Illegal invocation at line number 7.

How can I use document method on my HTML from JavaScript code, ID, and class which I want to use that is already present in HTML?

This is a data structure of prcent class:

 var Expense = function (id, description, value) {
    this.id = id;
    this.description = description;
    this.value = value;
    this.prcnt = 0;
};

I am aware of that we can use directly document query but these HTML are generating dynamically with unique ids. I have to put information according to element id in my HTML. ex document.getElementById("exp-" + cur.id) this line use for identifying the HTML element in which i want to put value

My main concern is that how can I use call method on QuerySelector so that I can change "this" pointer to innerHTML variable? If it's not possible, then why?

querySelector acts on a Document object. Its signature is querySelector(String selector)

The Document method querySelector() returns the first Element node within the document, in document order, that matches the specified selectors, or group of selectors. If no matches are found, null is returned.

The problem related to document.querySelector.call is because you are providing an invalid this value. Check you are setting document.getElementById("exp-" + cur.id).innerHTML ( String ) as the this argument for document.querySelector.call (lines: 5) , 6) )

The Element innerHTML property is used to get or set a string representing serialized HTML describing the element's descendants.

Therefore, using the call method on querySelector to change this pointer to innerHTML is not possible because that variable is a String and not a Document object.


In the following snippet you can check how we can use querySelector.call (nothing different to using call on any other function):

 const serializedHtml = document.getElementById('example').innerHTML; console.log(typeof serializedHtml, serializedHtml); // -> string "<div id="inner">inner div</div><span>...</span>" const inner = document.querySelector('#inner'); // equivalent call: same result using `.call` with the document object const usingCall = document.querySelector.call(document, '#inner'); console.log(inner === usingCall, typeof inner, inner); // -> true object <div id="inner">inner div</div> // using an empty Document console.log(document.querySelector.call(new Document(), '#inner')); // -> null // error code when pointing to innerHTML string document.querySelector.call(serializedHtml, '#inner'); // -> Error: Uncaught TypeError: Illegal invocation...
 #example, #inner { border: 1px solid; padding: 8px; text-align: center; }
 <div id="example"> <div id="inner">inner div</div> <span>...</span> </div>

Trying to bind the document.querySelector to another Document instance makes no sense to me because if you had another Document object, you can always invoke directly the querySelector function of the other document.

Check the following example:

 const htmlStr = '<div id="container"><div id="inner"></div></div>' const parser = new DOMParser(); const doc = parser.parseFromString(htmlStr, 'text/html'); // using window.document console.log(document.querySelector('#inner')); // -> null // pointing to the correct Document console.log(document.querySelector.call(doc, '#inner')); // -> <div id="inner"></div> // but, really not neccessary because you can use the correct Document directly console.log(doc.querySelector('#inner')); // -> <div id="inner"></div>


Hope all of this helps!

Read more info about document.querySelector , Element.innerHTML , Function.prototype.call and DOMParser

You can use querySelector directly on the element if its a DOM element like

var DomClass ={
    Eprcent: ".item__percentage"
};
var EPrsent = function (prcent) {
   prcent.forEach(function (cur) {
       var ele = document.getElementById("exp-" + cur.id);
       var S = ele.querySelector(DomClass.Eprcent);
       S.innerText = cur.prcnt + "%";
   });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM