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.
Related
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);
});
I have a big HTML-string containing multiple child-nodes.
Is it possible to construct a jQuery DOM object using this string?
I've tried $(string) but it only returns an array containing all the individual nodes.
Imtrying to get an element which i can use the .find() function on.
Update:
From jQuery 1.8, we can use $.parseHTML, which will parse the HTML string to an array of DOM nodes. eg:
var dom_nodes = $($.parseHTML('<div><input type="text" value="val" /></div>'));
alert( dom_nodes.find('input').val() );
DEMO
var string = '<div><input type="text" value="val" /></div>';
$('<div/>').html(string).contents();
DEMO
What's happening in this code:
$('<div/>') is a fake <div> that does not exist in the DOM
$('<div/>').html(string) appends string within that fake <div> as children
.contents() retrieves the children of that fake <div> as a jQuery object
If you want to make .find() work then try this:
var string = '<div><input type="text" value="val" /></div>',
object = $('<div/>').html(string).contents();
alert( object.find('input').val() );
DEMO
As of jQuery 1.8 you can just use parseHtml to create your jQuery object:
var myString = "<div>Some stuff<div>Some more stuff<span id='theAnswer'>The stuff I am looking for</span></div></div>";
var $jQueryObject = $($.parseHTML(myString));
I've created a JSFidle that demonstrates this: http://jsfiddle.net/MCSyr/2/
It parses the arbitrary HTML string into a jQuery object, and uses find to display the result in a div.
var jQueryObject = $('<div></div>').html( string ).children();
This creates a dummy jQuery object in which you can put the string as HTML. Then, you get the children only.
There is also a great library called cheerio designed specifically for this.
Fast, flexible, and lean implementation of core jQuery designed specifically for the server.
var cheerio = require('cheerio'),
$ = cheerio.load('<h2 class="title">Hello world</h2>');
$('h2.title').text('Hello there!');
$('h2').addClass('welcome');
$.html();
//=> <h2 class="title welcome">Hello there!</h2>
I use the following for my HTML templates:
$(".main").empty();
var _template = '<p id="myelement">Your HTML Code</p>';
var template = $.parseHTML(_template);
var final = $(template).find("#myelement");
$(".main").append(final.html());
Note: Assuming if you are using jQuery
the reason why $(string) is not working is because jquery is not finding html content between $(). Therefore you need to first parse it to html.
once you have a variable in which you have parsed the html. you can then use $(string) and use all functions available on the object
You can try something like below
$($.parseHTML(<<table html string variable here>>)).find("td:contains('<<some text to find>>')").first().prev().text();
I know this is an old thread, but I have another simple answer. jQuery has moved up quite a few versions and I'm on 1.13.x
Not being an expert jQuery programmer, I näively used:
var el = $( "#thecontainer" ).append( "<legit, lengthy html>" );
And presto! It worked: el is now a fully operational jQuery dom element.
I have been testing it out over the past couple of days and it seems to work as expected.
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
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');
Lets say I have this:
<div data-uid="aaa" data-name="bbb", data-value="ccc" onclick="fun(this.data.uid, this.data-name, this.data-value)">
And this:
function fun(one, two, three) {
//some code
}
Well this is not working but I have absolutely no idea why. could someone post a working example please?
The easiest way to get data-* attributes is with element.getAttribute():
onclick="fun(this.getAttribute('data-uid'), this.getAttribute('data-name'), this.getAttribute('data-value'));"
DEMO: http://jsfiddle.net/pm6cH/
Although I would suggest just passing this to fun(), and getting the 3 attributes inside the fun function:
onclick="fun(this);"
And then:
function fun(obj) {
var one = obj.getAttribute('data-uid'),
two = obj.getAttribute('data-name'),
three = obj.getAttribute('data-value');
}
DEMO: http://jsfiddle.net/pm6cH/1/
The new way to access them by property is with dataset, but that isn't supported by all browsers. You'd get them like the following:
this.dataset.uid
// and
this.dataset.name
// and
this.dataset.value
DEMO: http://jsfiddle.net/pm6cH/2/
Also note that in your HTML, there shouldn't be a comma here:
data-name="bbb",
References:
element.getAttribute(): https://developer.mozilla.org/en-US/docs/DOM/element.getAttribute
.dataset: https://developer.mozilla.org/en-US/docs/DOM/element.dataset
.dataset browser compatibility: http://caniuse.com/dataset
If you are using jQuery you can easily fetch the data attributes by
$(this).data("id") or $(event.target).data("id")
The short answer is that the syntax is this.dataset.whatever.
Your code should look like this:
<div data-uid="aaa" data-name="bbb" data-value="ccc"
onclick="fun(this.dataset.uid, this.dataset.name, this.dataset.value)">
Another important note: Javascript will always strip out hyphens and make the data attributes camelCase, regardless of whatever capitalization you use. data-camelCase will become this.dataset.camelcase and data-Camel-case will become this.dataset.camelCase.
jQuery (after v1.5 and later) always uses lowercase, regardless of your capitalization.
So when referencing your data attributes using this method, remember the camelCase:
<div data-this-is-wild="yes, it's true"
onclick="fun(this.dataset.thisIsWild)">
Also, you don't need to use commas to separate attributes.
HTML:
<div data-uid="aaa" data-name="bbb", data-value="ccc" onclick="fun(this)">
JavaScript:
function fun(obj) {
var uid= $(obj).attr('data-uid');
var name= $(obj).attr('data-name');
var value= $(obj).attr('data-value');
}
but I'm using jQuery.
JS:
function fun(obj) {
var uid= $(obj).data('uid');
var name= $(obj).data('name');
var value= $(obj).data('value');
}
you might use default parameters in your function
and then just pass the entire dataset itself, since the
dataset is already a DOMStringMap Object
<div data-uid="aaa" data-name="bbb" data-value="ccc"
onclick="fun(this.dataset)">
<script>
const fun = ({uid:'ddd', name:'eee', value:'fff', other:'default'} = {}) {
//
}
</script>
that way, you can deal with any data-values that got set in the html tag,
or use defaults if they weren't set - that kind of thing
maybe not in this situation, but in others, it might be advantageous to put all
your preferences in a single data-attribute
<div data-all='{"uid":"aaa","name":"bbb","value":"ccc"}'
onclick="fun(JSON.parse(this.dataset.all))">
there are probably more terse ways of doing that, if you already know
certain things about the order of the data
<div data-all="aaa,bbb,ccc" onclick="fun(this.dataset.all.split(','))">