2016-09-08 18 views
10

Pracuję nad stroną internetową, która osadza inną stronę z innej domeny wewnątrz elementu iframe. Zawartość tej strony dokładnie pasuje do elementu iframe, więc nie ma przepełnionej zawartości ani pasków przewijania. Jednak zawartość można powiększać za pomocą kółka myszy.Zatrzymaj przewijanie na powiększonym elemencie iframe

Jednak w Safari i Chrome powiększanie za pomocą kółka myszy powoduje również przewinięcie całej strony. Nie chcę, aby to było przewijanie - tylko powiększanie elementu iframe. Jak zatrzymać przewijanie, gdy wskaźnik myszy znajduje się nad ramką iframe?

Podjęto próbę odtworzenia problemu w minimalnym przykładzie na JSFiddle: https://jsfiddle.net/twodee/57a68k3h. Po powiększeniu zielonego elementu iframe tekst jest powiększany, ale strona również się przewija.

frame = document.getElementById('myframe'); 
 
frame_child = document.createElement('div'); 
 

 
var font_size = 12; 
 
frame_child.addEventListener('wheel', function(e) { 
 
    font_size += e.wheelDelta; 
 
    frame_child.style.fontSize = font_size + 'px'; 
 
}); 
 

 
frame_child.style.width = '190px'; 
 
frame_child.style.height = '190px'; 
 
frame_child.innerHTML = 'this text should zoom'; 
 
frame.contentWindow.document.body.appendChild(frame_child);
#myframe { 
 
    background-color: #00FF00; 
 
}
<ul> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
    <li>a</li> 
 
</ul> 
 
<div> 
 
    <iframe id="myframe" height="200px" width="800px" src="about:blank"></iframe> 
 
</div> 
 
<ul> 
 
    <li>b</li> 
 
    <li>b</li> 
 
    <li>b</li> 
 
    <li>b</li> 
 
    <li>b</li> 
 
    <li>b</li> 
 
    <li>b</li> 
 
    <li>b</li> 
 
    <li>b</li> 
 
    <li>b</li> 
 
    <li>b</li> 
 
    <li>b</li> 
 
    <li>b</li> 
 
</ul>

EDIT: Powyższy przykład jest trochę mylące, że źródło iframe naprawdę nie jest generowany dynamicznie przez własnego scenariusza. Zamiast tego źródło jest generowane przez osobną stronę internetową, która oczekuje wprowadzenia formularza od requestera. Oto CodePen, który lepiej pokazuje mój problem: http://codepen.io/twodee/pen/PGqgyw. (JSFiddle zezwala tylko na źródła https: //.)

Po przejściu przez element iframe kostka 3D zostanie powiększona, a strona przewinięta.

EDYCJA: Efekt, którego szukam, jest tym, co widzę, gdy Mapy Google są osadzone na stronie. Lub Sketchfab. Kiedy umieszczam je w elemencie iframe, nie muszę robić nic specjalnego na stronie, która wykonuje osadzanie, aby powiększanie odbywało się bez przewijania. Wydaje się, że coś w samej treści osadzonej wyłącza przewijanie, ale nie wiem co.

+0

StackOverflow Run fragment kodu nie działa z powodu polityki cross-pochodzenia. JSFiddle działa. – kaerimasu

Odpowiedz

2

Jak stwierdzili inni, preventDefault() działa dobrze dla twojego pierwszego przykładu, gdzie jest div.

Nie jest to jednak możliwe w przypadku ramek iframe do zewnętrznych stron, ponieważ tylko niektóre zdarzenia są przechwytywane w elemencie iframe. Na tym współdzieleniu widać, że zdarzenie mouseenter jest przechwytywane w elemencie iframe, ale kliknięcie i kółko nie są wykonywane. Zwróć szczególną uwagę na instrukcje console.log (docelowe), które działają, a które nie.

Codepen

<iframe id="myframe" src="http://www.w3schools.com"> 
</iframe> 
<br> 
<div id="div1"> 
    test 
</div> 
<div id="div2"> 
</div> 

CSS

iframe { 
    width:600px; 
    height:200px; 
    border: 10px solid red; 
} 
div { 
width:600px; 
height:40px; 
border: 10px solid blue; 
} 
#div2 { 
width:600px; 
height:800px; 
border: 10px solid green; 
} 

JS

frame = document.getElementById('myframe'); 
div = document.getElementById('div1'); 

frame.addEventListener('mouseenter', function(e) { 
    console.log('entered'); 
    var target = e.target; 
    console.log(target); 
}); 
frame.addEventListener('click', function(e) { 
    console.log('clicked'); 
    var target = e.target; 
    console.log(target); 
}); 
frame.addEventListener('wheel', function(e) { 
    console.log('wheel'); 
    var target = e.target; 
    console.log(target); 
}); 

font_size = 12; 
div1.addEventListener('wheel', function(e) { 
    var target = e.target; 
    console.log(target); 
    font_size += -e.wheelDelta/100; 
    this.style.fontSize = font_size + 'px'; 

    if(target.id === 'div1') 
    e.preventDefault(); 
}); 

Aktualizacja: Skoro mówisz, że mają kontrolę nad zawartością iframe, możesz dodać zdarzenie koła przewodnik do oprawionego zadowolony. Spróbuj tego ...

