Toon posts:

[JS] Regex werkt in test software en site, maar niet in code

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ben bezig met een aantal regex regels, en ik loop (net als een aantal keer hiervoor) tegen het volgende obstakel aan;

Als ik mijn regex test op http://www.regular-expressions.info/javascriptexample.html of met Regular Expression Editor 1.2.0 dan werkt ie gewoon. Maar wanneer ik hem invoer in mijn eigen .js file of inline javascript (met "" quotes eromheen) dan werkt ie niet meer.

Hier is (een stukje van) mijn code:
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[...]

<style type="text/css">
html, body {
    height: 100%;
    margin: 0;
    padding: 0;
}

#test {
    height: 100%;
    background-image: url("http://www.regular-expressions.info/img/bg.png");
}
</style>

[...]

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
[...]

var styles  = document.getElementsByTagName('style');

// Style elements (inline stylesheets)
var pattern = new RegExp("url\s*\(\s*\"([^\"\r\n]*)\"\)", 'g');
for (var i = 0; i < styles.length; i++) {
    alert( styles[i].innerHTML.match(pattern) );
}

[...]


De regex regels worden bij de window.onload uitgevoerd, hij loopt door het <style> element heen. Ik krijg null terug, de regex matcht niks.

Wat doe ik hier fout?

[ Voor 19% gewijzigd door Verwijderd op 21-02-2006 09:54 ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 11:33

crisp

Devver

Pixelated

Je moet dubbel escapen aangezien je een string voert aan de constructor, of een literal gebruiken. Verder zou ik de quotes optioneel maken, en ook de single quote meenemen aangezien dit allemaal valid is:
Cascading Stylesheet:
1
2
3
background-image: url(image.gif);
background-image: url('image.gif');
background-image: url("image.gif");

JavaScript:
1
var pattern = /url\s*\(\s*["']?([^"'\r\n]*)["']?\)/g;

;)

Intentionally left blank


Verwijderd

Topicstarter
Kijk eens aan! :) Leuk zo'n crisp!

Ik wou inderdaad rekening houden met enkele/dubbele quotes en zonder quotes. Maar ik dacht; laat ik maar eens beginnen met een werkende basis... ;)

Hij werkt nu!

Verwijderd

Topicstarter
Ik dacht- laat ik eens voor de grap kijken of mijn dingen ook in IE werken! -... Nee hoor, natuurlijk moeten alle dingen weer anders gedaan worden.

Nu loop ik door alle elementen heen met DOM. Ik wil o.a. in het <style> element en het style="" attribuut alle URLs kunnen aanpassen met behulp van bovenstaande regex.


JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
[...]

var LC_CB_URL = 'http://domein.nl/?test=';

function hasAttribute(attr) {
    if (this.attributes) {
    if (this.attributes[attr] && this.attributes[attr].specified) { return true; }
    }
    return false;
}

