contextMenu bij rechtermuisknop in iFrame beinvloeden

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Sgrovert
  • Registratie: Mei 2004
  • Laatst online: 17:12
Ik ben bezig een WYSIWYG editor voor html te maken. Momenteel ben ik bezig met de plaatjes die in de pagina staan. Om instellingen aan de plaatjes te kunnen doen wil ik de rechtermuisknop gaan gebruiken. Als er met de rechtermuisknop op een plaatje geklikt word, moet er een menu getoond worden, waarmee instellingen aan het plaatje gedaan kunnen worden. (De linkermuisknop word gebruikt om het plaatje te verplaatsen).
Op het moment ben ik zover dat ik het menu bij een plaatje kan tonen, maar het orginele menu van de browser valt over mijn custom menu heen.
Hieronder volgt de relevante code :
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
window.onload=Init;
function Init() {
if ($('iView') != undefined) { //Checken of de editor bestaat
    var doc = $('iView').contentDocument;
    doc.designMode = "on";
    var tekst = $('areaCode').value;
        
    doc.open();
    doc.write( tekst ); 
    doc.close();
    
    //Mouse evens starten;
    if(navigator.appName.substring(0,9) == "Microsoft"){ //IE
        doc.body.onmousedown = clicker; 
    } else { //FF
        doc.addEventListener('mousedown', clicker, false);
    }
}
function clicker(event){
 //IE is evil and doesn't pass the event object
if (event == null)
    event = $('iView').contentWindow.event;
// we assume we have a standards compliant browser, but check if we have IE
var target = event.target != null ? event.target : event.srcElement;
// only show the context menu if the right mouse button is pressed
// and a hyperlink or image has been clicked (the code can be made more selective)
if(event.button==2) {
    targetObject=target;
    var targetType=target.tagName.toLowerCase() //Type of the target
    
    if(targetType=="img")
        showmenu($('imageMenu'),event);  

    if(targetType=="a")
        showmenu($('linkMenu'),event);  
}
function showmenu(_id,event) {
    //Laat het menu behorende bij een afbeelding of link zien. (werk al)
}
function $(id) // Zorgt dat $((iView) het element oplevert
{
  return document.getElementById(id);
}

code:
1
2
3
4
5
<iframe id="iView" style="width: 100%; height:400px"></iframe>

<textarea name="areaCode" id="areaCode" rows="0" cols="0" style="visibility:hidden>
text die in de editor komt
</textarea>


Nu heb ik gevonden dat waarschijnlijk het "ontextmenu" event verhinderd moet worden.
Op deze site staat een tutorial hoe het ongeveer moet werken. Het probleem is dat ik het niet voor elkaar krijg om het werkend binnen het iframe te krijgen.

Lost In Music


Acties:
  • 0 Henk 'm!

  • apokalypse
  • Registratie: Augustus 2004
  • Laatst online: 14:48
Wat is nu helemaal het probleem? In een iframe zal de Javascript gewoon netjes in dat document van de iframe moeten zitten? Het is niet duidelijk wat er nu niet werkt en wat en nu wel/niet gebeurd.

Er is trouwens een mooie contextmenu plugin in jQuery: JeeGoo Context Menu

[ Voor 12% gewijzigd door apokalypse op 31-05-2010 01:17 ]


Acties:
  • 0 Henk 'm!

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 04-06 14:41
Ik ben bezig een WYSIWYG editor voor html te maken. Momenteel ben ik bezig met de plaatjes die in de pagina staan.
Klinkt als een hele uitdaging!

Je weet dat er al goede editors op de markt zijn, die je bovendien m.b.v. plugins naar je hand kunt zetten? http://ckeditor.com/ bijv.

Over je vraag: ik zou zeker kijken naar JQuery, wat je zou kunnen gebruiken voor je editor. Scheelt je een hoop geploeter om e.e.a. werkend te krijgen in IE in alle browsers.

[ Voor 24% gewijzigd door Rekcor op 31-05-2010 08:48 . Reden: JQuery ]


Acties:
  • 0 Henk 'm!

  • HenkEisDS
  • Registratie: Maart 2004
  • Laatst online: 11-06 00:28
Of deze bijvoorbeeld: http://tinymce.moxiecode.com/

Acties:
  • 0 Henk 'm!

  • Sgrovert
  • Registratie: Mei 2004
  • Laatst online: 17:12
Ik heb even een paar screenshots gemaakt om het probleem te verduidelijken :
De eerste is wat er gebeurd,
Afbeeldingslocatie: http://img714.imageshack.us/img714/5692/wrongj.jpg

En de tweede is wat er zou moeten gebeuren.
Afbeeldingslocatie: http://img217.imageshack.us/img217/5470/rightd.jpg

Het menu wat in het bovenste plaatje over mijn "custom" menu heenvalt moet geblokkeerd worden. Ik vermoed dat die kan met behulp van het "ontextmenu" event, maar krijg het niet voor elkaar.
Reckor
HenkEisjedies
Voordat ik begon met het zelf schrijven heb ik idd naar de "kant en klaar" alternatieven gekeken. Maar om deze compatable te krijgen met de bestaande code was erg veel werk. Mezelf kennende zou ik deze regel voor regel doorspitten, alles wat niet nodig is eruit slopen, en voor een groot deel overnieuw schrijven. Daarnaast was het zelf schrijven een goede oefening om javascript te leren. Een maand geleden had er ik nog nooit iets mee gedaan.

Lost In Music


Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 16:55

MueR

Admin Tweakers Discord

is niet lief

Rekcor schreef op maandag 31 mei 2010 @ 08:47:
Over je vraag: ik zou zeker kijken naar JQuery, wat je zou kunnen gebruiken voor je editor. Scheelt je een hoop geploeter om e.e.a. werkend te krijgen in IE in alle browsers.
Gaan we weer met het jQuery verhaal. Waar is dat nou voor nodig? Javascript != jQuery. Je kan editors uitstekend maken in good old javascript. Ja, het kost meer werk, tijd en waarschijnlijk wat grijze haren, maar het is een geweldige leerervaring.

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • Feanathiel
  • Registratie: Juni 2007
  • Niet online

Feanathiel

Cup<Coffee>

Wat je ziet is dat in IE het menu dat je hebt proberen aan te maken, er 'gewoon' achter staat. IE weet niet dat je bedoelt dat het standaard menu niet getoond moet worden. Dat staat dan ook niet in je bovenstaande voorbeeld. Op de site die je in de TS al aangaf, staat dit ook in de code, er wordt alleen geen aandacht aan besteed waarom dit er staat. De 'return false' in het onderstaande voorbeeld geeft aan dat dit normale menu niet getoond hoeft te worden:

JavaScript:
1
2
3
function clicker(event){
    return false;
}

Acties:
  • 0 Henk 'm!

  • Sgrovert
  • Registratie: Mei 2004
  • Laatst online: 17:12
In IE is het nu gefixed. Dit door ipv op het mousedown event op het oncontextmenu event te triggeren. Het oncontextmenu is blijkbaar een event dat losstaat van de mouse events. Door het mouse event op false te zetten (wat ik eerst deed) werd het "oncontextmenu event" nog steeds uitgevoerd.

De code ziet er als volgt uit :
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
function Init() {
    //Mouse evens starten;
    if(navigator.appName.substring(0,9) == "Microsoft"){ //IE
        doc.body.oncontextmenu = clicker; 
    } else { //FF
        doc.addEventListener('mouseup', clicker, false);
    }
}


function clicker(event){
 //IE is evil and doesn't pass the event object
    if (event == null)
        event = $('iView').contentWindow.event;
    // we assume we have a standards compliant browser, but check if we have IE
    var target = event.target != null ? event.target : event.srcElement;
    // only show the context menu if the right mouse button is pressed
    // and a hyperlink or image has been clicked (the code can be made more selective)
    targetObject=target;
    var targetType=target.tagName.toLowerCase() //Type of the target
        
    if(targetType=="img") {
        showmenu($('imageMenu'),event);
        return false;
    }  
    if(targetType=="a") {
        showmenu($('linkMenu'),event);
        return false;
    }
    return true;
}


Alleen nu nog in FF fixen. Ik kan het goede event niet vinden :(. Het contextmenu is namelijk geen onderdeel van het mousedown of mouseup menu. Iemand enig idee hoe ik deze in FF kan beinvloeden?

Lost In Music


Acties:
  • 0 Henk 'm!

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 04-06 14:41
MueR schreef op maandag 31 mei 2010 @ 12:04:
[...]

Gaan we weer met het jQuery verhaal. Waar is dat nou voor nodig? Javascript != jQuery. Je kan editors uitstekend maken in good old javascript. Ja, het kost meer werk, tijd en waarschijnlijk wat grijze haren, maar het is een geweldige leerervaring.
Je hebt natuurlijk gelijk, maar ik was me er niet bewust van dat de TS de editor aan het maken was om iets te leren...

Acties:
  • 0 Henk 'm!

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 04-06 14:41
Helpt dit?

oncontextmenu, document.designMode = on en firefox
Ik heb het gevonden:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
var contextmenuEvent = function(e)
{
laatContextMenuZien();
e.preventDefault(); // zorgt ervoor dat default context menu niet wordt geopend
}

/* dit werkt niet in ff: */
document.getElementById('iframe').contentWindow.oncontextmenu = contextMenuEvent;

/* dit wel: */
document.getElementById('iframe').contentWindow.addEventListener('contextmenu', contextmenuEvent, true);

Acties:
  • 0 Henk 'm!

  • apokalypse
  • Registratie: Augustus 2004
  • Laatst online: 14:48
MueR schreef op maandag 31 mei 2010 @ 12:04:
[...]

Gaan we weer met het jQuery verhaal. Waar is dat nou voor nodig? Javascript != jQuery. Je kan editors uitstekend maken in good old javascript. Ja, het kost meer werk, tijd en waarschijnlijk wat grijze haren, maar het is een geweldige leerervaring.
Als je graag het wiel opnieuw wilt uitvinden en je code in veel browsers wilt testen/debuggen (virtual machines), dan moet je vooral geen libaries gebruiken.

Acties:
  • 0 Henk 'm!

  • Sgrovert
  • Registratie: Mei 2004
  • Laatst online: 17:12
Het leren is mooi meegenomen, maar de voornaamste reden is dat ik met de editor nu precies de code kan genereren die ik nodig heb. Hierdoor hoef ik mijn andere code niet aan te passen.

Ik heb trouwens ook het FF problemeen opgelost. Om in een iFrame aan het contextmenu event te komen is devolgende code nodig :
JavaScript:
1
2
3
4
5
$('iView').contentWindow.addEventListener('contextmenu', clicker, true); 
//Let op "contentWindow" en niet contentDocument wat ik eerste gebruikte

if(navigator.appName.substring(0,9) != "Microsoft"){event.preventDefault();} 
//In FF zorgen dat contextmenu niet getoond word. De voorwaarde is nodig omdat IE event.precentDefault() niet kent.


Ter informatie voor wie tegen hetzelfde probleem aanloopt, hier het werkende script
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
var targetObject;
window.onload=Init;

function Init() {
    if ($('iView') != undefined) { //Checken of de editor bestaat
        var doc = $('iView').contentDocument;
        doc.designMode = "on";
        var tekst = $('areaCode').value;
        
        doc.open();
        doc.write( tekst ); 
        doc.close();
    
        //Mouse events starten;
        if(navigator.appName.substring(0,9) == "Microsoft"){ //IE
            doc.body.oncontextmenu = clicker; 
        } else { //FF
            $('iView').contentWindow.addEventListener('contextmenu', clicker, true);
        }
    }
}
function clicker(event){
 //IE is evil and doesn't pass the event object
    if (event == null)
        event = $('iView').contentWindow.event;
    // we assume we have a standards compliant browser, but check if we have IE
    var target = event.target != null ? event.target : event.srcElement;
    // only show the context menu if the right mouse button is pressed
    // and a hyperlink or image has been clicked (the code can be made more selective)
    targetObject=target; //targetObject is global en later te gebruiken om te detecteren op welke afbeelding/link geklikt is
    var targetType=target.tagName.toLowerCase() //Type of the target
        
    if(targetType=="img") {
        if(navigator.appName.substring(0,9) != "Microsoft"){event.preventDefault();}
        showmenu($('imageMenu'),event);
        return false;
    }  
    if(targetType=="a") {
        if(navigator.appName.substring(0,9) != "Microsoft"){event.preventDefault();}
        showmenu($('linkMenu'),event);
        return false;
    }
    return true;
}
function getPos (obj) {
    var output = new Object();
    var mytop=0, myleft=0;
    while( obj) {
        mytop+= obj.offsetTop;
        myleft+= obj.offsetLeft;
        obj= obj.offsetParent;
    }
    output.left = myleft;
    output.top = mytop;
    return output;
}
function showmenu(_id,event) {
    var posIframe=getPos($('iView')); //Absolute position of Iframe
    _id.style.display = 'none';
  _id.style.left = event.clientX + posIframe.left + 'px';
  _id.style.top = event.clientY + posIframe.top + 'px';
  _id.style.display = 'block';   
}



function $(id) // Zorgt dat $((iView) het element oplevert
{
  return document.getElementById(id);
}

HTML:
1
2
3
4
5
6
7
8
9
10
11
12
<iframe id="iView" style="width: 100%; height:400px"></iframe>

<textarea name="areaCode" id="areaCode" rows="0" cols="0" style="visibility:hidden>
text die in de editor komt <img scr="http://img217.imageshack.us/img217/5470/rightd.jpg" />
</textarea>
<div id="imageMenu" style="border: 1px solid blue; display: none; position: absolute">  
<ul class="cmenu">
      <li><a href="#" onclick="moveIm('left')">Left</a></li>
      <li><a href="#" onclick="moveIm('center')">Center</a></li>
      <li><a href="#" onclick="moveIm('right')">Right</a></li>
      <li class="topSep">  </li>
</ul></div>


Allemaal bedankt voor het meedenken.

edit :
Yep, heb idd in die post de oplossing gevonden

Lost In Music


Acties:
  • 0 Henk 'm!

  • apokalypse
  • Registratie: Augustus 2004
  • Laatst online: 14:48
JavaScript:
1
2
3
4
5
6
7
8
        //Mouse events starten;
        if(navigator.appName.substring(0,9) == "Microsoft"){ //IE
            doc.body.oncontextmenu = clicker; 
        } else { //FF
            $('iView').contentWindow.addEventListener('contextmenu', clicker, true);
        }
    }
}
Dus de wereld bestaat alleen uit IE & Firefox ;)
Mijn advies gaat toch OF het gebruik van libaries, OF het robuuster maken van het script met bijvoorbeeld Object detection. Voor cross-browser scripts maken is zeker de site quirksmode.org een goede aanbeveling.

