Variables not available in closure - javascript

I'm having trouble assigning some variables as within a closure scope of a javascript class/jQuery plugin.
When I move into Article.initObj() as in the constructor of the Article class, I can't see either domElement or settings in my closure scope, but I can see me and testVar. This is confusing me quite a lot. Can anyone shed some light on what be might going on here?
EDIT: I've tried this in both firefox and chrome.
Here's my HTML:
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script type="text/javascript" src="ArticleNav.js"></script>
<script type="text/javascript">
$(document).ready(function() {
// Init our Viomedia article graph
var articleList = $("#entityList").children().ArticleNav();
});
</script>
</head>
<body>
<div id="leftPanel" class="vpanel">
<div id="#search">
<label for="searchField">Search </label>
<input style="float: right;" name="searchField" id="searchField"/>
</div>
<div id="tree">
</div>
</div>
<div id="rightPanel" class="vpanel">
<div id="entityList" >
<div class="article program" id="1">
<div class="title">The Simpsons</div>
<div class="article playlist" id="2">
<div class="title">Classic Episodes</div>
<div class="article episode" id="6">
<div class="title">Homer the Heretic</div>
</div>
</div>
<div class="article season" id="3">
<div class="title">Season 4</div>
<div class="article episode" id="4">
<div class="title">Kamp Krusty</div>
</div>
<div class="article episode" id="5">
<div class="title">A Streetcar Named Marge</div>
</div>
<div class="article episode" id="6">
<div class="title">Homer the Heretic</div>
</div>
<div class="article episode" id="7">
<div class="title">Lisa the Beauty Queen</div>
</div>
</div>
</div>
<div class="artist article" id="7">
<div class="title">Electric Light Orchestra</div>
<div class="article album" id="8">
<div class="title">The Essential Electric Light Orchestra</div>
<div class="article album" id="9">
<div class="title">Disc 1</div>
<div class="article track" id="10">
<div class="title">So Serious</div>
</div>
</div>
<div class="article album" id="11">
<div class="title">Disc 2</div>
<div class="article track" id="12">
<div class="title">Last Train to London</div>
</div>
</div>
</div>
</div>
<div class="program article" id="13">
<div class="title">Archer</div>
</div>
</div>
</div>
</body>
</html>
Here's my jQuery plugin:
(function($){
var Article = function (element, options)
{
var me = this;
var testVar = "I can read this";
var domElement = $(element);
var settings = $.extend({}, options || {});
this.initObj = function()
{
me.test();
};
this.test = function()
{
console.log(testVar);
};
this.initObj();
};
var construct = function(element) {
var element = $(element);
// If this element already has this plugin attached to it.
if(element.data('Article')) {
return;
}
var ArticlePlugin = new Article(element);
element.data('Article', ArticlePlugin);
};
$.fn.ArticleNav = function(func) {
return this.each(function()
{
switch (func) {
default:
construct(this);
break;
}
});
};
}( jQuery ));

domElement is available from .initObj() from the parent closure scope. Did you actually try to use it or did you just not see it in the debugger?
If you are stepping through initObj() in the debugger, you won't see domElement as a local variable in the debugger because it is in a higher scope, but if you do an explicit watch on it, you will be able to see it. If you write code in initObj() that references it, it will work.
Same for settings.

Related

Reset Image Gallery Count When Loading New Article Content

