I am using creating costume directive in angularjs. I want to scroll the window on click to data-target element. but its showing the error el.bind is not a function
in custome directive code as bellow,
'use strict';
app.directive("productfinderpage", ["$window","$document", function($window, $document) {
console.log("enter into directive");
return {
restrict: "AC",
link: function () {
// get all anchors
var anchors = angular.element(document.querySelectorAll("a[data-target]"));
angular.forEach(anchors, function (el) {
el.bind("click", function (e) {
var targetLink = e.target.dataset.target;
var targetContext = angular.element(document.querySelector("[data-name=\"" + targetLink + "\""));
var targetContextInt = targetContext.offsetTop;
// initiate scroll
scrollTo(scrollable, targetContextInt, 225);
});
});
// scroll to function
function scrollTo(element, to, duration) {
if (duration <= 0) return;
var difference = to - element.scrollTop;
var perTick = difference / duration * 10;
setTimeout(function () {
element.scrollTop = element.scrollTop + perTick;
if (element.scrollTop == to) return;
scrollTo(element, to, duration - 10);
}, 10);
}
}
};
}]);
html code as bellow,
<div productFinderPage class="modal-body">
<div class="info" data-sticky="data-sticky">
<div class="info-inner">
<div class="lender-image">LOGO</div>
<div class="package-name"></div>
<div class="cta">
<button class="primary">Add to Favorites</button>
</div>
<nav>
<ul class="info-section">
<li>Basic Information</li>
<li>Extended Information</li>
<li>Loan Size / LVR</li>
<li>Loan Fees</li>
<li>Services</li>
</ul>
</nav>
</div>
</div>
<div class="main-details">
<div class="panel" data-name="basicInfo">
<div class="panel-header">Basic Information</div>
</div>
<div class="panel" data-name="extInfo">
<div class="panel-header">Extended Information</div>
</div>
<div class="panel" data-name="loanSize">
<div class="panel-header">Loan Size</div>
</div>
<div class="panel" data-name="loanFees">
<div class="panel-header">Loan Fees</div>
</div>
<div class="panel" data-name="services">
<div class="panel-header">Services</div>
</div>
</div>
</div>
jsfiddle is here.
If you iterate through an angular element, you get the plain document elements which need to be converted to an angular element again:
var anchors = angular.element(document.querySelectorAll("a[data-target]"));
angular.forEach(anchors, function(ele) {
var el = angular.element(ele);
el.bind("click", function(e) {
..
});
}
See this jsfiddle
Related
Javascript:
angular.element(document).ready(function() {
var Accordion = function(el, multiple) {
this.el = el || {};
this.multiple = multiple || false;
// Variables privadas
var links = this.el.find('.link');
// Evento
links.on('click', {el: this.el, multiple: this.multiple}, this.dropdown)
}
Accordion.prototype.dropdown = function(e) {
var $el = e.data.el;
$this = $(this),
$next = $this.next();
$next.slideToggle();
$this.parent().toggleClass('open');
if (!e.data.multiple) {
$el.find('.submenu').not($next).slideUp().parent().removeClass('open');
};
}
var accordion = new Accordion($('#accordion'), false);
$scope.$apply();
});
HTML:
<div class="box1">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Products</h3>
</div>
<div class="panel-body">
<ul id="accordion" class="accordion" >
<li ng-repeat="(key, categoryType) in categories">
<div class="link">{{categoryType.name}}<i class="fa fa-chevron-down"></i></div>
<ul class="submenu">
<li ng-repeat="item in categoryType[categoryType.name] track by $index" ng-click="getProductDetails(item)">{{item.Name}}</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
Accordion sometimes expand sometimes wont, when I inspect the element nothing triggers no action at all, I am doing this on visualforce page.
Posting part of snippet from the entire code.
Thanks
I've tried many combinations of this code and nothing works correctlly. I've also tried scrollTop. Just look at my js code and tell me what is wrong with it.
<header>
<div class="nav" id="nav">
<div class="navRow" id="navRow">
<div class="navBrand" id="brand"><img src="img/logo-light.png" alt="Snow" height="35"></div>
<div class="navLinks">
<div class="navItem">About</div>
<div class="navItem">Contact</div>
<div class="navItem">Portfolio</div>
<div class="navItem">Blog</div>
<div class="navItem">Wordpress Theme</div>
</div>
</div>
</div>
</header>
<script>
var yPos = window.pageYOffset;
var nav = document.getElementById("nav");
if (yPos > 50 || document.body.pageYOffset > 50) {
nav.style.backgroundColor = "white";
}
else {
nav.style.backgroundColor = "none";
}
</script>
Your code runs only once when page loads. I suppose you want it to run on every scroll event:
window.addEventListener('scroll', function(e) {
// ... your code here
})
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!
There is an i button in the middle of my website. I'd ask you to click it—you would see a button—contact.
When the user clicks on it, I want the content of the div above to be changed.
This is the code:
<section id="about" class="wrapper about accelerate hide">
<div class="cell accelerate">
<div class="cables center accelerate">
<div class="panel accelerate">
<header>
<h1>gog<em>sem</em>cel</h1>
</header>
<p><strong>gogsemcel </strong>is a trademark of <i font-family="Trebuchet MS">Company</i>.</p>
<p>This project is a collaboration between<br>Company name & gogsemcels.</p>
<ul class="links">
<li><a class="download" href="info/info.html">More Info</a></li>
<li><a class="github" target="_blank" href="contact.html">Contact</a></li>
</ul>
</div>
</div>
</div>
</section>
The button's class is github.
Any suggestions?
Gigantic thanks.
I see you have jQuery on your page so you could use this:
$('#about a.github').on('click', function(e){
e.preventDefault();
var content = $(this).closest('.panel').find('p');
content[0].innerHTML = 'This is a new text!'
content[1].innerHTML = 'This is the second line!'
});
Example
I am not a fan of disabling right-click. Just FYI I can see the whole content anyway...
If you want to do it with vanilla JS you can use this (credits do Chris's nice function):
function collectionHas(a, b) { //helper function (see below)
for (var i = 0, len = a.length; i < len; i++) {
if (a[i] == b) return true;
}
return false;
}
function findParentBySelector(elm, selector) {
var all = document.querySelectorAll(selector);
var cur = elm.parentNode;
while (cur && !collectionHas(all, cur)) { //keep going up until you find a match
cur = cur.parentNode; //go up
}
return cur; //will return null if not found
}
var git = document.querySelector('#about a.github');
git.addEventListener('click', function (e) {
e.preventDefault();
var content = findParentBySelector(git, '.panel').querySelectorAll('p');
content[0].innerHTML = 'This is a new text!'
content[1].innerHTML = 'This is the second line!'
});
Example
You should add href attribute to Contact link.
<a class="github" target="_blank" href="#contact">Contact</a>
Then, add id attribute to 2 p elements for easily selecting.
<section id="about" class="wrapper about accelerate hide">
<div class="cell accelerate">
<div class="cables center accelerate">
<div class="panel accelerate">
<header>
<h1>viva<em>stem</em>cell</h1>
</header>
<p id="abc"><strong>vivastemcell </strong>is a trademark of <i font-family="Trebuchet MS">Tsovn Tsirani Company</i>.</p>
<p id="def">This project is a collaboration between<br>Tsovn Tsirani & vivastemcells.</p>
<ul class="links">
<li><a class="download" href="info/info.html">More Info</a></li>
<li><a class="github" target="_blank" href="contact.html">Contact</a></li>
</ul>
</div>
</div>
</div>
</section>
Now, in onload event of your page, add following code. This use pure Javascript that you want.
// You can use document.querySelector -> returns the first element found.
var gh = document.querySelectorAll('#about .github')[0];
if (gh) {
gh.addEventListener('click', function (e) {
e.preventDefault();
document.getElementById('abc').textContent = new Date().getTime();
document.getElementById('def').textContent = new Date().getTime();
})
}
I am making a slideshow for a website i am making.
but my slideshow keeps getting error
Cannot set property 'className' of null
here is my code:
window.onload=function(){
var slideshow = document.getElementsByClassName('slideshow').item(0),
train = slideshow.getElementsByClassName('train').item(0),
lists = document.getElementsByClassName('btns').item(0).getElementsByClassName('btn'),
currentSlide = 0;
(go2slide = function (n) {
if(n>lists.length-1) n=0;
if(n<0) n=lists.length-1;
train.style.left=(-310*n)+'px';
lists.item(currentSlide).className = '';
lists.item(n).className = 'active';
currentSlide=n;
})(0); // set active of first li
nextSlide = function(){
go2slide(currentSlide+1);
}
prvSlide = function(){
go2slide(currentSlide-1);
}
var autoPlayIv = false;
(autoPlayStart = slideshow.onmouseout = function(){
if(autoPlayIv) return;
autoPlayIv = setInterval(nextSlide, 2000);
})(); // run auto play
autoPlayStop = slideshow.onmouseover = function(){
clearInterval(autoPlayIv);
autoPlayIv = false;
}
slideshow.getElementsByClassName('next').item(0).onclick=nextSlide;
slideshow.getElementsByClassName('previous').item(0).onclick=prvSlide;
for (var i=0; i<lists.length; i++) {
(function(j){
lists.item(j).onclick=function(){
go2slide(j);
}
})(i);
}
}
i DO have a li tag classes as btn and a btns ul.
its item(0).
and here is the html related to it
<div class="body">
<div class="slide">
<div class="s1">
<div class="slideshow">
<div class="train">
<script type="text/javascript">
var slidesLen = 3;
for(var i=1;i<=slidesLen;i++){
document.write("<div style=\"background-image:url('../images/pic"+i+".jpg');\"></div>");
}
</script>
</div>
<div class="previous"></div>
<div class="next"></div></div>
<ul class="btns">
<i class="btn"></i>
<i class="btn"></i>
<i class="btn"></i>
</ul>
</div>
<div class="s2"></div>
<div class="s3"></div>
<div class="s4"></div>
<div class="s5">
<div class="I"></div>
<div class="II"></div>
<div class="III"></div>
</div>
</div>
<div class="text"></div>
</div>
and of course its only the body.php i am posting here. I don't think header.php which contains the menu and the css and js association tags are needed. tell me if it is