2012-11-06 22 views
5

Bunun mümkün olup olmadığından emin değilim, ancak sayfadaki javascript'i çalıştıran bir tarayıcıda mini bir taklit editörü oluşturmaya çalışıyorum. İşte teoride yapmaya çalıştığım şey buydutextarea'dan javascript'i çalıştır

HTML

​<textarea id="cnsl"></textarea> 
<button onclick="run()"> run </button> 

javascript Yazarken 'kod' üzerinden bir tuval elemana yazmaya çalışıyorum daha spesifik

var cnsl = document.getElementById('cnsl'); 

function run() { 
    return cnsl.value 
} 

metin alanına, yani, örneğin, ben ctx.fillRect yazın (10,10,10,10); benim textarea içine ve o run() işlevi yürütmek sonra 10x10 kare benim tuvalimde görünecektir. yerine cnsl.value döndürmek benim HTML boş script öğesinin innerHTML bunu yazdığında

Biraz şans oldu. Ancak bu, yalnızca işlevi ilk kez çalıştırdığımda çalışır ve sayfayı yenileyene kadar tekrar çalışmayacaktır. (örneğin, bu, jsfiddle üzerinde çalışmıyor gibi görünen, ancak yukarıda açıklandığı gibi yerel olarak çalışan http://jsfiddle.net/ur5KC/1/)

... herhangi bir fikir ??? Önceden thnx! Bu JavaScript çalışacak ancak, ithal komut çağrı yöntemini metin alanında eylem yapmak istediğinizde sonra metin alanına sahiptir senaryoya dönüştürmek komut almayı deneyin Diğer dillerde çalışırsa

+1

** eval ** fonksiyon size yardımcı olacaktır: http://www.w3schools.com/jsref/jsref_eval.ASP – Damask

+3

... Bir gerçi Daha iyi bir bağlantı, ilk yöntem için https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/eval – JayC

cevap

10

Bir komut dosyası öğesi oluşturabilir, text (veya HTML5 ve DOM 3 ile uyumlu ise textContent) komut dosyasını çalıştırabilir ve belgeye ekleyebilirsiniz. Gitmek için öğeleri en iyi şekilde kullanabilirsiniz, böylece çok sayıda (işe yaramaz) komut dosyasıyla bitmezsiniz. HTML5'teki, her script element yürütüldüğünü olmasından bağımsız olarak belirtmek için, ilişkili bir bayrağı vardır ve yalnızca bir kez infaz edilebilir çünkü yeni bir öğe oluşturmanız gerekir

function run() { 
    var el = document.getElementById('cnsl'); 
    var scriptText = el.value; 
    var oldScript = document.getElementById('scriptContainer'); 
    var newScript; 

    if (oldScript) { 
     oldScript.parentNode.removeChild(oldScript); 
    } 

    newScript = document.createElement('script'); 
    newScript.id = 'scriptContainer'; 
    newScript.text = el.value; 
    document.body.appendChild(newScript); 
} 

Not. içeriklerini değiştirme bayrağı sıfırlama ve bir klonlanmış yazı elemanı ondan klonlandı elemanın ayar tutar.

Bazı HTML:

<textarea id="cnsl"></textarea> 
<button onclick="run();">run</button> 

belgeyi yok edebilir kendi komut dosyalarını yürütmek için bir kullanıcı teşvik, ama bu sanırım senin problemin. :-)

alternatif yukarıdaki (ama çok daha az kod) daha fazla veya daha az eşdeğer basitçe eval girdikleri her neyse oluyor şudur:

function run() { 
    var el = document.getElementById('cnsl'); 
    el && eval(el.value); 
} 
+1

++ olacaktır. Birçok farklı senaryo için çalışmak için değiştirilebilir; Bir iframe içinde kullanıcı tarafından yazılan JavaScript'i yürütmek için benzer bir kod kullandım. Bunu biraz farklı yaptım - id = "script" ile ayrı bir div vardı ve ben betik elemanlarını divun içine koydum. Komut dosyası birikimini önlemek için, her defasında yeni bir komut dosyası eklediğimde yalnızca div'un innerHTML'sini silmek zorunda kaldım. –

+0

Çok riskli. Herhangi bir sanitazion olmaksızın bir giriş alanında kullanıcı kodlarınız ne olursa olsun çalıştıramazsınız; Siteniz ağır JS bağımlı ise komut dosyası enjeksiyonu her zaman büyük bir risktir. –

+0

@ FranVerona — kullanıcılar zaten bir web sayfasında istedikleri betiği çalıştırabilirler, bu herhangi bir yeni zayıflık ortaya çıkarmaz. Web uygulamanız bunu kaldıramazsa, bazı sorunları vardır. – RobG

0

emin değil Yürütmek istediğiniz kod olan bu

5

Thnx @Prodigy & & @JayC !!!

böyle basit bir çözüm, böyle bir fonksiyon() fonksiyonu hile yaptı eval kullanarak :)

varlığından habersizdi !!!

HTML

<textarea id="cnsl"></textarea> 
<button onclick="run()"> run </button> 
<canvas id="canvas" width="200" height="200"></canvas> 

javascript

var cnsl = document.getElementById('cnsl'); 

function run() {  
    return eval(cnsl.value); // << did the trick ;) 
} 

//canvas 
var ctx; 

function setup() { 
    var canvas = document.getElementById('canvas'); 
     ctx = canvas.getContext('2d'); 
} 
setup();​