Acties:
  • 0 Henk 'm!

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 04-06 14:41
apokalypse schreef op maandag 31 mei 2010 @ 13:52:
[...]

Als je graag het wiel opnieuw wilt uitvinden en je code in veel browsers wilt testen/debuggen (virtual machines), dan moet je vooral geen libaries gebruiken.
Daarnaast kun je je afvragen of het leren van core Javascript anno 2010 een nuttige leerervaring is. Vgl. het leren solderen van een printplaat voor een computerbouwer. Maar goed, offtopic

Acties:
  • 0 Henk 'm!

  • Sgrovert
  • Registratie: Mei 2004
  • Laatst online: 17:12
Zou je me een stukje op weg kunnen helpen?
Als ik het "Object detection" artikel lees, moet ik testen of de browser het "oncentextmenu" object kent.
JavaScript:
1
if($('iView').contentDocument.body.oncontextmenu) --> false

Hoe moet ik het wel doen?

Checken of de browser de functionaliteit ondersteund is idd een veel nettere manier dan de manier waarop ik het nu doe.

Lost In Music


Acties:
  • 0 Henk 'm!

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 04-06 14:41
JavaScript:
1
2
3
4
5
6
7
if (document.body.oncontextmenu){
//IE
}else if (window.oncontextmenu){
//FF
}else{
alert('You browser is not supported, sorry');
}

