- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我有一个 slider ,它通过 touchmove 事件检测滑动并相应地移动内容。但是,当内容中有 iframe 时,我在 iframe 上滑动手指,页面不会移动,因为 touchmove 事件是由 iframe 本身拦截的,而不是父页面。因此父 div 不会移动。
这个 iframe 也需要保持可点击,因为它是一个广告,所以我不能用另一个具有更高 z-index 的 div 覆盖它。
我可以在 Javascript 中做什么来将 touchmove 事件冒泡到父级?他们在同一个域中。任何帮助将不胜感激!
我使用的 slider 是这个 - http://dezignhero.github.io/swiper.js/ (当页面中没有 iframe 时效果很好)
var Swiper = function(selector, options) {
/*------- Globals -------*/
var viewportWidth = 0,
frameWidth = 0,
animating = false,
numSlides = 0,
limitEnd = 0,
goTo = 0,
currentSlide = 0,
orientation = 0;
// Swiping
var swipe = {
started : false,
startX : 0,
endX : 0,
at : 0,
strength : 0
};
// Settings
var settings = {
ease : 0.3,
swipeMin : 40,
preventAdvance : false,
container : '.container',
frame : '.page',
frameWidth : false, // accepts a number in pixels
controls : '.control',
clickEvent : 'click',
updateEvent : 'update',
controlsOnly : false,
};
/*------- Handles -------*/
var el = selector,
$parent = $(el),
$container, $controls, $frame, $prevCtrl, $nextCtrl;
/*------- Methods -------*/
var init = function(options) {
// Exit if element doesn't exist
if ( $(el).length == 0 ) return;
// Merge settings
settings = $.extend(settings, options || {});
// Initialize handles
$container = $(settings.container, el);
$controls = $(settings.controls, el);
$frame = $(settings.frame, el);
// Assign Ids to frames
$frame.each(function(i){
$(this).attr('data-id', i);
numSlides++;
});
// Add initial class
$($frame.selector+'[data-id=0]', el).addClass('current');
// Set Dimensions
resize();
// Setup CSS
$container.css({
'-webkit-transition' : 'all '+settings.ease+'s ease-out',
'-webkit-transform' : 'translate3d(0,0,0)', // Performance optimization, put onto own layer for faster start
'left' : 0
});
// Monitoring controls if they exist
if ( $controls.length > 0 ) {
// Determine whether or not to use click event
if ('ontouchstart' in document.documentElement) {
settings.clickEvent = 'touchstart';
}
// Create handlers
$prevCtrl = $(settings.controls+'[data-action=prev]');
$nextCtrl = $(settings.controls+'[data-action=next]');
// Bind behavior
$controls.on(settings.clickEvent, function(){
var self = $(this),
action = self.attr('data-action');
// Ensure action defined
if ( typeof action == 'undefined' ) return;
if ( action == 'next' && currentSlide < numSlides - 1 ) {
goTo = currentSlide + 1;
} else if ( action == 'prev' && currentSlide > 0 ) {
goTo = currentSlide - 1;
}
// Move container
jumpTo(goTo);
});
}
// Display controls correctly
if ( settings.preventAdvance ) {
disableSliding();
} else {
updateControls();
}
// Swiping
if ( !settings.controlsOnly ) {
$container[0].addEventListener('touchstart', function(e) { touchStart(e); }, false);
$container[0].addEventListener('touchmove', function(e) { touchMove(e); }, false);
$container[0].addEventListener('touchend', function(e) { touchEnd(e); }, false);
// Desktop
$container[0].addEventListener('mousedown', function(e) { touchStart(e); }, false);
$container[0].addEventListener('mousemove', function(e) { if (e.which==1) { touchMove(e); } }, false);
$container[0].addEventListener('mouseup', function(e) { touchEnd(e); }, false);
}
// Prevent anchor tags from getting in the way
$('a', el).on('touchstart click', function(){
return swipe.started ? false : true;
});
// Prevent image dragging on getting in the way
$('img', el).on('dragstart', function(){
return false;
});
// Check if Android
var ua = navigator.userAgent.toLowerCase(),
isAndroid = ua.indexOf("android") > -1;
// Orientation Change
var supportsOrientationChange = "onorientationchange" in window,
orientationEvent = (supportsOrientationChange && !isAndroid) ? "orientationchange" : "resize";
// Listener for orientation changes
window.addEventListener(orientationEvent, function() {
// Prevent 'fake' orientation calls
if ( orientation != window.orientation ) {
orientation = window.orientation;
resize(function(){
jumpTo(currentSlide);
});
}
}, false);
},
resize = function(callback){
viewportWidth = $parent.width();
frameWidth = ( settings.frameWidth ) ? settings.frameWidth : viewportWidth;
// Apply new sizes
$frame.width(frameWidth);
$container.width(frameWidth*numSlides);
// Set end limit
limitEnd = settings.frameWidth ? viewportWidth/frameWidth : numSlides;
// callback
if ( typeof callback == 'function' ) {
callback();
}
},
touchStart = function(e) {
swipe.at = getPosition(); // for touch move
// Get start point
swipe.startX = e.touches ? e.touches[0].pageX : e.pageX;
swipe.startY = e.touches ? e.touches[0].pageY : e.pageY;
swipe.endX = swipe.startX; // prevent click swiping when touchMove doesn't fire
},
touchEnd = function(e) {
swipe.started = false;
// Nullify event
e.preventDefault();
if ( animating ) return;
var moved = swipe.endX - swipe.startX,
threshold = frameWidth / 3;
goTo = currentSlide;
// Figure out closest slide
if ( Math.abs(moved) > threshold || swipe.strength > settings.swipeMin ) {
if ( moved > 0 && currentSlide > 0 ) {
goTo--;
} else if ( moved < 0 && currentSlide < limitEnd-1 ) {
goTo++;
}
}
// Jump to closest
jumpTo(goTo);
},
touchMove = function(e) {
if ( !$parent.hasClass('disabled') ) {
swipe.started = true;
var touchX = e.touches ? e.touches[0].pageX : e.pageX,
touchY = e.touches ? e.touches[0].pageY : e.pageY,
dX = touchX - swipe.startX,
dY = touchY - swipe.startY;
swipe.strength = Math.abs(touchX - swipe.endX);
swipe.endX = touchX;
// Escape if motion wrong
if ( Math.abs(dX) < Math.abs(dY) ) return;
e.preventDefault();
// Always run this so that hit the ends
animate(swipe.at+dX, false);
}
},
getPosition = function() {
// Get current point and Stay there
var style = document.defaultView.getComputedStyle($container[0], null),
transform = new WebKitCSSMatrix(style.webkitTransform);
// Return position based on direction
return transform.m41;
},
animate = function(scrollTo, ease) {
// Momentum Effect or Not
$container[0].style.webkitTransition = ( ease ) ? 'all '+settings.ease+'s ease-out' : 'none';
$container[0].style.webkitTransform = 'translate3d('+scrollTo+'px,0,0)';
// Allow animating again
if ( ease ) {
animating = true;
window.setTimeout(function(){
animating = false;
}, settings.ease*1000);
}
},
jumpTo = function(num, ease) {
// Keep within range
if ( num >= 0 && num < limitEnd ) {
// Animate
var hasEase = ( typeof ease !== 'undefined' ) ? ease : true;
animate(-num*frameWidth, hasEase);
// If new slide
if ( num != currentSlide ) {
// Update current slide
currentSlide = num;
// Update current slide
$frame.removeClass('current');
$($frame.selector+'[data-id='+currentSlide+']').addClass('current');
// Update parent to trigger update event and new slide
$parent.trigger(settings.updateEvent, [ currentSlide, Math.floor(limitEnd) ]);
// Control Buttons
updateControls();
// Disable Again
if ( settings.preventAdvance ) {
disableSliding();
}
}
}
},
updateControls = function() {
// Only run if controls exist
if ( $controls.length == 0 ) return;
if ( currentSlide >= 0 && currentSlide < limitEnd ) {
$controls.show();
if ( currentSlide == 0 ) {
$prevCtrl.hide();
} else if ( currentSlide == limitEnd-1 ) {
$nextCtrl.hide();
}
} else {
$controls.hide();
}
},
disableSliding = function() {
// Hide Controls
$('.control', el).hide();
// Add disabled flag
$parent.addClass('disabled');
},
enableSliding = function() {
// Enable control buttons
updateControls();
// Remove disabled flag
$parent.removeClass('disabled');
};
// Initialize the object
init(options);
return {
element : $parent,
jumpTo : jumpTo,
swiping : function() {
return swipe.started;
},
disableSliding : disableSliding,
enableSliding : enableSliding,
status : function() {
return {
'current' : currentSlide+1,
'total' : numSlides
}
},
next : function() {
jumpTo(currentSlide+1);
},
prev : function() {
jumpTo(currentSlide-1);
}
};
最佳答案
问题是 iframe 吞噬了触摸事件。因此,如果有任何 iframe,则在您滑动的区域上,您将无法滑动。我知道的唯一解决方案是用透明的 div 覆盖 iframe,并将所有点击事件分派(dispatch)给 iframe。这样,将在 iframe 上启用 touchmove 事件。
我在这里创建了一个基本的 jquery 插件来执行此操作。 https://gist.github.com/agaase/6971953
用法
$(selector).coverIframes();
这将使用透明的 div 覆盖 $(selector) 内的任何 iframe 并传输任何点击事件。
关于javascript - 在 iframe 上滑动时如何移动父元素?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17076153/
只是想知道 Jquery Mobile 是否足够稳定以用于实时生产企业移动应用程序。 有很多 HTML5 框架,因为我们的团队使用 JQuery 已经有一段时间了,我们更愿意使用 Jquery 移动框
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 3 年前。 Improve t
所以我尝试在 JavaScript 中对元素进行拖放。我使用的视频教程在这里; https://www.youtube.com/watch?v=KTlZ4Hs5h80 。我已经按照它的说明进行了编码,
无法在移动 iOS(safari 和 chrome)上自动播放以前缓存的 mp3 音频 我正在 Angular 8 中开发一个应用程序,在该应用程序的一部分中,我试图在对象数组中缓存几个传入的音频 m
Git 基于内容而不是文件,所以我目前理解以下行为,但我想知道是否有特殊选项或 hack 来检测此类事情: git init mkdir -p foo/bar echo "test" foo/a.tx
我正在寻找语义 ui 正确的类来隐藏例如移动 View 中的 DIV。在 Bootstrap 中,我们有“visible-xs”和“hidden-xs”。 但是在语义ui上我只找到了“仅移动网格” 最
我正在使用 ubuntu 和 想要移动或复制大文件。 但是当我与其他人一起使用服务器时,我不想拥有所有内存并使其他进程几乎停止。 那么有没有办法在内存使用受限的情况下移动或复制文件? 最佳答案 如果你
这些指令有什么区别?以 ARM9 处理器为例,它不应该是: ASM: mov r0, 0 C: r0 = 0; ASM: ld r0, 0 C: r0 = 0; ? 我不知道为什么要使用一个或另一个:
我有一个文件夹,其中包含一些随机命名的文件,其中包含我需要的数据。 为了使用数据,我必须将文件移动到另一个文件夹并将文件命名为“file1.xml” 每次移动和重命名文件时,它都会替换目标文件夹中以前
我经常在 IB/Storyboard 中堆叠对象,几乎不可能拖动其他对象后面的对象而不移动前面的对象。无论如何我可以移动已经选择但位于其他对象后面的对象吗?当我尝试移动它时,它总是选择顶部的对象,还是
几个月前,我看到 Safari 7 允许推送通知,它似乎是一个非常有用的工具,除了我看到的每个示例都专注于桌面浏览,而不是移动设备。 Safari 推送通知是否可以在移动设备上运行,如果没有,是否有计
我有一个简单的 View 模型,其中包含修改后的 ObservableCollection使用 SynchronizationContext.Current.Send在 UI 线程上执行对集合的更改。
关于cassandra创建的数据文件和系统文件的位置,我需要移动在“cassandra.yaml”配置文件中设置的“commitlog_directory”、“data_file_directorie
我有这个代码 $(function() { var message = 'Dont forget us'; var original; var txt1 = ' - '; $(wind
我的客户报告说他的网站有一个奇怪的问题。该网站的 URL 是 your-montenegro.me 在 基于 Android 的浏览器 上加载时,页面底部会出现一个奇怪的空白区域。以下是屏幕截图: 华
我有这个 HTML 标记: Express 300 bsf Sign Up 我需要将元素从 DOM 上的一个
我有一个可重新排序的 TableView (UITableView 实例)。尽管我已经实现了 UITableViewDataSource 方法: tableView:moveRowAtIndexPat
我的客户报告说他的网站有一个奇怪的问题。该网站的 URL 是 your-montenegro.me 在 基于 Android 的浏览器 上加载时,页面底部会出现一个奇怪的空白区域。以下是屏幕截图: 华
我需要在拖放或复制/剪切和粘贴(复制与移动)期间获取操作类型。它是一个 Swing 应用程序,并且实现了 TransferHandle。我在操作结束时需要此信息,在 importData 方法中。 对
我编写了一个具有 add 和 get 方法的 SortedIntList 类。 我调用以下四个方法: SortedIntList mySortedIntList = new SortedIntList
我是一名优秀的程序员,十分优秀!