Ricerca nel sito web

jquery - JavaScript replace() se la stringa viene trovata tra startIndex ed endIndex come fa substring()


Ho dell'HTML nel mio DOM e voglio sostituire alcune stringhe, ma solo se non sono già state sostituite o se non si tratta di un TAG.

Tutto ciò si basa su un array che contiene la stringa che voglio trovare e la nuova stringa con cui voglio che venga sostituita.

Lavoro in corso: https://jsfiddle.net/u2Lyaab1/23/

AGGIORNAMENTO: Il markup HTML è scritto solo per semplicità con UL nel codice di esempio, MA può contenere tag diversi, persino diversi livelli di nidificazione

Fondamentalmente il desiredReplcement funziona bene (tranne per il fatto che cerca anche nei tag), ma voglio che questo avvenga sul DOM, non sulla nuova stringa perché voglio mantenere qualsiasi altro markup HTML nel DOM.

FRAMMENTO:

var list = [{
    original: 'This is',
    new: 'New this is'
  },
  {
    original: 'A list',
    new: 'New A list'
  },
  {
    original: 'And I want',
    new: 'New And I want'
  },
  {
    original: 'To wrap',
    new: 'New To wrap'
  },
  {
    original: 'li',
    new: 'bold'
  },
  {
    original: 'This',
    new: 'New This'
  },
  {
    original: 'strong',
    new: 'bold'
  },  {
original: 'This is another random tag',
new: 'This is another random tag that should be bold'
  }

];


var div = $('.wrap');
var htmlString = div.html();
var index = 0;
list.forEach(function(item, index) {

  console.log(index + ' Should replace: "' + item.original + '" with "' + item.new + '"');

  //I know that there is something here, but not sure what
  index = htmlString.indexOf(item.original);
  var expressionLength = index + item.original.length;
  var substring = htmlString.substring(index, expressionLength);
  var desiredReplcement = substring.replace(item.original, '<strong>' + item.new + '</strong>');
  console.log('index', index);
  console.log('substring', substring);
  console.log('desiredReplcement', desiredReplcement);

  //Current implementation in replace looks in the full div, but I just want to replace in the substring mathced above;
  var replacement = '<strong>' + item.new + '</strong>';
  var newHTML = div.html().replace(item.original, replacement);
  div.html(newHTML);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap">
  <ul>
    <li>This is</li>
    <li>A list</li>
    <li>And I want</li>
    <li>This should not be bold</li>
    <li>To wrap</li>
    <li>This</li>
    <li>strong</li>
    <li>li</li>
  </ul>
<span><p><em>This is another random tag</em></p></span>
</div>

Risposta n. 1

La tua variabile div fa riferimento a <div class="wrap">...</div>, quindi il valore di htmlString è un gruppo di tag HTML invece di una stringa.

Questa è la ragione principale per cui il tuo codice non funziona come previsto.

E quindi ho riscritto la tua implementazione.

var list = [
  {
    original: 'This is',
    new: 'New this is'
  },
  {
    original: 'A list',
    new: 'New A list'
  },
  {
    original: 'And I want',
    new: 'New And I want'
  },
  {
    original: 'To wrap',
    new: 'New To wrap'
  },
  {
    original: 'li',
    new: 'bold'
  },
  {
    original: 'This',
    new: 'New This'
  },
  {
    original: 'strong',
    new: 'bold'
  }
  
];

var div = document.getElementsByClassName('wrap')[0].getElementsByTagName('li');  // Getting all <li> elements within <div class="wrap">

Array.prototype.forEach.call(div, function(li, x){  // Borrowing Array's forEach method to be used on HTMLCollection

    list.forEach(function(value, i){                // Looping through list
        if (value.original === li.innerHTML)        // if list[i]['original'] === li[x].innerHTML
            li.innerHTML = '<strong>' + value.new + '</strong>';
            
    });
    
    
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap">
  <ul>
     <li>This is</li>
     <li>A list</li>
     <li>And I want</li>
     <li>This should not be bold</li>
     <li>To wrap</li>
     <li>This</li>
     <li>strong</li>
     <li>li</li>
  </ul>
</div>

Risposta n. 2

Non penso che jQuery sia necessario qui.

Per prima cosa, vuoi recuperare il tuo contenitore, che nel tuo caso sarà il div .wrap.

var container = document.querySelector('.wrap');

Quindi vuoi creare una funzione ricorsiva che scorra un array per cercare e sostituire i dati forniti.

function replacement(containers, data){

    if(!data || !data.length)
        return;

    for(let i=0; i<containers.length; i++){

        var container = containers[i];

        // Trigger the recursion on the childrens of the current container
        if(container.children.length)
            replacement(container.children, data);

        // Perform the replacement on the actual container
        for(let j=0; j<data.length; j++){
            var index = container.textContent.indexOf(data[j].original);

            // Data not found
            if(index === -1)
                continue;

            // Remove the data from the list
            var replace = data.splice(j, 1)[0];
            container.innerHTML = container.innerHTML.replace(replace.original, '<strong>' + replace.new + '</strong>');

            // Lower the j by 1 since the data array length has been updated
            j--;

            // Only want to perform one rule
            break;

        }
    }
}

Demo: https://jsfiddle.net/u2Lyaab1/25/