[ Voor 15% gewijzigd door Rekcor op 31-05-2010 15:39 ]


Acties:
  • 0 Henk 'm!

  • Sgrovert
  • Registratie: Mei 2004
  • Laatst online: 17:12
Deze code werkt niet. "document.body.oncontextmenu" geeft in IE false.

Lost In Music


Acties:
  • 0 Henk 'm!

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 04-06 14:41
Mmm... inderdaad. Ontextmenu is in alle gevallen 'gewoon' een eigenschap van het object, en zal dus altijd null teruggeven.

Heb je hier iets aan? http://perfectionkills.co...without-browser-sniffing/

Acties:
  • 0 Henk 'm!

  • Sgrovert
  • Registratie: Mei 2004
  • Laatst online: 17:12
Niet direct, maar heeft me wel op een ander idee gebracht.
Wat vind je van devolgende oplossing :
JavaScript:
1
2
3
4
5
    if(typeof(doc.body.oncontextmenu)=="object"){ //IE 
        doc.body.oncontextmenu = clicker; 
    } else { //FF
        $('iView').contentWindow.addEventListener('contextmenu', clicker, true);
    }

Lost In Music


Acties:
  • 0 Henk 'm!

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 04-06 14:41
Sgrovert schreef op woensdag 02 juni 2010 @ 14:19:
Niet direct, maar heeft me wel op een ander idee gebracht.
Wat vind je van devolgende oplossing :
JavaScript:
1
2
3
4
5
    if(typeof(doc.body.oncontextmenu)=="object"){ //IE 
        doc.body.oncontextmenu = clicker; 
    } else { //FF
        $('iView').contentWindow.addEventListener('contextmenu', clicker, true);
    }
