How to store jQuery selector in a variable? - javascript

I would like to know why this way of selecting a DOM element works :
var $consoleDisplayHTML = document.getElementById('consoleDisplay');
var $watchedFolderHTML = document.getElementById('watchedFolder');
whereas this one doesn't work :
var $consoleDisplayHTML = $('#consoleDisplay');
var $watchedFolderHTML = $('#watchedFolder');
Code to fill the text works in the first case, not in the second one :
$consoleDisplayHTML.innerHTML = messages.pop().content;
$watchedFolderHTML.innerHTML = watchedFolder;
In the HTML, the IDs are defined :
<h4>Console</h4>
<p id="consoleDisplay" class="darken-4 indigo white-text"></p>
<div class="card darken-1 grey">
<div class="card-content white-text">
<span class="card-title">Watched Folder</span>
</div>
<div class="card-action">
<p id="watchedFolder" class="darken-4 indigo white-text"></p>
</div>
...
In the <head> section of the page, jQuery is declared :
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
What am I doing wrong ?
---------------- (edit)
To summerize :
This works :
var $consoleDisplayHTML = document.getElementById('consoleDisplay');
var $watchedFolderHTML = document.getElementById('watchedFolder');
$consoleDisplayHTML.innerHTML = messages.pop().content;
$watchedFolderHTML.innerHTML = watchedFolder;
This doesn't work :
var $consoleDisplayHTML = $('#consoleDisplay');
var $watchedFolderHTML = $('#watchedFolder');
$consoleDisplayHTML.innerHTML = messages.pop().content;
$watchedFolderHTML.innerHTML = watchedFolder;
This doesn't work too :
var $consoleDisplayHTML = $('#consoleDisplay');
var $watchedFolderHTML = $('#watchedFolder');
$consoleDisplayHTML.html(messages.pop().content);
$watchedFolderHTML.html(watchedFolder);
Finally, this worked :
$consoleDisplayHTML.get(0).innerHTML = messages.pop().content;
$watchedFolderHTML.get(0).innerHTML = watchedFolder;
I now understand that this notation acts as a wrapper :
$('#consoleDisplay');
and that's why it was necessary not to forget specifying elements' index :
.get(0)
Nevertheless, I still wander why it is necessary to specify an index where an object is necessary UNIQUE because the $('#consoleDisplay') notation looks for an ID.
Isn't an ID is necessary UNIQUE ??
Thanx for your help and explanations.

Your second example doesn't work because the variables hold jQuery objects, not Element objects as in the first example. As such they do not have an innerHTML property.
To do what you need with a jQuery object use the html() method:
$consoleDisplayHTML.html(messages.pop().content);
$watchedFolderHTML.html(watchedFolder);
I'd suggest familiarising yourself with the jQuery documentation to see what methods are available as they differ greatly from what's available on an Element.

The variables in the second piece of code contain jQuery objects which wrap the DOM Elements.
So if you wanted to set innerHTML property you could use the jQuery function .html().
$consoleDisplayHTML.html(messages.pop().content);
$watchedFolderHTML.html(watchedFolder);
If you want to assign yourself the inner HTML to the Dom Elements you can extract the wrapped element from the jQuery object and set it to the innerHTML property.
$consoleDisplayHTML.get(0).innerHTML = messages.pop().content;
$watchedFolderHTML.get(0).innerHTML = watchedFolder;
In regard to your edit: there could be a number of reasons the above snippets don't work. Usually for this kind of problem if you execute that code directly in <head> without surrounding it in a document ready callback the code will be executed as soon as it is reached by the browser but the elements in the DOM are not yet created. To avoid usage of a callback you may try to move to the bottom of the page the javascript code you wrote for example.
Here's a good old document ready callback:
jQuery(function ($) {
var $consoleDisplayHTML = $('#consoleDisplay');
var $watchedFolderHTML = $('#watchedFolder');
$consoleDisplayHTML.html(messages.pop().content);
$watchedFolderHTML.html(watchedFolder);
});

Related

How can I implement a non-jQuery version of data()?

I'm re-code a plugin jQuery I created, so I want take for create in pure Javascript
Most functions I can make fallowing YouMightNotNeedjQuery reference, but I don't have any idea to implement jQuery.data function for use in my plugin.
How to can I implement this function with Javascript pure?
You can do it via datasets
HTML
<article
id="electriccars"
data-columns="3"
data-index-number="12314"
data-parent="cars">
...
</article>
Javascript
var article = document.getElementById('electriccars');
article.dataset.columns // "3"
article.dataset.indexNumber // "12314"
article.dataset.parent // "cars"
Reference: https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Using_data_attributes
Edit as per comment
HTML
<article id="electriccars">
...
</article>
Javascript
var article = document.getElementById('electriccars');
article.setAttribute('data-columns', '3');
Example:
If you use getAttribute() the value is treated as a string, therefore it is not a like for like usage of jQuery .data as .data will assign objects and arrays to the data attr.
If you use dataset you will get a like for like usage as per jQuery.
Fiddle https://jsfiddle.net/69ukrpcf/
var myArr = ['item1', 'items2'];
jQuery Version
$('#one').data('foo', myArr);
var one = $('#one').data('foo');
console.log(one);
NON jQuery Version
var div = document.getElementById('two');
var two = div.dataset.foo = myArr;
console.log(two);
Read this article about how to work with data attributes here.
There are many ways to retrieve a data attribute with javascript :
var domElement = document.getElementById('randomid');
var articleId = domElement.getAttribute('data-articleid');
console.log(articleId);//Outputs 123
You can use too the datasets property of the dom element, however element.dataset will fail in old IE.