I have a lots of articles that have 1, 2, 3 or 4 pictures. On mobile I created a carousel. All images all on the same line and I have a count that is 0. And when I press on the right button(for example) that count it will be -100 and all images will have a left: -100 and so on. The problem is that, let's say, I press on the button from one article that count will be -100. but after I go to another article and if I press again the count is not -100 and is -200. How can I reset that count when I change the article. The code is something like:
var c = 0;
$('.plus').on('click', function(){
c += 100
$(this).siblings('.num').text(c)
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="article">
<div class="minus">Minu</div>
<div class="plus">Plus
</div><div class="num">0</div>
</div>
<div class="article">
<div class="minus">Minu2</div>
<div class="plus">Plus2
</div><div class="num">0</div>
</div>
<div class="article">
<div class="minus">Minu3</div>
<div class="plus">Plus3
</div><div class="num">0</div>
</div>
<div class="article">
<div class="minus">Minu4</div>
<div class="plus">Plus4
</div><div class="num">0</div>
</div>
<div class="article">
<div class="minus">Minu5</div>
<div class="plus">Plus5
</div><div class="num">0</div>
</div>
Here's what I cooked up for you.
$('.plus').on('click', function(){
c = Number($(this).siblings('.num').text()) + 100;
$(this).siblings('.num').text(c)
});
$('.minus').on('click', function(){
c = Number($(this).siblings('.num').text()) - 100;
$(this).siblings('.num').text(c)
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="article">
<div class="minus">Minu</div>
<div class="plus">Plus</div>
<div class="num">0</div>
</div>
<div class="article">
<div class="minus">Minu2</div>
<div class="plus">Plus2</div>
<div class="num">0</div>
</div>
<div class="article">
<div class="minus">Minu3</div>
<div class="plus">Plus3</div>
<div class="num">0</div>
</div>
<div class="article">
<div class="minus">Minu4</div>
<div class="plus">Plus4</div>
<div class="num">0</div>
</div>
<div class="article">
<div class="minus">Minu5</div>
<div class="plus">Plus5</div>
<div class="num">0</div>
</div>
The Plus button will add to the total displayed for the current article and Minus will subtract from it. Every article has it's own c value that can't be changed by a button from a different article.
I hope that's what you are looking for.
Add an on('click', function() {...}) handler to your "change the article" button. If this button is just another article's text, then give them all a common class and a common class onclick handler.
HTML...
<span class="article">Article 1</span>
<span class="article">Article 2</span>
<span class="article">Article 3</span>
jQuery...
$('.article').on('click', function() {
c = 0;
});

Replace Onclick prameters with a part of img src path

Hi I am new to the world of Greasemonkey and JavaScript..
I want to replace every onclick function with a part of its related img src link
the source looks like this:
<div id="playlist_container">
<div id="video_container" onclick="playvid('a1a1a1a1a1',3201)" class="playing">
<div id="thumbnail">
<img src="https://.../thumb/ABCD.jpg">
</div>
<div id="title"></div>
<div id="synopsis">
Vid 1 </div>
</div>
<hr>
<div id="video_container" onclick="playvid('b2b2b2b2bb2',3202)" >
<div id="thumbnail">
<img src="https://.../thumb/EFGH.jpg">
</div>
<div id="title"></div>
<div id="synopsis">
Vid 2 </div>
</div>
i want to replace the onclick 'playvid' a1a1a1a1a1 & b2b2b2b2bb2 & c3c3c3c3c3c3 ... with part of img src link
to become like this:
<div id="playlist_container">
<div id="video_container" onclick="playvid('ABCD',3201)" class="playing">
<div id="thumbnail">
<img src="https://.../thumb/ABCD.jpg">
</div>
<div id="title"></div>
<div id="synopsis">
Vid 1 </div>
</div>
<hr>
<div id="video_container" onclick="playvid('EFGH',3202)" >
<div id="thumbnail">
<img src="https://.../thumb/EFGH.jpg">
</div>
<div id="title"></div>
<div id="synopsis">
Vid 2 </div>
</div>
Here's what i've tried so far:
var els = $("#playlist_container");
var cod = $("div#thumbnail img").prop("src").replace(/(https(.+)\/thumb\/|.jpg)/gi, '');
for(var i=0;i<els.length;i++){
var el = els[i];
el.innerHTML = el.innerHTML.replace(/playvid(.)(.)(\w+)(.)/gi, "playvideo('" + cod +"'");
}
this works for me but the issue is that it puts the first cod 'ABCD' to all the following 'playvid()' functions as shown below:
<div id="playlist_container">
<div id="video_container" onclick="playvid('ABCD',3201)" class="playing">
<div id="thumbnail">
<img src="https://.../thumb/ABCD.jpg">
</div>
<div id="title"></div>
<div id="synopsis">
Vid 1 </div>
</div>
<hr>
<div id="video_container" onclick="playvid('ABCD',3202)" >
<div id="thumbnail">
<img src="https://.../thumb/EFGH.jpg">
</div>
<div id="title"></div>
<div id="synopsis">
Vid 2 </div>
</div>
another issue is when i try $("#video_container") it doesnt work i dont know why, I'm very confused and can't find anything on it
Your html has duplicate ID values which can cause issues when finding the correct element. Try using class if you want to target multiple elements.
This code only gets the first element value
var cod = $("div#thumbnail img").prop("src").replace(/(https(.+)\/thumb\/|.jpg)/gi, '');
Try this code and let me know how it goes
var images = $("div.thumbnail img");
images.each(function(img) {
var name = $(this).prop("src").replace(/(https(.+)\/thumb\/|.jpg)/gi, '');
var container = this.closest("div.video_container");
var evt = $(container).attr("onclick").replace(/playvid(.)(.)(\w+)(.)/gi, "playvideo('" + name +"'");
$(container).attr("onclick", evt);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="playlist_container">
<div class="video_container" onclick="playvid('a1a1a1a1a1',3201)" class="playing">
<div class="thumbnail">
<img src="https://.../thumb/ABCD.jpg">
</div>
<div class="title"></div>
<div class="synopsis">Vid 1</div>
</div>
<hr>
<div class="video_container" onclick="playvid('b2b2b2b2bb2',3202)" >
<div class="thumbnail">
<img src="https://.../thumb/EFGH.jpg">
</div>
<div class="title"></div>
<div class="synopsis">Vid 2</div>
</div>

Cannot get element inside distant parent div using jQuery

In a dom which has many of the blocks like the one below, I'd like to get name of pid element (i.d 123) when link is clicked:
<div class="a-post">
<a class="pid" name="123"></a>
<div class="row">
<p>Some text</p>
</div>
<br>
<div class="row">
<div class="col-xs-12">
<p>Othe text </p>
</div>
<br>
<div class="row">
<div class="col-xs-1">
<img class="link" src="link.svg">
</div>
</div>
</div>
</div>
Here is my jQuery:
$(document).ready(function () {
$(".link").click(function () {
let pid = $(this).parent(".a-post").find(".pid").attr('name');
console.log('pid is:', pid);
}
});
But I get pid is: undefined
How can I fix this?
You have to use .closest() and not .parent(), because .parent() only goes 1 step up. .closest() will continue until it reach the top or finds the element.
$(document).ready(function() {
$(".link").click(function() {
let pid = $(this).closest(".a-post").find(".pid").attr('name');
console.log('pid is:', pid);
})
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="a-post">
<a class="pid" name="123"></a>
<div class="row">
<p>Some text</p>
</div>
<br>
<div class="row">
<div class="col-xs-12">
<p>Othe text </p>
</div>
<br>
<div class="row">
<div class="col-xs-1">
<img class="link" src="link.svg">
</div>
</div>
</div>
</div>

How to get the id of each first element of a nexted div in JQuery

here is my HTML code
<div id="parent">
<div id="computer">
<div id="items">
<div id="1">hp</div>
<div id="2">compaq</div>
<div id="3">toshiba</div>
</div>
</div>
<div id="laptop">
<div id="1">i5</div>
<div id="2">dual core</div>
<div id="3">i3</div>
</div>
<div id="printer">
<div id="laser">hp laser</div>
</div>
<div id="cpu">
<div id="item">
<div id="1">pintuim</div>
<div id="2">celeron</div>
</div>
</div>
<div id="scanner">
<div id="canon">
<div>canon</div>
</div>
</div>
</div>`
I am trying to get the id of each first element of the parent div
that is to get an
array=[computer, laptop, printer, cpu, scanner]
here is my jquery code but it's taking everything.
var a = $("div.content :nth-child(1)")find("*").toArray();
please I need some help thanks
there is a selector in jQuery which will return the first level of children: DEMO
var a=[];
$("#parent > div").each(function(){ // using > will return the first level of children
a.push($(this).attr('id'));
});
alert(a);
Those are children of the #parent element so you can iterate over that and create an array out of it using .map()
var array = $('#parent').children().map(function() {
return this.id;
}).get();
snippet.log(array)
<!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div id="parent">
<div id="computer">
<div id="items">
<div id="1">hp</div>
<div id="2">compaq</div>
<div id="3">toshiba</div>
</div>
</div>
<div id="laptop">
<div id="1">i5</div>
<div id="2">dual core</div>
<div id="3">i3</div>
</div>
<div id="printer">
<div id="laser">hp laser</div>
</div>
<div id="cpu">
<div id="item">
<div id="1">pintuim</div>
<div id="2">celeron</div>
</div>
</div>
<div id="scanner">
<div id="canon">
<div>canon</div>
</div>
</div>
</div>

How to show hidden content according to clicked value jquery?

sorry for the midunderstanding. I meant index, not value. Sorry.
I am wondering if there is a way to use the value of the shown content ".wbox" of this jsfiddle example to coincide with the hidden value, that when clicked will show the hidden content?
For example, When Cont 1 is clicked, hidden box 1 shows. When Cont2 is clicked, hidden box 2 shows... and so forth.
Here is my fiddle: http://jsfiddle.net/kqbLtn8b/1/
HTML:
<div class="box">
<div class="content one">
<h1>Cont 1</h1>
</div>
<div class="content two">
<h1>Cont 2</h1>
</div>
<div class="content three">
<h1>Cont 3</h1>
</div>
</div>
<div class="hidden-content">
<div class="hidden-box b-one">one</div>
<div class="hidden-box b-two">two</div>
<div class="hidden-box b-three">three</div>
</div>
jquery:
var boxVal = $('.box').val();
Thanks for any help!
What I am really trying to do is shorten the code from something like this:
$('.one').on('click', function(){
$('.b-one').show()
});
and so forth with the rest
Try this : use index of content div to show hidden-box
$(function(){
$('.content').click(function(){
var index = $(this).index();
$('.hidden-content .hidden-box:eq('+index+')').show();
});
});
And make change in your css, instead of hiding hidden-content div you need to hide hidden-box. So change your
.hidden-content{
display:none;
}
to
.hidden-box{
display:none;
}
Demo
If you want to stick to the current HTML you have, it is going to be cumbersome and dirty since there are 2 ways to handle that scenario.
Translate a string like "Cont 1" into "one", "Cont 2" into "two". It's all well and good till nine but what about 100 -> hundred? Or even thousand?
The other approach is instead of naming your hidden boxes as "b-one", "b-two", you can name them "b-1", "b-2", "b-3". That way you can just detect the clicked element and then wipe of the "Cont " part and then use the remainder of the string to get the hidden part's class.
Both the above cases will still give you a very very dirty code since you have to get the .html() of the clicked element and stip of h1 tags.
So my suggestion would be to follow the below method.
HTML:
<div class="box">
<div class="content one" rel="1">
<h1>Cont 1</h1>
</div>
<div class="content two" rel="2">
<h1>Cont 2</h1>
</div>
<div class="content three" rel="3">
<h1>Cont 3</h1>
</div>
</div>
<div class="hidden-content">
<div class="hidden-box b-1">one</div>
<div class="hidden-box b-2">two</div>
<div class="hidden-box b-2">three</div>
</div>
JS:
$('.content').on('click', function(){
var divNum = this.rel;
$('.b-'+divNum).show();
});
I recommend restructuring your HTML in the following way:
<div class="box">
<div class="content" id= "c1">
<h1>Cont 1</h1>
</div>
<div class="content" id= "c2">
<h1>Cont 2</h1>
</div>
<div class="content" id= "c3">
<h1>Cont 3</h1>
</div>
<div class="hidden-content">
<div class="hidden-box" id= "h1">one</div>
<div class="hidden-box" id= "h2">two</div>
<div class="hidden-box" id= "h3">three</div>
then use this as your jquery code:
$('.content').click(function(){
var num = $(this).attr('id').split("c")[1];
$("#h"+num).show();
});
and by the way, change your css too:
.hidden-content{
/* display:none;*/
}
.hidden-box{
width:35px;
height:35px;
border:1px solid black;
display:none;
}
This is another way (although not so reliable, as it would break if you change your classes):
$(function () {
$('.content').on('click', function () {
var className = $(this).attr('class').replace('content', '').trim();
$('.hidden-box').hide();
$('.b-' + className).show();
});
});
.hidden-box {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="box">
<div class="content one">
<h1>Cont 1</h1>
</div>
<div class="content two">
<h1>Cont 2</h1>
</div>
<div class="content three">
<h1>Cont 3</h1>
</div>
</div>
<div class="hidden-content">
<div class="hidden-box b-one">one</div>
<div class="hidden-box b-two">two</div>
<div class="hidden-box b-three">three</div>
</div>
UPDATE
Based on #Regent comment which I agree to, this would be a more reliable way because it will work even if you change your markup.
You just need to add a data attribute to your markup that will be used to match elements:
$(function () {
$('.content').on('click', function () {
var sel = $(this).data('rel');
$('.hidden-box').each(function () {
$(this).toggle($(this).data('rel') == sel);
});
});
});
.hidden-box {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="box">
<div class="content one" data-rel="1">
<h1>Cont 1</h1>
</div>
<div class="content two" data-rel="2">
<h1>Cont 2</h1>
</div>
<div class="content three" data-rel="3">
<h1>Cont 3</h1>
</div>
</div>
<div class="hidden-content">
<div class="hidden-box b-one" data-rel="1">one</div>
<div class="hidden-box b-two" data-rel="2">two</div>
<div class="hidden-box b-three" data-rel="3">three</div>
</div>

Categories

Resources