Ok, maar wat als je bezoeker Opera, Safari etc heeft? Die krijgen nu de FF-implementatie.

Acties:
  • 0 Henk 'm!

  • Sgrovert
  • Registratie: Mei 2004
  • Laatst online: 17:12
dat weet je niet. Dat in het commentaar //IE staat betekend niet direct dat andere browsers het object ook niet kennen.
Verder is het voor mijn toepassing voorlopig voldoende om het alleen voor FF en IE werkend te hebben. Ik hoop dat tegen de tijd dat er vraag vanuit andere browsers komt, html 5 ondersteund word.

Lost In Music


Acties:
  • 0 Henk 'm!

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 04-06 14:41
Sgrovert schreef op woensdag 02 juni 2010 @ 18:37:
dat weet je niet. Dat in het commentaar //IE staat betekend niet direct dat andere browsers het object ook niet kennen.
Misschien het commentaar veranderen in 'Browser supports body.oncontextmenu (e.g. IE8)' en 'Browser supports....'? Nu lijkt het een IE-only-hack. Maar goed, klein puntje natuurlijk :).

Acties:
  • 0 Henk 'm!

  • Sgrovert
  • Registratie: Mei 2004
  • Laatst online: 17:12
Voor mij is belangrijk dat ik weet dat het betreffende statement te maken heeft met de browser-interpretatie. Mochten dingen in bepaalde browsers niet werken heb ik dus een hele goede indicatie waar ik moet zoeken. Verder is het vooral een kwestie van smaak en stijl van programmeren.

