Equivalent of cheerio.load() in jquery? [duplicate] - javascript

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.

Related

jQuery: get the normal JS format of a html element

I am using jQuery and everything works fine except a few stuff. There are a few things you cannot do with the jQuery format of an element but only with the simple JS format. Especially, when using the hasAttributes() in simple JS.
This works:
let fooDiv = document.getElementsByTagName("div")[0];
console.log(fooDiv.hasAttributes()); //returns false as expected
let barDiv = document.getElementsByTagName("div")[1];
console.log(barDiv.hasAttributes()); //returns true as expected
<div>foo</div>
<div id="id">bar</div>
This doesn't:
let fooDiv = $(document.getElementsByTagName("div")[0]) //creates a jQ object
console.log(fooDiv.hasAttributes()); //error
let barDiv = $(document.getElementsByTagName("div")[1]) //creates a jQ object
console.log(barDiv.hasAttributes()); //error
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div>foo</div>
<div id="id">bar</div>
I am aware that the jQuery hasAttr() exists but I want to get the JS format of a jQuery object. There are a lot of differences, for example the jQuery creates an object but otherwise it is a html node list.
Initially, my question is:
How do I get the html node list or html element or the simple JS format of a html element(s) from jQuery?
To expand on what blex said in the comments ... when jQuery is used to select an HTML element, the raw HTML is always collected in an array as part of the variable you assign it to. For example, using your code:
// grab the element or elements
let fooDiv = $(document.getElementsByTagName("div")[0]);
// lets see the HTML!
consoe.log( fooDiv[0] );
The HTML itself will be exposed in that array, allowing direct access to the HTML and its properties... for example:
console.log( fooDiv[0].innerHTML );
or
console.log( fooDiv[0].tagName );

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.

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');

Can jQuery work for html strings that are not in DOM?

I have an html string that I created with a template.
This string has an html table with a bunch of rows, I'd like to manipulate this string using jquery, for example to add some classes to some rows based on logic, or other manipulation and then have jquery return a string. However, it seems that jQuery only manipulates the DOM. But I don't want to post this string into the DOM yet.
var origString = "<table><tr id='bla'>...more html inside here...</tr></table>";
//Something like
var newString = $(htmlString -> '#bla').addClass('blaClass');
// this syntax is obviously wrong, but what I mean is I'm trying
// to look inside the string not the dom
Or maybe it's better to post this string into an invisible div first and then manipulate it with jquery?
Parse it to a variable, manipulate, then append:
var origString = "<table><tr id='bla'>...";
origString = $.parseHTML(origString);
$(origString).find("tr").addClass("test");
$("body").append(origString);
Concept demo: http://jsfiddle.net/6bkUv/
Yeah, you can add a class without appending it to the dom.
var origString = "<table><tr id='bla'>...more html inside here...</tr></table>",
newString = $('<div>'+origString+'</div');
newString.find('#bla').addClass('blaClass');
console.log(newString.html());
Yes, you can definitely manipulate a string with jQuery. Here is what the following code does:
Declares a div to wrap the string in
Wraps the string in the div and does the manipulation
Finally, produces the manipulated string
No interaction with the DOM whatsoever.
var htmlString = "<table><tr id='bla'>...";
var div = $('<div/>');
div.html( htmlString ).find( '#bla' ).addClass( 'class' );
var newString = div.html();
WORKING JSFIDDLE DEMO
//OUTPUT
Original: <table><tr id='bla'><td></td></tr></table>
New: <table><tbody><tr id="bla" class="class"><td></td></tr></tbody></table>
NOTE: Please note that if your table string does not have a tbody element jQuery will include it as that makes for valid table markup.
The answers were too complicated. The answer is just a dollar sign and some parentheses:
var queryObj = $(str);
So
var str = "<table><tr>...</tr></table>"
var queryObj = $(str);
queryObj.find('tr').addClass('yoyo!');
// if you use 'find' make sure your original html string is a container
// in this case it was a 'table' container
$("body").append(queryObj);
works just fine..

jQuery syntax not setting object property

My jQuery question I beleive is pretty simple, which is driving me insane that I can't get it.
I have an object with a property "content", I want to be able to take that object, manipulate the property "content" with jQuery and then overwrite the value with the new value jQuery creates.
Example:
o.content = "<div><span>hello</span></div>";
$('div', o.content).addClass('test');
At this point I want o.content to be equal to <div class='test'><span>hello</span></div>
I can not for the life of me figure out the syntax. Any help is really appreciated.
This will give you a string <div class="test"><span>hello</span></div> if this is what you want:
$(o.content).addClass('test').wrap('<div>').parent().html();
Parse the html in o.content, add the class, append the parsed html to a new <div>, and get the html of the new div:
o.content = "<div><span>hello</span></div>";
var el = $(o.content).addClass('test');
o.content = $("<div>").append(el).html();
Edit: This assumes you want o.content to still contain a string, rather than a jQuery object. In that case, it's simpler:
o.content = $(o.content).addClass('test');
from the docs of the jquery function, context must be
A DOM Element, Document, or jQuery to use as context
Your context (o.content) is a string. Also, the jQuery function is not able to select the entire context, it can only select elements in that context.
Try this instead:
// make o.content a jquery element, not a string
o.content = $("<div><span>hello</span></div>");
// select on something inside the context (inside the div), not the div itself
$('span', o.content).addClass('test');
http://jsfiddle.net/JfW4Q/
I don't think you can lookup an element from a string like that.. I would rather do it like below,
var content = "<span>hello</span>";
content = $('<div/>', {class: 'test'}).html(content)
DEMO: http://jsfiddle.net/k4e5z/
You want the following
o.content = "<div><span>hello</span></div>";
// Create a jQuery object you can call addClass on
var docFragment = $(o.content);
docFragment.addClass('test');
// Since there's no outerHTML in jQuery, append it to another node
var wrapper = $('div');
docFragment.appendTo(wrapper);
// The HTML of the wrapper is the outerHTML of docFragment
console.log(wrapper.html()); // outputs <div class='test'><span>hello</span></div>
Why not do it all in one line:
var o = {};
o.content = $( "<div></div>" ) // create element
.addClass('test') // add class
.html( '<span>hello</span>' ); // append content
Fiddle: http://jsfiddle.net/kboucher/eQmar/
o.content = $("<div><span>hello</span></div>");
o.content.addClass('test');
o.content is a jQuery object in this example, as opposed to just a string. Here's a demo on jsfiddle: http://jsfiddle.net/cvbsm/1/

Categories

Resources