2016-09-08 4 views
10

Я работаю над веб-страницей, которая вставляет другую страницу из другого домена внутри iframe. Содержимое этой страницы точно соответствует iframe, поэтому нет переполненного содержимого и никаких полос прокрутки. Однако содержимое может быть увеличено с помощью мыши.Остановить прокрутку по масштабируемому iframe

Но в Safari и Chrome, масштабирование с помощью колесика мыши также прокручивает всю страницу. Мне не нужна эта прокрутка - только масштабирование iframe. Как остановить эту прокрутку, когда мышь находится над iframe?

Я попытался воссоздать проблему в минимальном примере на JSFiddle: https://jsfiddle.net/twodee/57a68k3h. Когда я масштабирую зеленый iframe, текст масштабируется, но страница также прокручивается.

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: В приведенном выше примере это немного вводит в заблуждение в том, что источник IFrame не действительно генерируется динамически по собственному сценарию. Вместо этого источник создается отдельным сайтом, который ожидает ввода формы от запрашивающего. Вот код, который лучше демонстрирует мою проблему: http://codepen.io/twodee/pen/PGqgyw. (JSFiddle позволяет только https: // sources.)

Когда я перебираю iframe, масштабирование 3D-кубов и прокрутку страницы.

EDIT: Эффект, который я получаю, - это то, что я вижу, когда Карты Google встроены в страницу. Или Sketchfab. Когда я внедряю их в iframe, мне не нужно делать ничего особенного на странице, которая делает вложение, чтобы сделать масштабирование без прокрутки. Кажется, что-то связано с встроенным контентом, который отключает прокрутку, но я не знаю, что.

+0

StackOverflow Бег Код сниппета не работает из-за политики перекрестного происхождения. JSFiddle работает. – kaerimasu

ответ

2

Как указано другими, preventDefault() отлично подходит для вашего первого примера, где это div.

Но это не представляется возможным в iframe для внешних сайтов, поскольку на iframe фиксируются только определенные события. В этом кодежете вы можете увидеть, что событие mouseenter записывается в iframe, но щелчок и колесо отсутствуют. Обратите пристальное внимание на консольные (целевые) заявления и которые работают, а какие нет.

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(); 
}); 

Обновлено: Так вы говорите, у вас есть контроль над содержанием Iframe, вы можете добавить событие колеса обработчик в рамке содержание. Попробуйте это ...

HTML на структурированном содержание

<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 на структурированном содержание

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

Каким-то сайтам, таким как SketchFab, сделать так, чтобы масштабирование не распространялось на родительский фрейм и приводило к прокрутке. Что-то о содержимом iframe, которое влияет на это. Я контролирую содержимое iframe, но я не знаю, какие свойства нужно настроить. В коде CodePen родительский кадр начинает прокрутку, как только я достиг нижней части содержимого iframe. Для моего контента у меня нет ни дна (или вершины), и я никогда не хочу, чтобы прокрутка произошла. – kaerimasu

+0

Я обновил свой ответ, так как вы говорите, что у вас есть контроль над содержимым кадра - добавьте событие колеса на страницу с рамкой. – RSSM

+0

Спасибо. Похоже, что я бы получил свой ответ несколько дней назад, если бы только что понял, что слушатель колес должен быть частью содержимого iframe. – kaerimasu

1

Добавить прослушиватель для окна (родитель IFrame), и попробовать это:

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

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

     // call iframe zoom function here 

     return false; 

    } 

}); 

Когда мышь парит над IFRAME, вернуться ложным на окне прокрутки, но выполнить масштабирование.

+0

Я пробовал это, но в то время как я действительно получаю обратные вызовы, завися от элементов в родительском, я не получаю ни одного, когда я перебираю iframe. Это заставляет меня чувствовать, что это должно быть какое-то свойство самого iframe или его содержимого. – kaerimasu

3

Вы можете добавить обработчики событий мыши на вашем Iframe, чтобы проверить, если мышь находится в нем, и если после этого остановить свиток происходит на окне:

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); 

Просто добавьте предотвратить по умолчанию на вашем сНу колеса слушателя:

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

Что делать, если содержимое iframe было не так удобно сгенерировано, как в примере? Я добавил фрагмент кода, который более точно демонстрирует мою проблему. – kaerimasu

+0

Это оказалось ответом, но код должен быть частью встроенного содержимого iframe, а не частью контекста внедрения. – kaerimasu

2

использовать этот код на мышь :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); 
Смежные вопросы