How to combine multiple scripts into one?

I've got five of the same scripts that just use five different variables. #video0 to #video4. I'm just not quite sure on how to combine them all so I don't have redundant code. I've been trying to make them all variables
var video= [
$('#video0'),
$('#video1'),
$('#video2'),
$('#video3'),
$('#video4')
];
http://jsfiddle.net/cwfybnzr/
Use each() with the array
var videos = [
$('#video0'),
$('#video1'),
$('#video2'),
$('#video3'),
$('#video4')
];
$(function() {
$.each(videos, function(){
var iframe = $(this)[0];
...
});
});
Isn't it better to create class for those elements? Then it will be possible to iterate through them using simple jQuery syntax: $('.video'). Plus it would not require changing any JavaScript code when new videos will be added.
You can add a class element like videoCSS to all the elements and then loop through them like
$('.videoCSS').each(function(){
var player = $(this);
// your code here
});
This way you can future proof you js code as you can add as many new player/iframes to the HTML with videoCSS class and your js code will still be the same.
Also, I found that in your code you are doing like
var iframe = $('#video0')[0];
var player = $(iframe);
Which means that first you are getting a jquery object using $('#video0'), then you are trying to get a DOM element out of it like $('#video0')[0] and then again you are converting it to a jquery object using $(iframe).
I think there is no need of this much extra processing, you can simply use
var player = $('#video0');
or using my updated code like
var player = $(this);
UPDATED FIDDLE

jQuery: easier way to use .clone() than described below?

If you execute in the console on this page
var cloned = $(".question").clone(true);
$(".question").addClass("first");
var clonedStr = cloned[0].outerHTML || new XMLSerializer().serializeToString(cloned[0]);
$(".question").after(clonedStr);
you will clone the question (there will be two questions on the page, but the first one will be with the .first class). That's what is needed.
Is there any simpler way to do this with jQuery? I'm confused of the third string in the code above and believe it could be simpler. Any ideas?
Thank you.
If you don't use the HTML as string, then don't get it. Just use the jQuery object:
var cloned = $(".question").clone(true);
$(".question").addClass("first").after(cloned);
Also, you can do it one line:
$(".question").after($(".question").clone(true)).first().addClass("first");
You could use insertAfter to insert the cloned element after changing the class. You don't need to convert the element in the jQuery object to a string, you can use that object within the function itself:
var $question = $('.question');
var $cloned = $question.clone(true).insertAfter($question);
$question.addClass('first');

How can I find out whether a HTML-Tagname is Standalone

Is there a way to find out whether a HTML-tagName comes in pair or alone (Standalone-Tag)?
E.g. <div></div>, <em></em>, <p></p>, ... they come in pair, but <br/>, <input>, <area> ... are Standalone.
I need a function which should find out if a HTML-Code snippet is entered correct. Therefore the function has to investigate among others which HTML-Element can be created with Standalone-Tag.
Do you have any idea how can I find out if an HTML element is standalone? Except for example
something like this:
var myArray = [ list of Standalone-Tags ];
if(jQuery.inArray("test", myArray) != -1 ) { ... }
Thanks.
Browsers don't have a built in list of elements which are defined as empty.
You're most reliable bet would be to create one manually by reading the HTML specification.
Alternatively, you could create an element and see what the browser returns when you convert it to HTML.
var element = prompt("What element name? e.g. br");
var container = document.createElement('div');
var content = document.createElement(element);
container.appendChild(content);
var reg = new RegExp("/" + element);
alert(reg.test(container.innerHTML) ? "Not Empty" : "Empty");

Why this type of array wrapping does not work in jQuery?

Consider this:
var i=$('<img src="/path/to/imgI.png"/>');
var j=$('<img src="/path/to/imgJ.png"/>');
$([i,j]).css('cursor','hand');
The cursor is not changed however and I don't know why..
When I do it separately, it works.
Thanks.
The array is of two jQuery objects when what you require is the DOM elements within those jQuery objects. This will work:
var i=$('<img src="/path/to/imgI.png"/>')[0]; // <= Notice [0]
var j=$('<img src="/path/to/imgJ.png"/>')[0];
$([i,j]).css('cursor','pointer');
Alternatively, (using add())
var i=$('<img src="/path/to/imgI.png"/>');
var j=$('<img src="/path/to/imgJ.png"/>');
$(i).add(j).css('cursor','pointer');
EDIT: Also, use cursor:pointer; instead of cursor:hand;
Are you sure your problems isn't browser specific? That particular css property is tricky, it requires the property be set two different ways to work in IE and Firefox.
I'd recommend using a class in the img tag to specify the hand property. Then you can specify both rules and get what you are looking for.
Would make more sense to put selectors in the array:
var i = $('<img src="/path/to/imgI.png"/>').attr('id','i');
var j = $('<img src="/path/to/imgJ.png"/>').attr('id','j');
$( ['#i', '#j'] ).css('cursor','hand');
The correct cursor property is "pointer" not "hand", which is an IE only extension no longer required for anything but IE 5.5 and lower - i.e. very rarely.
You can use jQuery method to turn the jQuery object into a true array and then merge them.
var i=$('<img src="/path/to/imgI.png"/>');
var j=$('<img src="/path/to/imgJ.png"/>');
i = $.makeArray(i);
j = $.makeArray(j);
$( $.merge(i,j) ).css('cursor','pointer');
Btw that also works when you need to add multiple jQuery selection together,
i = $.makeArray( $('div') );
j = $.makeArray( $('a') );
$( $.merge(i,j) ); //this jQuery object holds all divs and a's
You could of course also do that like this:
$('div').add('a');

Categories

Resources