javascript Extracting an element from HTML - Keeping parent/child structure - javascript

Having the following html:
<html>
<body>
<div id="first">
1
<div class="first-first">
<p>1.1</p>
</div>
<div class="first-second">
<p>1.2</p>
</div>
</div>
<div id="second">
2
<div class="second-first">
<p>2.1</p>
</div>
<div class="second-second">
<p>2.2</p>
</div>
</div>
</body>
</html>
How could I extract an element from the HTML keeping his parent-child structure? e.g. if I want to extract the class 'second-first', I will have a html object that looks like this:
<html>
<body>
<div id="second">
2
<div class="second-first">
<p>2.1</p>
</div>
</div>
</body>
</html>
So #first and .second-second will be removed.
jsfiddle
I've tried different approaches but with no success at all, also if someone knows how to do that with a time complexity less than O(n^2) would be great to know.
Thanks a lot!

Related

Converting Jquery hide/show to Vue

I made a few hide/show panels that I am hoping to use with Vue. The panels are written in Jquery - however when I mount the Jquery functions in Vue, the whole thing seems to fail. The panels do not/hide/show.
Does anyone know why? I have heard that there are issues with Jquery & Vue, but I have not worked out a solution to solve this. Do I need to convert the Jquery to Vue (I'm not even sure how to do this). Can anyone advise on how I could go about fixing this?
Fiddle here: https://jsfiddle.net/syed263/m4s9Lyed/111/
HTML
<!DOCTYPE html>
<html>
<head>
<link crossorigin="anonymous" href="https://use.fontawesome.com/releases/v5.2.0/css/all.css" integrity="sha384-hWVjflwFxL6sNzntih27bfxkr27PmbbK/iSvJ+a4+0owXq79v+lsFkW54bOGbiDQ" rel="stylesheet">
<title></title>
</head>
<body>
<div class="container">
<!--COMPONENT START-->
<div>
<div>
<div id='panel0'>
<div class="panel_head">
TITLE
</div>
<div class="panel_body">
BODY
</div>
</div>
</div>
<div>
<span class="btn" id='click' value="Show/Hide"><span id="eee"><i class="far fa-window-maximize"></i></span></span>
</div>
</div>
<!--COMPONENT END-->
<!--COMPONENT START-->
<div>
<div>
<div id='panel2'>
<div class="panel_head">
TITLE
</div>
<div class="panel_body">
BODY
</div>
</div>
</div>
<div>
<span class="btn" id='click2' value="Show/Hide"><span id="eee"><i class="far fa-window-maximize"></i></span></span>
</div>
</div>
<!--COMPONENT END-->
<!--COMPONENT START-->
<div>
<div>
<div id='panel3'>
<div class="panel_head">
TITLE
</div>
<div class="panel_body">
BODY
</div>
</div>
</div>
<div>
<span class="btn" id='click3' value="Show/Hide"><span id="eee"><i class="far fa-window-maximize"></i></span></span>
</div>
</div>
<!--COMPONENT END-->
</div>
</body>
</html>
JavaScript
$('#click').click(function() {
$("#panel0").toggle("slide");
});
$('#click2').click(function() {
$("#panel2").toggle("slide");
});
$('#click3').click(function() {
$("#panel3").toggle("slide");
});
(function() {
$("#panel0").toggle("slide");
$("#panel2").toggle("slide");
$("#panel3").toggle("slide");
}());
Your question is actually more like two; Do this by using jQuery in Vue, or do this in pure Vue. Obviously it would be better to convert it to pure Vue, especially if you are only using the toggle() method, as importing the whole jQuery library for just one function is major overkill.
With jQuery Version:
To use jQuery in Vue you want to wrap in a Vue component and put v-once directive on the component so Vue leaves it alone. Then you would usually target the elements using window.jQuery.('#someid').toggle()
I distilled the panel component down to be reusable and am targeting it with the following method from within the panel component itself.
methods:{
toggleMe(id){
window.jQuery('#'+id).toggle('slide');
}
}
Here is the full working fiddle https://jsfiddle.net/skribe/cmwtqe7d/3/
No jQuery Version
It is quite easy to replicate jQuery's toggle() method since it is only adding/removing "display:none" You would do this with Vue's class bindings. No function even necessary in this case. Just create a hidePanel data property, write a.hideme css class, bind it to div in the template, and toggle it with hidePanel = !hidePanel with an #click event.
<div :id='panel.pId' :class="{hideme : hidePanel}">
<div class="panel_head"> TITLE </div>
<div class="panel_body"> BODY </div>
</div>
<div>
<span #click="hidePanel = !hidePanel" class="btn">
<span id="eee"><i class="far fa-window-maximize"></i></span>
</span>
</div>
Here is the working Jfiddle:
https://jsfiddle.net/skribe/L9mq20nd/14/

Daily bible verse from ourmanna.com API is not always displaying

I have HTML and JS code that should display the daily verse from ourmanna.com API. However, the verse is not always displaying. I was wondering if it's a problem on their side or my side?
here is the html code:
<div class="col-md-6">
<div class="owl-carousel owl-theme">
<div class="item">
<div class="daily-verse">
<h2>Daily Verse</h2>
<div class="body-daily-verse">
<div id="ourmanna-verse">Loading...</div>
<script src="https://www.ourmanna.com/verses/api/js/" type="text/javascript"></script>
<p class="daily-verse-text">
</p>
<br />
<p class="verse-reference"></p>
</div>
</div>
</div>
</div>
</div>
Thanks very much
If you look at the script returned by ourmanna, you see the problem is a not escaped quote in the mannaverse:
var mannaverse='"'If you can'?" said Jesus. "Everything is possible for him who believes."';
Correct would be
var mannaverse='"\'If you can\'?" said Jesus. "Everything is possible for him who believes."';
So you cannot do anything about it, it is a ourmanna-problem.

Converting from working function in console to working script. (See Edit)

I'm trying to automate a clicking of a link within a class list. Currently I have a working script that will pick the first item in the container using the querySelector(), one line of code wrapped in a function.
To have more usability, I was wondering if I could modify the code so that the script searches within each item in the container trying to match a title of the listing or name with a defined variable, to the users desire, and once found, clicks the link for that particular item.
<div class="item-wall">
<div class="grid-item" data-column-index="0" data-pdpurl="http://www.LINK1.com">
<div class="grid-item"> … </div>
<div class="content">
<div class="grid-item-details-wrapper">
<div class="grid-item-image"> … </div>
<div class="grid-item-info-wrapper no-chipper">
<a href="http://www.LINK1.com">
<div class="product-name">
<p class="griditem-display-name nsg-font-size--regular nsg-text--dark-grey">
PRODUCT1
</p>
<p class="griditem-subtitle nsg-font-size--regular nsg-text--medium-grey"> … </p>
</div>
<div class="product-price-wrapper"> … </div>
</a>
</div>
<div class="grid-item-extras"> … </div>
</div>
</div>
</div>
<div class="grid-item" data-column-index="1" data-pdpurl="http://www.LINK2.com">
<div class="grid-item"> … </div>
<div class="content">
<div class="grid-item-details-wrapper">
<div class="grid-item-image"> … </div>
<div class="grid-item-info-wrapper no-chipper">
<a href="http://www.LINK2.com">
<div class="product-name">
<p class="griditem-display-name nsg-font-size--regular nsg-text--dark-grey">
PRODUCT2
</p>
<p class="griditem-subtitle nsg-font-size--regular nsg-text--medium-grey"> … </p>
</div>
<div class="product-price-wrapper"> … </div>
</a>
</div>
<div class="grid-item-extras"> … </div>
</div>
</div>
</div>
<div class="paging-bar hidden"> … </div>
<div class="spacer"></div>
</div>
Sorry for being so verbose. The web page has an 'item-wall' with several items, 2 are only shown here. I wish to be able to set a variable as a string in the script and be able to use something along the lines of .contain() to find an instance of the matching product name in the wall and then have it open the link corresponding to the selection.
Thanks for any input!
/////////////////////////////////////////////////////////////////////////////////////////////
EDIT: Thanks to #Barmar for the working console function:
function product_click(product) {
$(".griditem-display-name:contains("+product+")").closest("a").click();
}
product_click("Desirable here")
Now I am at a loss as to how to make this function operational in an script. I've tried with scriptish in firefox and have tried writing this to a .js file and loading it as an unpacked extension in chrome to no avail. It seems as though the function/script won't load. If anyone has any thoughts, they'd be greatly appreciated.
Thanks again!
If I understand you correctly, I think this is it:
function product_click(product) {
$(".griditem-display-name:contains("+product+")").closest("a").click();
}

How do I trigger fitVids for multiple, dynamically generated ids on a page?

I'm working on a responsive tumblr-theme based on the 1140GRID. To make the static videos fit the column, I used the jquery fitvids plugin.
My setup code looks like this:
$(document).ready(function(){
$("#post_{PostID}").fitVids();
});
and the accompanying html like this:
<div class="container">
<div class="row">
<div class="ninecol"> //grid I want it to fit into
{Block:Video}
<div id="post_{PostID}">
{Video-500}
</div>
{/Block:Video}
</div>
</div>
</div>
How do I trigger fitVids for multiple, dynamically generated ids on a page?
Thank you!
You may want to put that closing DIV inside the video block.
<div class="container">
<div class="row">
<div class="ninecol"> //grid I want it to fit into
{Block:Video}
<div id="post_{PostID}">
{Video-500}
</div>
{/Block:Video}
</div>
</div>
</div>
Then, you could target all the subdivs of ninecol.
<script>
$(document).ready(function(){
$('.ninecol > div').fitVids();
});
</script>

jQuery is not finding elements loaded with AJAX

I have a page like this:
<html>
<head>
<script language="javascript" type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script language="javascript" type="text/javascript" src="jqtouch.js"></script>
<script language="javascript" type="text/javascript" src="myfunctions.js"></script>
[...]
</head>
<body>
[...]
<div id="jqt">
<div id="home" class="current">
<div class="toolbar">
TITLE
</div>
<div class="s-scrollwrapper">
<div class="content">
<div class="container" >
LOAD ME 1LOAD ME 2
</div>
</div>
</div>
</div>
</div>
[...]
</body>
The contents of the loaded page is like this, for example:
<div id="AG3456AF002347634">
<div class="toolbar">
TITLE 1
</div>
<div class="s-scrollwrapper">
<div class="content">
<div class="container" >
<div style="display:none" id="myItemId"></div><button onclick="javascript: showItem();"/>
</div>
</div>
</div>
</div>
showItem is a function located in myfunctions.js and the contents is, for example this:
function showItem() {jQuery(jQT.hist[0].hash + ' #myItemId').show();}
so when i click on the button, after the page is loaded, jQT.hist[0].hash value is #AG3456AFGG2347634. This works fine the first time that i load a page with AJAX (well, when jQTouch does it). But if i load another page with same content (but the main identifier is different) it doesn't work. After two AJAX calls, the page dom is simmilar to this:
<html>
<head>
<script language="javascript" type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script language="javascript" type="text/javascript" src="jqtouch.js"></script>
<script language="javascript" type="text/javascript" src="myfunctions.js"></script>
[...]
</head>
<body>
[...]
<div id="jqt">
<div id="home">
<div class="toolbar">
TITLE
</div>
<div class="s-scrollwrapper">
<div class="content">
<div class="container" >
LOAD ME 1LOAD ME 2
</div>
</div>
</div>
</div>
<div id="AG3456AF002347634">
<div class="toolbar">
TITLE 1
</div>
<div class="s-scrollwrapper">
<div class="content">
<div class="container" >
<div style="display:none" id="myItemId"></div><button onclick="javascript: showItem();"/>
</div>
</div>
</div>
</div>
<div id="FC00A83473BE33457" class="current">
<div class="toolbar">
TITLE 2
</div>
<div class="s-scrollwrapper">
<div class="content">
<div class="container" >
<div style="display:none" id="myItemId"></div><button onclick="javascript: showItem();"/>
</div>
</div>
</div>
</div>
</div>
[...]
</body>
so when i click the button on the second loaded page it doesn't works cause jQuery is not finding the item. the value of jQT.hist[0].hash is correct, that is #FC00A83473BE33457. The item id #myItemId is the same on both pages, that's the reason to use the wrapper div id that it's unique, to locate each loaded item.
Why this is working on the first page but it's not when i load additional pages into the DOM??
You have to use the "live" command in jQuery for dynamic loaded content.. Pass a class to your button (like .myButton) and to your div container (.container) and use :
$('.myButton').live('click', function(){
//and scope from $(this) here
$(this).parents().find('.container:first').attr('id');
});
I suggest using the jQuery .on() method instead of live, it's a newer method (live has some problems), read about it: http://api.jquery.com/on/
As for passing parameters you can add an attribute to the element clicked or call your function from inside the .on() callback with the parameter, Or even do a little (ugly) hack and use .on for the 'load' (or 'ready') events instead of 'click' and add the onclick (if there is really no other way). Something like:
$(".myButton").on("load", function(event){
$(this).attr('onclick' , yourFunction)
});
But you probably can make it work in a cleaner way with just .on().
Ids are singular, you can not have more than one id with the same value on the page.
Change the ids to classes and reference it that way.

Categories

Resources