2015-02-17 1 views
0

У меня есть функциональный блок, который является динамическим, и мне нужно вызвать либо с помощью eval, либо с новой функцией (желательно последней). Я хочу, чтобы пройти в случае, если он был поднят изJavascript, передавая «e» на новую функцию, область действия

function MyFunc(e) 
{ 
    new Function("OtherFunc(e, 'abcde')"); 
} 

Я не могу видеть, как это сделать, я попробовал несколько вещей, таких как Bind (это), и (это), но никакой радости. Это необычная вещь, которая хочет от меня избавиться.

NB Я вижу, что он работает с eval, но новая функция была бы лучше, если это возможно, и у меня создается впечатление, что это должно быть, например. How to use scope in JavaScript for Function constructor? (второй ответ)

Любые предложения? Спасибо

(Добавлено: Почему я хочу это делать) Я использую мобильные кнопки Kendo. Я двигаюсь от этого:

<button onclick="MyFunc(e)"/> 

к этому

<button data-click="Call" data-func="MyFunc(e)"/> 

это происходит потому, что OnClick не рекомендуется с Кендо UI на айфонов

+2

Почему должен быть 'новый Function'? Я имею в виду, почему бы не назвать 'OtherFunc' напрямую? – Kokizzu

+0

Несомненно, Kendo обеспечивает лучший способ подключения обработчиков событий. –

+0

Проблема в том, что у меня уже есть целая куча onclicks, альтернатива - переписать каждую кнопку – tony

ответ

1

Так в принципе, вы прямо сейчас есть кнопки с

onclick="MyFunc(e); OtherFunc('a')" 

... и вы хотите изменить тех

data-click="Call" data-func="MyFunc(e); OtherFunc('a')" 

... и вы пытаетесь фигуры как написать Call функцию без любой значительный рефакторинг, продолжающий использовать строки, как у вас сейчас, в onclick.

Я немного смущен вашим использованием e в пределах onclick, а не event. Насколько мне известно, нет e в области для обработчиков onXyz; событие доступно как event. В ответе ниже я предположил, что event в onclick, но e везде; при необходимости отрегулируйте.

В пределах этих ограничений, eval и new Function действительно в значительной степени ваш единственный вариант. Это не больше зла, чем onclick (а также eval в масках); eval Используется со строками, которыми вы управляете, не обязательно злом, это просто последнее средство (вроде как with).

на основе the documentation, выглядит как ваш Call будет выглядеть примерно так:

function Call(e) { 
    var code = this.element.prop("data-func"); 
    var f = new Function("e", code); 
    f.call(this, e); 
} 

Это заканчивает выполнение кода с this будучи элементом, была нажата, и с e в объеме к коду в сгенерированная функция.

I не рекомендую этот, за исключением, возможно, временной меры при правильном рефакторинге, но в рамках ограничений, которые вы указали, так я вижу, что это работает. Одна из причин, почему я не рекомендую, так это то, что, как и в случае с onclick, все ваши функции должны быть глобальными (потому что кроме аргументов, которые вы передаете, new Function имеет только доступ к глобальным переменным), и лучше всего избегать глобалов, таких как чума.

Живой пример (с некоторыми обходного за то, что я не включают Кендо):

// Kendo calls the data-click function with this being something 
 
// other than the element; but the element is available as `this.element` 
 
function fakeKendo(e) { 
 
    Call.call({element: this}, e); 
 
} 
 

 
function Call(e) { 
 
    // (Using getAttribute instead of Kendo's prop here) 
 
    var code = this.element.getAttribute("data-func"); 
 
    var f = new Function("e", code); 
 
    f.call(this, e); 
 
} 
 

 
function MyFunc(e) { 
 
    snippet.log("MyFunc: e.type = " + e.type); 
 
} 
 

 
function OtherFunc(arg) { 
 
    snippet.log("OtherFunc: arg is " + arg); 
 
}
<p onclick="fakeKendo.call(this, event)" data-func="MyFunc(e); OtherFunc('a')"> 
 
    Click me 
 
</p> 
 
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> 
 
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

+1

Да, это работает. Это будет упражнение по рефакторингу, но я бы скорее смог изменить одно место за раз и иметь рабочий продукт. – tony

2

Не используйте функцию конструктора. На самом деле, нет. Это eval другим именем. Вместо этого используйте объявление функции. Это не будет нарушать масштаб или ожидать, что он будет создан из строк.

function MyTest(e) { 
    function callOtherFunc() { 
     OtherFunc(e, "abcde"); 
    } 

    return callOtherFunc; 
} 
Смежные вопросы