I have a simple jQuery Mobile example with 2 pages and listviews. I'm trying to figure out the best way to bind iScroll. Please checkout my pen below. Currently I've included iScroll but I'm not sure how to properly bind and refresh
http://codepen.io/aherrick/pen/LzCFJ
HTML:
<div id="first" data-role="page">
<div data-role="header" data-position="fixed" data-tap-toggle="false">
<h1>iScroll-ify Me Please!</h1>
</div>
<div role="main">
<div id="scroll-wrap">
<ul id="my-list" data-role="listview"></ul>
</div>
</div>
<div data-role="footer" data-position="fixed" data-tap-toggle="false">
<div data-role="navbar">
<ul>
<li></li>
<li></li>
</ul>
</div>
</div>
</div>
<div id="second" data-role="page">
<div data-role="header" data-position="fixed" data-tap-toggle="false">
Home
<h1>Scroll Me <span id="id"></span></h1>
</div>
<div role="main">
<div id="scroll-wrap2">
<ul id="my-list2" data-role="listview"></ul>
</div>
</div>
<div data-role="footer" data-position="fixed" data-tap-toggle="false">
<div data-role="navbar">
<ul>
<li></li>
<li></li>
</ul>
</div>
</div>
</div>
JS:
$(function () {
$.mobile.paramsHandler.addPage('second', ['id'], null, secondLoad);
$.mobile.paramsHandler.init();
});
$(document).on('pageinit', '#first', function() {
// simulate an AJAX call
setTimeout(function() {
var text = '';
var list = $('#my-list').empty();
for (i = 0; i < 100; i++) {
text += '<li>data loaded from AJAX '+i+'</li>';
}
list.append(text).listview('refresh');
}, 1000);
});
function secondLoad(parms) {
$('#id').text(parms.id);
// simulate a long AJAX call
setTimeout(function() {
var text = '';
for (i = 0; i < 100; i++) {
text += '<li><img src="http://images.nike.com/is/image/DotCom/THN_PS/Nike-Strike-Football-SC2140_144_A.jpg?fmt=jpg&qty=85&wid=620&hei=620"><h2>data loaded from AJAX '+parms.id+'</h2></li>';
}
$('#my-list2').empty().append(text).listview('refresh');
}, 2500);
}
function initScroll(elmId) {
var $this = $(elmId);
$this.css('position', 'absolute')
.css('overflow', 'hidden')
.css('top', '0')
.css('bottom', '0')
.css('left', '0')
.css('width', '100%');
return new IScroll($this.get(0), {
eventPassthrough: false,
scrollX: false,
scrollY: true,
preventDefault: false,
scrollbars: true,
mouseWheel: true,
interactiveScrollbars: true,
shrinkScrollbars: 'clip',
useTransition: false,
bindToWrapper: true,
bounceEasing: 'elastic',
bounceTime: 1200,
probeType: 3, // watch the scroller
fadeScrollbars: false
});
}
How about right after appending the listitems and refreshing the listview:
list.append(text).listview('refresh');
var page1Scroll = initScroll("#scroll-wrap");
and
$('#my-list2').empty().append(text).listview('refresh');
var page2Scroll = initScroll("#scroll-wrap2");
Updated PEN
Related
Here is my owl carousel HTML and javascript.
HTML:
<div id="owl-demo" class="owl-carousel owl-theme">
<div class="item" data-hash="slide1">
<img src="images/mainslider.png">
<h1>Heading</h1>
<p>Paragraph Text</p>
</div>
<div class="item" data-hash="slide2">
<img src="images/mainslider.png">
<h1>Heading</h1>
<p>Paragraph Text</p>
</div>
<div class="item" data-hash="slide3">
<img src="images/mainslider.png">
<h1>Heading</h1>
<p>Paragraph Text</p>
</div>
</div>
JavaScript:
$("#owl-demo").owlCarousel({
navigation : true, // Show next and prev buttons
slideSpeed : 300,
paginationSpeed : 400,
items : 1,
itemsDesktop : false,
itemsDesktopSmall : false,
itemsTablet: false,
itemsMobile : false,
URLhashListener:true,
autoplayHoverPause:true,
startPosition: 'URLHash'
});
I have a navigation block below it that uses Url Hash Navigation.
<nav class="navbar navbar-default secondary-navbar">
<div class="container-fluid">
<div class="container">
<ul class="nav navbar-nav">
<li>Slide 1</li>
<li>Slide 2</li>
<li>Slide 3</li>
</ul>
</div>
</div>
When a slide is clicked to or comes on screen, I need the corresponding link to change it's styles to show it is the one currently active.
I haven't found any native way to do this in Owl Carousel and wasn't sure how to accomplish this with Javascript
After playing around for a long time, I came up with the solution.
Add #link as class in hash navigations, and one more additional class in this case "slidetabs" e.g. <a class="night_tubing slidetabs" href="#night_tubing">NIGHT TUBING</a>
Get the current slide item and then its data-hash
Feed that data hash as a class in on changed function for adding class to navigation button
Then repeat same for change event to remove active class
Add a css to .slidetabs.active
$('.owl-carousel').on('changed.owl.carousel', function(event) {
var current = event.item.index;
var hash = $(event.target).find(".owl-item").eq(current).find(".item").attr('data-hash');
$('.'+hash).addClass('active');
});
$('.owl-carousel').on('change.owl.carousel', function(event) {
var current = event.item.index;
var hash = $(event.target).find(".owl-item").eq(current).find(".item").attr('data-hash');
$('.'+hash).removeClass('active');
});
Note: this is works as expected so I have not worked any further on it, there may be better solutions with good coding out there.
following is the full code:
Slider HTML:
<div class="owl-carousel owl-theme owl-loaded owl-drag">
<div class="owl-stage-outer">
<div class="owl-stage">
<div class="owl-item">
<div class="item" data-hash="cowboy_coaster">
<!-- Slide Content -->
</div>
</div>
<div class="owl-item">
<div class="item" data-hash="night_tubing">
<!-- Slide Content -->
</div>
</div>
<!-- . -->
<!-- . -->
<!-- . -->
<!-- . -->
</div>
</div>
</div>
</div>
<div class="owl-nav">
<button type="button" role="presentation" class="owl-prev">
<img class="slider-arrow" src="/wp-content/uploads/2019/01/slider-arrow-pre.png">
<div class="slider-counter">1 / 4</div>
</button>
<button type="button" role="presentation" class="owl-next"><img class="slider-arrow" src="/wp-content/uploads/2019/01/slider-arrow-next.png"></button>
</div>
<div class="owl-dots disabled"></div>
<div class="owl-slider-tabs">
<ul>
<li>
<a class="dining slidetabs active" href="#dining">DINING</a>
</li>
<li>
<a class="night_tubing slidetabs" href="#night_tubing">NIGHT TUBING</a>
</li>
<li>
<a class="cowboy_coaster slidetabs" href="#cowboy_coaster">COWBOY COASTER</a>
</li>
<li>
<a class="lift_tickets slidetabs" href="#lift_tickets">LIFT TICKETS</a>
</li>
</ul>
</div>
Javascript:
jQuery(document).ready(function($) {
$('.owl-carousel').on('initialized.owl.carousel changed.owl.carousel', function(e) {
if (!e.namespace) {
return;
}
var carousel = e.relatedTarget;
$('.slider-counter').text(carousel.relative(carousel.current()) + 1 + ' / ' + carousel.items().length);
}).owlCarousel({
nav:true,
navText: ["<img class='slider-arrow' src='/wp-content/uploads/2019/01/slider-arrow-pre.png'><div class='slider-counter'>1 / 3</div>","<img class='slider-arrow' src='/wp-content/uploads/2019/01/slider-arrow-next.png'>"],
loop:true,
slideSpeed : 300,
paginationSpeed : 400,
items:1,
dots:false,
URLhashListener:true,
startPosition: 'URLHash',
autoplay:true,
autoplayTimeout:9000,
autoplayHoverPause:true,
animateOut: 'fadeOut',
animateIn: 'fadeIn',
responsiveClass:true,
responsive:{
0:{
items:1,
nav:true
},
600:{
items:1,
nav:true
},
1000:{
items:1,
nav:true
}
}
});
$('.owl-carousel').on('changed.owl.carousel', function(event) {
var current = event.item.index;
var hash = $(event.target).find(".owl-item").eq(current).find(".item").attr('data-hash');
$('.'+hash).addClass('active');
});
$('.owl-carousel').on('change.owl.carousel', function(event) {
var current = event.item.index;
var hash = $(event.target).find(".owl-item").eq(current).find(".item").attr('data-hash');
$('.'+hash).removeClass('active');
});
});
CSS:
.slidetabs.active {
color: #ce2d27;
text-decoration: underline;
}
Owl Carousel supports this natively, see here in the docs:
https://owlcarousel2.github.io/OwlCarousel2/docs/api-classes.html
I am using object-oriented javascript to show/hide 'views' on click of the nav link and also on a button that is used to go to the next view. I feel like this can definitely be simplified but I am not sure what the best way to do this is. My html is as follows:
<div id="sidebar">
<svg width="261" height="70"><use xlink:href="#logo"></use></svg>
<nav>
<ol>
<li><span>1</span>Run your business</li>
<li><span>2</span>Let us work for you</li>
<li><span>3</span>Check your books</li>
</ol>
</nav>
<a class="progress-btn main-btn visible" href="#">Start the demo</a>
<a class="progress-btn main-btn" href="#">Next</a>
<a class="progress-btn main-btn" href="#">Next</a>
<a class="progress-btn main-btn" href="#">30-day free trial</a>
</div><!--end sidebar-->
<div id="content">
<div class="page page1">
<h2>Page 1</h2>
</div><!--end page1-->
<div class="page page2">
<h2>Page 2</h2>
</div><!--end page2-->
<div class="page page3">
<h2>Page 3</h2>
</div><!--end page3-->
<div class="page page4">
<h2>Page 4</h2>
</div><!--end page4-->
</div><!--end content-->
And my object looks like this:
View = {
page: '.page',
mainLink: '#sidebar li a',
progressButton: '.progress-btn',
init: function() {
$(this.mainLink).click(this.showView.bind(this));
$(this.mainLink).click(this.activeNav.bind(this));
$(this.progressButton).click(this.sidebarButton.bind(this));
},
showView: function(e) {
e.preventDefault();
var target = $(e.target),
targetIndex = target.index(this.mainLink),
pageToTarget = targetIndex + 2;
$(this.page).removeClass("current").fadeOut('fast').promise().done(function() {
$('.page' + pageToTarget).fadeIn().addClass("current");
});
},
activeNav: function(e) {
$(this.mainLink).removeClass("active");
e.preventDefault();
$(e.target).addClass("active");
var targetIndex = $(e.target).index(this.mainLink)
$(".progress-btn").removeClass("visible");
$(".progress-btn").eq(targetIndex + 1).addClass("visible");
},
sidebarButton: function(e) {
e.preventDefault();
var target = $(e.target);
targetIndex = target.index(this.progressButton);
pageToTarget = targetIndex + 2;
if (target.text() == "30-day free trial") {
window.open("http://google.com");
} else {
target.removeClass("visible");
target.next().addClass("visible");
$(this.page).removeClass("current").fadeOut('fast').promise().done(function() {
$('.page' + pageToTarget).fadeIn().addClass("current");
});
$(this.mainLink).removeClass("active");
$("#sidebar li a").eq(targetIndex).addClass("active");
}
console.log(targetIndex);
// pageRoute(targetIndex);
}
}
View.init();
Here is a fiddle https://jsfiddle.net/rsgLbgg3/4/. How can I simplify this to work with both the nav and the button without being so repetitive.
Just learning to learn a little. Thanks in advance!
I've been trying to get the automatic update on my navbar but i cant get it to work.
Here is my code: http://pastebin.com/YTHaBD0i
<div id="header">
<ul class="nav-list">
<li class="download selected">Download</li>
<li class="features">Features</li>
<li class="method">Method</li>
<li class="purchase">Purchase</li>
</ul>
</div>
<div id="footer">yey productions © 2016</div>
<div id="fullpage">
<div class="section " id="section0">
<div class="intro">
<h1>Download</h1>
<p>Lorem Ipsum</p>
</div>
</div>
<div class="section" id="section1">
<div class="slide" id="slide1">
<div class="intro">
<h1>Features</h1>
<p>Cheese.</p>
</div>
</div>
<div class="slide" id="slide2">
<h1>Cheese2</h1>
</div>
</div>
<div class="section" id="section2">
<div class="intro">
<h1>Yey</h1>
</div>
</div>
<div class="section" id="section3">
<div class="intro">
<h1>Yey2</h1>
</div>
</div>
</div>
Help would be much appreciated!
Greetz,
Assuming you are using jQuery, you will need a function that fires every time you scroll.
From there, you need to detect which elements are in view.
Once you know which elements are in view, clear any currently active elements with the .selected class, then choose which one you want to be .selected and add the .selected class.
Edit for more detail:
Below is a pure JavaScript solution, which I found here. This should be close to a drop-in solution!:
(function() {
'use strict';
var section = document.querySelectorAll(".section");
var sections = {};
var i = 0;
Array.prototype.forEach.call(section, function(e) {
sections[e.id] = e.offsetTop;
});
window.onscroll = function() {
var scrollPosition = document.documentElement.scrollTop || document.body.scrollTop;
for (i in sections) {
if (sections[i] <= scrollPosition) {
document.querySelector('.selected').setAttribute('class', ' ');
document.querySelector('a[href*=' + i + ']').setAttribute('class', 'selected');
}
}
};
})();
I've edited the code provided from here to cater for two carousel without it being id dependent, which works fine, except that I can't get the tabs to work properly upon click. (E.g, removing the class "synced" and adding them onto the clicked tab properly.) Think I'm not doing something right with both function syncPosition and function left.
Where did I miss out, or did wrong?
HTML:
<!--Carousel 1-->
<div class="tabslider">
<div class="owl-carousel tabthumb">
<div class="item" >1</div>
<div class="item" >2</div>
<div class="item" >3</div>
<div class="item" >4</div>
<div class="item" >5</div>
</div>
<div class="owl-carousel tabcontent">
<div class="item">Content 1</div>
<div class="item">Content 2</div>
<div class="item">Content 3</div>
<div class="item">Content 4</div>
<div class="item">Content 5</div>
</div>
</div>
<!--Carousel 2-->
<div class="tabslider">
<div class="owl-carousel tabthumb">
<div class="item" >1</div>
<div class="item" >2</div>
<div class="item" >3</div>
<div class="item" >4</div>
</div>
<div class="owl-carousel tabcontent">
<div class="item">Content 1</div>
<div class="item">Content 2</div>
<div class="item">Content 3</div>
<div class="item">Content 4</div>
</div>
Script:
<script>
$(document).ready(function() {
$('.tabslider').each(function(){
var sync1 = $(this).children(".tabcontent");
var sync2 = $(this).children(".tabthumb");
sync1.owlCarousel({
singleItem : true,
slideSpeed : 1000,
pagination:false,
afterAction : syncPosition,
responsiveRefreshRate : 200,
});
sync2.owlCarousel({
items : 3,
itemsDesktop : [1199,3],
itemsDesktopSmall : [979,3],
itemsTablet : [768,2],
itemsMobile : [479,2],
pagination:false,
navigation: false,
navigationText: [
"<i class='icon-arrow-left7'></i>",
"<i class='icon-uniE6E2'></i>"
],
responsiveRefreshRate : 100,
afterInit : function(el){
el.find(".owl-item").eq(0).addClass("synced");
}
});
function syncPosition(el){
var current = this.currentItem;
// $(".tabthumb")
$(this).find(".tabthumb")
.find(".owl-item")
.removeClass("synced")
.eq(current)
.addClass("synced")
if($(this).children(".tabthumb").data("owlCarousel") !== undefined){
left(current)
console.log(this)
}
}
$(this).children(".tabthumb").on("click", ".owl-item", function(e){
e.preventDefault();
var number = $(this).data("owlItem");
sync1.trigger("owl.goTo",number);
});
function left(number){
var sync2visible = sync2.data("owlCarousel").owl.visibleItems;
var num = number;
var found = false;
for(var i in sync2visible){
if(num === sync2visible[i]){
var found = true;
}
}
if(found===false){
if(num>sync2visible[sync2visible.length-1]){
sync2.trigger("owl.goTo", num - sync2visible.length+2)
}else{
if(num - 1 === -1){
num = 0;
}
sync2.trigger("owl.goTo", num);
}
} else if(num === sync2visible[sync2visible.length-1]){
sync2.trigger("owl.goTo", sync2visible[1])
} else if(num === sync2visible[0]){
sync2.trigger("owl.goTo", num-1)
}
}
})
});
</script>
JS:
//remove the following(and its closing tag of course) :
$('.tabslider').each(function(){
//modify this part:
$(this).children(".tabthumb").on("click", ".owl-item", function(e)
{
//we modify our trigger to only apply to our current gallery, not all of them
e.preventDefault();
var number = $(this).data("owlItem");
//The navigation with the thumbnails
var $thumbnailNavWrapper = $(this).closest('your-thumbnail-navigation-class');
//the slider with the big images .prev or .next depending on
whether we find our slider before or next to the thumbnail navigation
$sync1 = $thumbnailNavWrapper.prev();
sync1.trigger("owl.goTo",number);
});
If the above is not enough and you need a thumbnail nav with a "centerized" style.
function center(number){
var sync2visible = $sync2.data("owlCarousel").owl.visibleItems;
var num = number;
if(num === sync2visible[0])
{
$sync2.trigger("owl.goTo", num-1);
}
else if(sync2visible.length <= 2)
{
$sync2.trigger("owl.goTo", num+1);
}
else
{
$sync2.trigger("owl.goTo", num-1);
}
}
Not sure if this will 100% help. Just made mine with the same issue.
I use list_carousel slider to run posts with HTML like that :
<div class="list_carousel">
<div id='gallary'>
<ul id='foo3'>
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
</div>
</div>
I use document.write, slider run ok.
<div class="list_carousel">
<div id='gallary'>
<script>
document.write('<ul id="foo3">');
document.write('<li>A</li>');
document.write('<li>B</li>');
document.write('<li>C</li>');
document.write('<ul>');
</script>
</div>
</div>
But when I use innerHTML, slider does not run :
<div class="list_carousel">
<div id="gallary">
</div>
document.getElementById('gallary').innerHTML = " <ul id='foo3'>..... </ul>";
</div>
Slider run with call :
<script>
$("#foo3").carouFredSel({
auto: false,
responsive: true,
scroll: 1,
mousewheel: true,
items: {
visible: 3,
width: 200
}
});
</script>
Say me reason why and solution for this.