var patterns = new Array();
patterns[0] = /url\s*\(\s*["']?([^"'\r\n]*)["']?\)/g;
patterns[1] = /location(\.href)?\s*=/g;
patterns[2] = /window.open\s*\(\s*/g;
var replaces = new Array();
replaces[0] = 'url("' + LC_CB_URL + '$1")';
replaces[1] = 'location.href = "' + LC_CB_URL + '" + ';
replaces[2] = 'window.open("' + LC_CB_URL + '" + ';

var els = document.getElementsByTagName('*');
for (var i = 0; i < els.length; i++) {

    // For browsers that lack DOM level 2 support (IE<7)
    if (!els[i].hasAttribute) { els[i].hasAttribute = hasAttribute; }

    //alert( els[i].tagName.toLowerCase() );
    // First check separate elements by their tag name
    switch (els[i].tagName.toLowerCase()) {
    case 'script': // Script elements
        els[i].innerHTML = els[i].innerHTML.replace(patterns[1], replaces[1]);
        els[i].innerHTML = els[i].innerHTML.replace(patterns[2], replaces[2]);
        break;
    case 'style': // Style elements (inline stylesheets)
        els[i].innerHTML = els[i].innerHTML.replace(patterns[0], replaces[0]);
        break;
    default:
        // 
    }

    // Search and replace style attribute
    if (els[i].hasAttribute('style')) {
    var attr = els[i].getAttribute('style');
    if (attr.cssText) { // IE way
        attr.cssText = attr.cssText.replace(patterns[0], replaces[0]);
    } else {
        els[i].setAttribute('style', els[i].getAttribute('style').replace(patterns[0], replaces[0]));
    }
    }
} // end for

[...]
Blijkbaar mag ik met IE niet de .innerHTML van <style> en <script> elementen aanpassen. Kan dit kloppen? Weet iemand wat ik hier aan kan doen?

Thanks!

[ Voor 12% gewijzigd door Verwijderd op 21-02-2006 15:19 ]


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 11:33

crisp

Devver

Pixelated

jep, IE b0rked daarop. Workaround is volgens mij door te werken met de styleSheets/rules collecties.

Intentionally left blank


Verwijderd

Topicstarter
crisp schreef op dinsdag 21 februari 2006 @ 15:55:
jep, IE b0rked daarop. Workaround is volgens mij door te werken met de styleSheets/rules collecties.
Thanks indeed, en <script> ? Ik zag het volgende:
When using innerHTML to insert script, you must include the DEFER attribute in the script element.
Maar als ik het volgende doe werkt het nog steeds niet:
JavaScript:
1
2
3
4
5
6
7
8
[...]

        els[i].defer = true;
        els[i].innerHTML = els[i].innerHTML.replace(patterns[1], replaces[1]);
        els[i].innerHTML = els[i].innerHTML.replace(patterns[2], replaces[2]);
        break;

[...]


Vaag?

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 11:33

crisp

Devver

Pixelated

Script wordt volgens mij niet opnieuw geparsed als je het dmv innerHTML wijzigt.
Note dat innerHTML sowieso een propriety method is zonder officiele specificaties; het effect ervan op script en style is niet gedefinieerd dus je kan er niet vanuit gaan dat browsers daar op dezelfde manier mee omgaan...

[ Voor 3% gewijzigd door crisp op 21-02-2006 16:08 ]

Intentionally left blank


  • crisp
  • Registratie: Februari 2000
  • Laatst online: 11:33

crisp

Devver

Pixelated

Het enige dat werkt in Firefox maar niet in IE, is dit:
JavaScript:
1
2
3
4
5
6
var s = document.createElement('script');
s.type = 'text/javascript';
s.innerHTML = 'function bar(){ alert(\'foo\'); }';
document.body.appendChild(s);

bar();


innerHTML replaces, en zelfs iets als dit:
JavaScript:
1
2
var c = document.getElementById('script-container');
c.innerHTML = '<script type="text/javascript" DEFER>function bar(){ alert(\'foo\'); }<\/script>';
(wat volgens de MSDN link in IE zou moeten werken) werkt niet - javascript wordt hier niet geparsed.

Sowieso is het replacen van javascript content natuurlijk al een lastig punt, want wat doe je met objecten die al in het geheugen staan?

Intentionally left blank


Verwijderd

Topicstarter
crisp schreef op dinsdag 21 februari 2006 @ 16:24:
[...]
Sowieso is het replacen van javascript content natuurlijk al een lastig punt, want wat doe je met objecten die al in het geheugen staan?
Goed punt inderdaad, mijn script werkt trouwens wel in Firefox, óók het replacen van JavaScript spul, zowel in inline <script> elementen als in inline event handlers (onclick/onmouseup/etc). (met .innerHTML)
Balen dat Internet Explorer er niks mee kan, altijd erg vermoeiend die browser verschillen.

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 11:33

crisp

Devver

Pixelated

Verwijderd schreef op dinsdag 21 februari 2006 @ 16:56:
[...]


Goed punt inderdaad, mijn script werkt trouwens wel in Firefox, óók het replacen van JavaScript spul, zowel in inline <script> elementen als in inline event handlers (onclick/onmouseup/etc). (met .innerHTML)

Weet je het zeker?
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<script type="text/javascript">

function foo()
{
    alert('Mooh!');
}

</script>
<script type="text/javascript">

var s = document.getElementsByTagName('script')[0];
alert(s.innerHTML);

s.innerHTML = s.innerHTML.replace(/Mooh!/g, 'Miauw!');
alert(s.innerHTML);

foo(); // Mooh!

</script>

Intentionally left blank

Pagina: 1