Er rest overigens wel nog ander vraagje waar hopelijk iemand de oplossing van weet. Als er met de rechtermuisknop op een afbeelding geklikt word, zet te browser een aantal rechthoekjes waarmee het formaat van de afbeelding te wijziggen is. Wie weet welk event hiervoor verantwoordelijk is, en hoe ik dit "blokkeer"?
Nog even een plaatje om mijn verhaal te verduidelijken :
Afbeeldingslocatie: http://img217.imageshack.us/img217/5470/rightd.jpg

Lost In Music


Acties:
  • 0 Henk 'm!

  • bindsa
  • Registratie: Juli 2009
  • Niet online
Sgrovert schreef op zondag 06 juni 2010 @ 00:34:
Voor mij is belangrijk dat ik weet dat het betreffende statement te maken heeft met de browser-interpretatie. Mochten dingen in bepaalde browsers niet werken heb ik dus een hele goede indicatie waar ik moet zoeken. Verder is het vooral een kwestie van smaak en stijl van programmeren.

Er rest overigens wel nog ander vraagje waar hopelijk iemand de oplossing van weet. Als er met de rechtermuisknop op een afbeelding geklikt word, zet te browser een aantal rechthoekjes waarmee het formaat van de afbeelding te wijziggen is. Wie weet welk event hiervoor verantwoordelijk is, en hoe ik dit "blokkeer"?
Nog even een plaatje om mijn verhaal te verduidelijken :
[afbeelding]
Welke browser bedoel je? (Kan het hier namelijk in IE8 en Chrome niet reproduceren) En bedoel je die zes witte vierkantjes die je in jouw screenshot rondom het plaatje ziet?

