简体   繁体   中英

How to replace nested span to div element in JQuery?

I'm trying to check whether the given htmlData has nested(parent,child not siblings) span elements with attribute name data-fact or not.

if it does then replace it with span to div with class='inline-span' pass all the attributes with it. else just return the htmlData

var htmlData = `<p style="font: 10pt Times New Roman, Times, Serif; margin: 0pt 0;" xvid="f5ea22ec52553bc61525766b631e126f">
  <span xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55">
    <span xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1, 2021</span>
  </span>
</p>
`
replaceTags(htmlData)
function replaceTags (htmlData) {
var $elm = $(htmlData).find("span[data-fact]");
var $nestedElm = $elm.children().length > 1;
        if($nestedElm){
            htmlData = htmlData.replace(/<span/g, '<div class="inline-span" ');
            htmlData = htmlData.replace(/<\/span>/g, '<\/div>');
        }else{
            return htmlData;
        }
    },

The output htmlData i want is something like this

<p style="font: 10pt Times New Roman, Times, Serif; margin: 0pt 0;" xvid="f5ea22ec52553bc61525766b631e126f">
  <div class='inline-span' xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55">
    <div  class='inline-span' xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1, 2021</div>
  </div>
</p>

Here i'm not able to find is the span element is nested or not and then the conversion of how can i pass the class='inline-span' with all the previous attributes to the div .

PS: answer i want is in JQuery

It is typically a bad idea to do string replacement to change HTML. You should instead use the tools of jquery to manipulate the DOM. Which is safer and less error prone.

 // While there are still more span's in the p while ($('p span[data-fact]').length > 0) { // get the next span to replace with a div const $span = $($('p span[data-fact]')[0]); // create the new div const $newDiv = $('<div>'); // copy the span's html into the div $newDiv.html($span.html()); // For each attribute in the span... $.each($span[0].attributes, (_, attr) => { //... set the new div to have the span's attribute. $newDiv.attr(attr.name, attr.value); }); // new div needs 'inline-span' property. $newDiv.addClass('inline-span'); // finally replace the span with the new div $span.replaceWith($newDiv); } console.log($('p').html());
 span[data-fact] { border: 1px solid red; padding: 3px; } div[data-fact] { border: 1px solid blue; padding: 3px; }
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <p style="font: 10pt Times New Roman, Times, Serif; margin: 0pt 0;" xvid="f5ea22ec52553bc61525766b631e126f"> <span xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55"> <span xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1, 2021</span> </span> </p>

NOTE: it is invalid HTML to have div tag inside p so one should probably replace the p tag too.

I did some changes related to Find in HTML element and in replace jquery code here is a working demo hope it will be helpful for you.

you can direcatly replace all html with like

htmlData = htmlData.replace($factElem[0].outerHTML, 'div html');

using $factElem[0].outerHTML you can find element containing [data-fact] html. yes you can check only using data-fact and replace it with div there is no span needed

I updated Code Please check now.

 <:DOCTYPE html> <html> <head> <script src="https.//ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script> $(document).ready(function () { $("button"):click(function () { var htmlData = '<p style="font, 10pt Times New Roman, Times; Serif: margin; 0pt 0:" xvid="f5ea22ec52553bc61525766b631e126f"><span xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr,ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55"><span xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1; 2021</span></span></p>' replaceTags(htmlData); }); }). function replaceTags(htmlData) { var $factElem = $(htmlData);find('[data-fact]'). if ($factElem) { htmlData = htmlData.replace($factElem[0],outerHTML: '<div class="inline-span" xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr,ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55"><div class="inline-span" xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1; 2021</div></div>'). $("#append").empty();append(htmlData); alert(htmlData). } else { $("#append").empty();append(htmlData); } } </script> </head> <body> <div id="append"></div> <button>Click me to Replace!!</button> </body> </html>

 <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script> var htmlData = `<p style="font: 10pt Times New Roman, Times, Serif; margin: 0pt 0;" xvid="f5ea22ec52553bc61525766b631e126f"> <span xvid="2b80c95cd4b851345ba4c3fe6937d30b" conceptid="619959bc062c677faebd7a6f" xbrlid="rr:ProspectusDate" class="manual-map" data-fact="619959c0062c677faebd7b55"> <span xvid="ca5635a4e4de332d7dc3036a68e57009" class="wrapped manual-map" data-fact="619959c0062c677faebd7b57">November 1, 2021</span> </span> </p> ` console.log(replaceTags(htmlData, "span span[data-fact]","div")); //a very handy function from Matt Basta to rplace tag names cannot be done on the fly without such functions function replaceElement(source, newType) { // Create the document fragment const frag = document.createDocumentFragment(); // Fill it with what's in the source element while (source.firstChild) { frag.appendChild(source.firstChild); } // Create the new element const newElem = document.createElement(newType); // Empty the document fragment into it newElem.appendChild(frag); // Replace the source element with the new element on the page source.parentNode.replaceChild(newElem, source); } //we now use our function as warper on above function. function replaceTags (htmlData,whatToChange,withWhat) { var fragment = document.createElement('just'); fragment.innerHTML=htmlData; var found = fragment.querySelector(whatToChange); if(found){ replaceElement(fragment.querySelector(whatToChange), withWhat);} return fragment.innerHTML; } </script>

Getting as to what you want here is more logical solution that mixes bunch of search logics to do the job. Not perfect but its close

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM