0

need to create variables from all elements having id attribute
name of each variable should be just the value of id attribute
for example <div id='btnsave'>SAVE</div> - should be a variable named btnsave
here is my try - without success:

let els = $("*");
els.forEach(function(el){
    if(el.hasId()){
        console.log(el.attr('id'));
        window[el] = $('#' + el);
    }
});
vegas
  • 101
  • 1
  • 7
  • Why? What is the benefit of doing that? – VLAZ May 17 '21 at 09:17
  • @VLAZ - I have a lot of divs as buttons and is simpler to write `btnsave.on('click'...` then `$('#btnsave').on('click'...` – vegas May 17 '21 at 09:20
  • 1
    In that case you simply need to cache the selector at the top of your script (within scope) and use it where required. This is a standard pattern to follow. Creating jQuery objects from every element in the DOM with an `id` and storing them in the `window` object is an anti-pattern, which will cause performance issues and most likely break native code which expects those references to contain DOMElement objects, not jQuery objects. – Rory McCrossan May 17 '21 at 09:21
  • @vegas so you want to save... 6 characters? By potentially causing more problems for yourself? Feels a lot like [an XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) because you shouldn't even be writing that many even handlers (or even IDs) that 6 extra character would make your code more complex. – VLAZ May 17 '21 at 09:25

2 Answers2

4

If you're using id attributes for your elements then they already have references accessible through the properties of the window object which match their id value:

console.log(window.foo.textContent);
console.log(window.fizz.textContent);
<p id="foo">bar</p>
<p id="fizz">buzz</p>

Given your comment under the question:

I have a lot of divs as buttons and is simpler to write btnsave.on('click'... then $('#btnsave').on('click'...

In that case you simply need to cache the selector at the top of your script (within scope) and use it where required. This is a standard pattern to follow.

Creating jQuery objects from every element in the DOM with an id and storing them in the window object is an anti-pattern, which will cause performance issues and most likely break native code which expects those references to contain DOMElement objects, not jQuery objects.
Do not do it.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • 3
    Relevant: [Do DOM tree elements with ids become global variables?](https://stackoverflow.com/q/3434278) – VLAZ May 17 '21 at 09:19
  • `window.foo.on('click', function...` - doesn't work – vegas May 17 '21 at 09:24
  • 1
    I'm *guessing* `$(window.foo).on('click', function...` would work – freedomn-m May 17 '21 at 09:26
  • @freedomn-m - there is no much difference between `$(window.foo).on('click', function...` - and `$('#foo').on('click', ...` - I want to shorter the selector code – vegas May 17 '21 at 09:29
  • Correct, I was referencing `window.foo.on` not available, not recommending you actually use `$(window.foo).on` – freedomn-m May 17 '21 at 09:33
  • 1
    "*and most likely break native code which expects those references to contain DOMElement objects, not jQuery objects.*" I'd like to add here - it would also break code that expects those global references to *not* be DOM elements. The ID to `window` property is resolved first and any further globals overwrite those. So, if you have some library that registers itself as `window.someLib` and there is an element with `id="someLib"` that would *destroy* the global library registration. Worse yet, it might even be some dependency of the library you use that stops working which leads to weird bugs. – VLAZ May 17 '21 at 09:49
  • so what is on the end - `$(window.btnsave).on('click', function()` instead of `btnsave.on('click', function()` - am I right? – vegas May 17 '21 at 12:29
  • @RoryMcCrossan - give me example, pls, excuse me for my confusion – vegas May 17 '21 at 12:41
  • @RoryMcCrossan - but that's what I want in my original code - not one by one element but using `forEach` - isnt't it? – vegas May 17 '21 at 12:46
  • @RoryMcCrossan - could you give me pls, your code using any kind of loop. I have a lot of elements which I want to have as a variable. In fact - all elements having `id` attribute – vegas May 17 '21 at 12:52
  • @RoryMcCrossan - I can't see how to do this without using `window` or `document` object. – vegas May 17 '21 at 13:03
1

To get elements by any attribute you can use query selector.

let elementsWithId = {}

document.querySelectorAll('[id]').forEach(el => {
    elementsWithId[el.id] = el
})

console.log(elementsWithId)

You can record a jQuery element to window variable. Example:

window[el.id] = $(el)

But as people mentioned, this is a bad practice.