Выход из дилеммы в Javascript - PullRequest
1 голос
/ 04 ноября 2008

У меня есть следующее

var id='123';

newDiv.innerHTML = "<a href=\"#\" onclick=\" TestFunction('"+id+"', false);\"></a>";

Что отображает <a href="#" onclick="return Testfunction('123',false);"></a> в моем HTML.

Проблема, с которой я столкнулся, заключается в том, что я хочу взять вызов метода TestFunction и использовать в качестве строкового параметра в моей функции StepTwo (string, boolean), которая в идеале должна была бы оказаться в реальном HTML, как показано ... 1007 *

<a href="#" onclick="StepTwo("TestFunction('123',false)",true)"></a>

обратите внимание, что TestFunction является строкой здесь (она выполняется внутри StepTwo с использованием eval).

Я попытался отформатировать JS как:

newDiv.innerHTML = "<a href=\"#\" onclick=\"StepTwo(\"TestFunction('"+id+"', false);\",true)\"></a>";

но, хотя мне кажется, что это правильно в моей среде IDE, в отрисованном HTML-коде это искажено невероятно.

Был бы признателен, если бы кто-нибудь мог указать мне правильное направление. Спасибо!

Ответы [ 11 ]

5 голосов
/ 04 ноября 2008

Одна из самых больших проблем с капиталом в Интернете - это создание html в javascript путем склеивания строк.

var mya = document.createElement("a");
mya.href="#"; 
mya.onclick = function(){ 
    StepTwo(function(){ 
        TestFunction('123', false ); 
    }, true );   
};
newDiv.innerHTML = ""; 
newDiv.appendChild(mya);

Это устраняет необходимость в каких-либо причудливых вещах.

(я, вероятно, должен делать 'onclick' по-другому, но это должно работать, я стараюсь не просто использовать код jQuery для всего)

Вот как бы я это сделал в jQuery:

jQuery(function($){ 

  var container = $("#container"); 
  var link = document.createElement("a"); /* faster than  $("<a></a>"); */
  $(link).attr("href", "Something ( or # )" ); 
  $(link).click( function(){ 
       var doStepTwo = function()
       { 
            TestFunction('123', true ); 
       };
       StepTwo( doStepTwo, false );  /* StepTwo -> doStepTwo -> TestFunction() */
  });
  container.append(link); 
}); 

Нет хорошего повода для склеивания строк в Javascript

Все, что он делает, это ADD накладные расходы на синтаксический анализ html-структур обратно в структуры dom и ADD потенциал для разбитого HTML на основе XSS. Даже любимый google ошибаются в некоторых своих рекламных сценариях и вызывают эпические сбои во многих случаях, которые я видел (и они не хотят об этом знать)

Я не понимаю, Javascript является единственным оправданием, и это НЕ хороший.

2 голосов
/ 04 ноября 2008

Попробуйте использовать & quot; вместо \ "

newDiv.innerHTML = "

2 голосов
/ 04 ноября 2008

Вы должны использовать &quot;, а не " или \" внутри строки HTML, заключенной в двойные кавычки.

NewDiv.innerHTML = "<a href=\"#\" onclick=\"StepTwo(&quot;TestFunction('"+id+"', false);&quot;,true)\"></a>";

Вероятно, есть лучший способ сделать это - всякий раз, когда вы обнаружите, что используете eval(), вы должны отступить и искать другое решение.

1 голос
/ 04 ноября 2008

Вы утверждаете, что eval - то, что нужно делать здесь. Я не уверен в этом.

Рассматривали ли вы этот подход:

<a href="#" onclick="StepTwo(TestFunction,['123',false],true)"></a>

и в вашей функции StepTwo

function StepTwo(func,args,flag){
    //do what ever you do with the flag
    //instead of eval use the function.apply to call the function.
    func.apply(args);
}
0 голосов
/ 10 июля 2016

Я знаю, что сейчас это hella 'old, но если у кого-то возникают проблемы с экранированными строками при использовании eval (и вам обязательно нужно использовать eval), у меня есть способ избежать проблем.

var html = '<a href="#\" onclick=" TestFunction(\''+id+'\', false);"></a>';
eval('(function(div, html){div.innerHTML = html;})')(newDiv, html);

Итак, что здесь происходит?

  1. eval создает функцию, которая содержит два параметра, div и html, и возвращает ее.
  2. Функция запускается сразу с параметрами справа от функции eval. Это в основном как IIFE.

В этом случае

var myNewMethod = eval('(function(div, html){div.innerHTML = html;})');

в основном совпадает с:

var myNewMethod = function(div, html){div.innerHTML = html;}

и тогда мы просто делаем это:

myNewMethod(newDiv, html); //where html had the string containing markup

Я бы предложил не использовать eval. Если этого нельзя избежать, или если вы контролируете все входы и риск впрыска отсутствует, это поможет в случаях, когда экранирование строк является проблемой.

Я также склонен использовать Function, но это уже не безопасно. Вот фрагмент, который я использую:

    var feval = function(code) {
    return (new Function(code))();
}
0 голосов
/ 04 ноября 2008
<a href="#" onclick="StepTwo('TestFunction(\'123\', false)', true)">...</a>
0 голосов
/ 04 ноября 2008

Привет, ребята, спасибо за все ответы. Я считаю, что это; кажется, работает лучше всего.

Я дам вам, ребята, несколько голосов, как только я получу больше репутации!

Что касается eval (), то, что вы видите в вопросе, является очень маленьким снимком разрабатываемого приложения. Я понимаю горести Eval, однако, это одна из тех, в миллионной ситуации, когда это правильный выбор для текущей ситуации.

Было бы лучше понять, если бы вы могли видеть, что делают эти функции (дали им очень общие имена для stackoverflow).

Еще раз спасибо!

0 голосов
/ 04 ноября 2008

Лучший способ - создать элемент с document.createElement, но если вы не хотите, я думаю, вы могли бы сделать <a href="#" onclick="StepTwo('TestFunction(\'123\',false)',true)"></a> или использовать &quot;.

В вашем коде:

newDiv.innerHTML = "<a href=\"#\" onclick=\"StepTwo('TestFunction(\'"+id+"\', false);\',true)\"></a>";

Если это не работает, попробуйте изменить "\'" на "\\'".

Помните, что символ "используется для открытия и закрытия атрибута в тегах HTML. Если вы используете его в значении атрибута, браузер будет понимать его как символ закрытия.

Пример: <input type="text" value="foo"bar"> в конечном итоге станет <input type="text" value="foo">.

0 голосов
/ 04 ноября 2008

Ваша самая большая проблема - это использование eval, это приводит к такому количеству потенциальных проблем, что почти всегда лучше найти альтернативное решение.

Ваша непосредственная проблема в том, что у вас действительно есть

<a href="#" onclick="StepTwo("></a>

как следующий " после начала атрибута onclick закрывает его. Используйте & quot; как другие предложили. И не используйте eval.

0 голосов
/ 04 ноября 2008
  1. Вам нужно чередовать "и".

  2. Возможно, вам не нужны кавычки вокруг 123 из-за гибкой типизации Javascript Передавайте это без кавычек, но рассматривайте это как строку в TestFunction.

...