Acties:
  • 0 Henk 'm!

  • Sgrovert
  • Registratie: Mei 2004
  • Laatst online: 17:12
L0calh0st schreef op zondag 06 juni 2010 @ 19:40:
En bedoel je die zes witte vierkantjes die je in jouw screenshot rondom het plaatje ziet?
Die ja. Wanneer er met de rechtermuisknop geklikt word wil ik niet dat ze getoond worden.
Welke browser bedoel je? (Kan het hier namelijk in IE8 en Chrome niet reproduceren)
komt omdat een normale webpagina niet met designMode = "on"; word weergegeven.

Lost In Music


Acties:
  • 0 Henk 'm!

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 04-06 14:41

Acties:
  • 0 Henk 'm!

  • Klaasvaak
  • Registratie: Maart 2010
  • Laatst online: 04-06 10:55
Voor IE kan je deze code gebruiken.
img.oncontrolselect = function(){return false;};

Als je events toevoegt is het bovendien netter om te kijken of addEventListener aanwezig is, dan om te kijken of element.on(event) een object is.

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
var addEvent = (function(){
 var addEvent;
 //W3
 if(document.addEventListener){
  addEvent = function(node, type, handler){
   node.addEventListener(type, handler, true);
  };
 }
 //IE
 else if(document.attachEvent){
  addEvent = function(node, type, handler){
   node.attachEvent('on'+type, handler);
  };
 }
 //FALLBACK
 else {
  addEvent = function(node, type, handler){
   node['on'+type] = handler;
  };
 };
 return addEvent;
}());

addEvent(element, 'eventtype', function);

function geenMenu(e){
  e = e || window.event;
  e.preventDefault && e.preventDefault();
  return false;
};
addEvent(doc.body, 'contextmenu', geenMenu);
addEvent(img, 'controlselect', function(){return false;});


Houdt er ook rekening mee dat '(on)contextmenu' niet beschikbaar is in Opera.
Pagina: 1