HTML na ramce zawartości

<div id="framedDiv"> 
    abc<br> 
    def<br> 
    ghi<br> 
    jkl<br> 
    mno<br> 
    pqr<br> 
    stu<br> 
    vwx<br> 
    abc<br> 
    def<br> 
    ghi<br> 
    jkl<br> 
    mno<br> 
    pqr<br> 
    stu<br> 
    vwx<br> 
    abc<br> 
    def<br> 
    ghi<br> 
    jkl<br> 
    mno<br> 
    pqr<br> 
    stu<br> 
    vwx<br> 
</div> 

JS na ramce zawartości

framed = document.getElementById('framedDiv'); 
font_size = 12; 

framed.addEventListener('wheel', function(e) { 
    var target = e.target.id; 
    console.log(target); 
    font_size += -e.wheelDelta/100; 
    this.style.fontSize = font_size + 'px'; 
    e.preventDefault(); 
}); 
+0

W jakiś sposób witryny takie jak SketchFab powodują, że powiększanie nie rozprzestrzenia się do ramki rodzica i prowadzi do przewijania. Jest coś w treści iframe, które ma na to wpływ. Mam kontrolę nad zawartością elementów iframe, ale nie wiem, jakie właściwości poprawić. W twoim CodePen, ramka nadrzędna zaczyna przewijać, gdy tylko osiągnąłem dno treści elementu iframe. W przypadku moich treści zasadniczo nie mam dna (lub góry) i nigdy nie chcę, aby przewijanie się wydarzyło. – kaerimasu

+0

Zaktualizowałem moją odpowiedź, ponieważ mówisz, że masz kontrolę nad zawartością ramki - dodaj zdarzenie koła do strony treści z ramkami. – RSSM

+0

Dzięki. Wygląda na to, że otrzymałem odpowiedź kilka dni temu, gdybym właśnie zdał sobie sprawę, że słuchacz kół musi być częścią zawartości iframe. – kaerimasu

1

dodać detektor do okna nadrzędnego (iframe) i spróbuj tego:

window.addEventListener("wheel", function() { 

    if ($("#myframe").is(":hover")) { 

     // call iframe zoom function here 

     return false; 

    } 

}); 

Kiedy mysz znajduje się nad iframe, return false na przewijania okna, ale wykonać zoom.

+0

Próbowałem tego, ale podczas gdy rzeczywiście otrzymuję zwrotne połączenia podczas unoszące się nad elementami w rodzica, nie dostaję żadnego, gdy przewracam iframe. To sprawia, że ​​mam wrażenie, że musi to być własność samej iframe lub jej zawartości. – kaerimasu

3

Możesz dodać detektory zdarzeń myszy na iframe, aby sprawdzić, czy mysz jest w nim, a jeśli jest on następnie zatrzymać zwój dzieje w oknie:

frame = document.getElementById('myframe'); 
frame_child = document.createElement('div'); 
var font_size = 12; 
var inFrame=false; 
frame_child.addEventListener('wheel', function(e) { 
    font_size += e.wheelDelta; 
    frame_child.style.fontSize = font_size + 'px'; 
}); 
frame.addEventListener("mouseover",function(e){ 
inFrame=true; 
}); 
frame.addEventListener("mouseout",function(e){ 
inFrame=false; 
}); 
window.addEventListener('wheel',function(e){ 
if(inFrame) 
    e.preventDefault(); 
}) 
frame_child.style.width = '190px'; 
frame_child.style.height = '190px'; 
frame_child.innerHTML = 'this text should zoom'; 
frame.contentWindow.document.body.appendChild(frame_child); 

Wystarczy dodać zapobiec domyślne na div słuchacza koła:

frame_child.addEventListener('wheel', function(e) { 
e.preventDefault(); 
    font_size += e.wheelDelta; 
    frame_child.style.fontSize = font_size + 'px'; 
}); 
+0

Co jeśli zawartość iframe nie była tak wygodnie wygenerowana jak w przykładzie? Dodałem fragment kodu, który wierniej demonstruje mój problem. – kaerimasu

+0

To była odpowiedź, ale kod musi być częścią osadzonej treści elementu iframe, a nie częścią kontekstu osadzania. – kaerimasu

2

użyć tego kodu na myszy :hover

$("#myframe").hover(
    function() { 
    function disableScroll() { 
    if (window.addEventListener) // older FF 
     window.addEventListener('DOMMouseScroll', preventDefault, false); 
    window.onwheel = preventDefault; // modern standard 
    window.onmousewheel = document.onmousewheel = preventDefault; // older browsers, IE 
    window.ontouchmove = preventDefault; // mobile 
    document.onkeydown = preventDefaultForScrollKeys; 
    }, function() { 
    if (window.removeEventListener) 
     window.removeEventListener('DOMMouseScroll', preventDefault, false); 
    window.onmousewheel = document.onmousewheel = null; 
    window.onwheel = null; 
    window.ontouchmove = null; 
    document.onkeydown = null; 
    } 
); 

$("#myframe.fade").hover(function() { 
    $(this).fadeOut(100); 
    $(this).fadeIn(500); 
Powiązane problemy