i've spent ages trying to understand bootstrap's navigation bar, mainly by spending 4-5 days reading stackoverflow posts
& finally i think i've found an answer that helps!!!
trouble is, i can't understand the accompanying javascript/jquery code. i'm guessing its a shorthand version of js or something but just what it means i cannot decipher
basically, its the javascript code that appears on this jsfiddle page
$('.navbar').on('show', function () {
var actives = $(this).find('.collapse.in'),
hasData;
if (actives && actives.length) {
hasData = actives.data('collapse')
if (hasData && hasData.transitioning) return
actives.collapse('hide')
hasData || actives.data('collapse', null)
}
});
so, if anyone can explain to me what the code is doing on a line by line basis it'd be really cool
the first line i understand. its the weird-ass syntax in the next 6 lines that have me mystified
var actives = $(this).find('.collapse.in'),
hasData;
This creates two variables. One with elements picked from current scope that match the selector .collapse.in, and one empty variable.
if (actives && actives.length)
If actives exists and contains more than zero elements, do the following...
hasData = actives.data('collapse')
Retrieve arbitrary data stored under the key collapse. See https://api.jquery.com/jquery.data/ for more info.
if (hasData && hasData.transitioning) return
If hasData exists and hasData.transitioning is truthy, stop function execution.
actives.collapse('hide')
Call the collapse function on actives. This is not a native jQuery function, so you'll have to look up whatever plugin it comes from to make sense of the argument being passed in.
hasData || actives.data('collapse', null)
If hasData is truthy, skip this line. Otherwise, set the arbitrary data in actives variable to null.
Related
I've created a script (my first) that accepts input text and then runs about 30 regular expressions on the text, outputting discovered values into an HTML table. The purpose is for me to be able to paste in text containing specification information for products and have them uniformly outputted so I can paste them into a spreadsheet.
I've had it working really well and I've been tuning the regexes as I've pasted data with different variations/layouts in. However, I've hit an impasse and need some assistance:
One of the regular expressions searches for the product part number (sku) and returns the value in a column. Some of the source data includes more than one match because there are regional variations to the products. In all cases the first match is the only one that I want. I've tested the RegEx on RegEx101 and it returns the first match only with the 'global' flag switched off. However, the same RegEx running in my script causes it to return console messages infinitely before crashing. It's immediately unresponsive so I can't see any error messages.
Here's a sample of the regex section in my script. sku being the one that's causing problems:
let wallMountable = /(?<wallmountable>[Ww]all [Mm]ount)/mg;
let sku = /^.*\((?<sku>\d\d\w\w[\d\w]+?).+?\).*$/m;
function parseData() {
// Execute the Regular Expressions on the text in 'specSheet'
let specSheet = document.getElementById("specSheet").value;
let wallMountableToken = wallMountable.exec(specSheet);
let skuToken = sku.exec(specSheet);
do {
// If Token isn't null, then test to see if the regex group value is undefined. If either are true, do nothing, otherwise write the value to the document.
if (wallMountableToken !== null) {
if (wallMountableToken.groups.wallmountable !== undefined)
{document.write(`${wallMountableToken.groups.wallmountable}`);}
else {}
}
else {}
if (skuToken !== null) {
if (skuToken.groups.sku !== undefined)
{document.write(`${skuToken.groups.sku}`);}
else {}
}
else {}
}
// Loop through the script until a condition is met.
while (
(wallMountableToken = wallMountable.exec(specSheet)) !== null,
(skuToken = sku.exec(specSheet)) !== null
);
}
The while loop may not be necessary and in truth I'm not entirely sure what purpose it serves here, but it seemed to consistently appear in the reference material I was studying. I have included it here because it's part of the script, but please note that the script works if I change the second regex to /mg instead of /m, however, it returns multiple values and I only want it to return the first capture.
I know there's a lot wrong with the script, but this particular question is about why the regex is causing an infinite loop, so any help toward that goal is much appreciated.
solved: requires explicit return statement for each filter. I thought the single boolean in each filter would be clear enough. by #adiga
I want to find the elements in one array (dcm) that are not found in a second array (vari). I want to match only two elements, vp (string type) and vd (date type). I've made sure there are some rows in dcm that meet the condition, but I'm getting no results.
Did I do up the code wrong? is there a better way to do this (.includes .contains .indexOf)?
var dcmm = dcm.filter(r=>{
vari.filter(rv=>{
rv[vp]+rv[vd] == r[dp]+r[dd]
}).length == 0
});
ps. sorrynotsorry to all the long variable name proponents out there. as well as the const-not-var proponents.
pps. this is google apps script not javascript, but I think the idea is the same.
Just in case, as it said #adiga you don't need return statements if you don't use {}.
Most likely this will work fine:
var dcmm = dcm.filter( r => vari.filter( rv => (rv[vp]+rv[vd] == r[dp]+r[dd]) ).length == 0 );
Basically what I'm trying to do is write a greasemonkey script so that if a link on a page is not a link I have on an ignore list to just open the link, if it is on the list then reload the page after 5 seconds here is what I tried so far
var url1 = $("span.capsulelink a:eq(0) ").attr("href");
var ignoreList = ["example1.com","example2.com"]
if (url1 !== ignoreList) {
window.open(url1);
} else {
setTimeout(function() {
location.reload();
},5000);
}
I know it's the (url1 !== ignoreList) part I am having trouble with, I just can not seem to find the right expression for that. Like I do not know how to say if url1 is not on the ignoreList {do something}.
ignoreList.indexOf(url1) !== -1
This is another way of saying "is url contained in the ignoreList array?"
This is because the indexOf() method of Array returns the index of the element you're looking for, or -1 if the element doesn't exist.
To negate this, which is what you want to do, you write:
ignoreList.indexOf(url1) === -1
(i.e. is url1 not in ignoreList?)
This is a good question, because the answer really isn't intuitive.
When you're starting to learn javascript, some of the syntax patterns begin to look familiar.
But the javascript equivalent of PHP's
if (!in_array([ARRAY]));
simply isn't obvious at all - this is one syntax you just need to know.
Here is the javascript you're looking for:
if (ignoreList.indexOf(url1) !== -1) {
[RELOAD PAGE CODE HERE]
}
else {
[OPEN THE LINK CODE HERE]
}
Here's why it works:
ignoreList.indexOf([VALUE]) looks through the ignoreList array and searches through the array's items.
If one of those items is [VALUE], it returns the index of that item.
Importantly, if none of the items are [VALUE] it returns -1.
So, in order to establish that at least one of the items is [VALUE], you have to verify that the returned index definitely isn't -1.
Consequently the condition you need to check for is:
if (ignoreList.indexOf(url1) !== -1)
Can you tell me what I am missing in writing this code?
<button onclick="getBrowserName()">You Browser Name?</button>
<script>
function getBrowserName()
{
//Uses external interface to reach out to browser and grab browser useragent info.
var browserAgent:String = ExternalInterface.call("function getBrowser(){return navigator.userAgent;}");
//Determines brand of browser using a find index. If not found indexOf returns (-1).
if(browserAgent != null && browserAgent.indexOf("Firefox")>= 0)
{
alert("Firefox");
}
else if(browserAgent != null && browserAgent.indexOf("Safari")>= 0)
{
alert("Safari");
}
else if(browserAgent != null && browserAgent.indexOf("MSIE")>= 0)
{
alert("IE");
}
else if(browserAgent != null && browserAgent.indexOf("Opera")>= 0)
{
alert("Opera");
}
else
{
alert("Undefined");
}
return 0;
}
</script>
Well, there are a few things wrong here.
var browserAgent: String: it appears that you're using actionscript syntax, but JS uses dynamic typing, so var is all you need. There's no need to explicitly define the variable's data type, and if you try to do it this way in JS, it's going to give you syntax errors.
ExternalInterface.call: this is another carryover from ActionScript: you don't need this. In fact, it won't work at all because there's no ExternalInterface class in standard JS.
Your getBrowser() function is unnecessary. You're setting browserAgent equal to the result of calling a function from an ExternalInterface, but you can do this directly: var browserAgent = window.navigator.userAgent.
When I fixed those things, it worked fine.
Next time, I would recommend checking the browser console, because, if nothing is happening, the errors that appear there will help you solve your issue nine times out of ten.
Demo
If you replace this line
var browserAgent:String = ExternalInterface.call("function getBrowser(){return navigator.userAgent;}");
with this line:
var browserAgent = window.navigator.userAgent;
Then your script works fine on my side.
However, the criteria you use to test the engine are not precise. Have a look at this:
http://www.useragentstring.com/pages/useragentstring.php
There are many browsers that will tell you Firefox even if they another brand. But they are based on each other or they use a specific engine that is built in other browsers too.
If I use your script with a Chrome browser, it says "Safari" instead of "undefined".
About the punctuation: I know of only two places in Javascript where to use the double point:
the conditional operator a = b ? c : d;
the attribute - value assignment in object notation: { name : value }
Your code line containing :String = ExternalInterface... reminds me rather on ActionScript (?).
Im not quite sure what the follow code should be doing. Are you sure its correct?
var browserAgent:String =
ExternalInterface.call("function getBrowser(){return navigator.userAgent;}");
I would expect this code to simply look like this:
var browserAgent = navigator.userAgent;
Below is a example with this change.
http://jsbin.com/lukasere/1/edit
Well my short and easy to explain explanation can be this. I have 2 arrays, FilterList and GamesReset. Whenever this function I have works and filters out some games with check boxes and a drop down menu, the function starts off with something like FilterList=GamesReset;. This functions seems to work fine until I filter out ages for the game. The function never touches GamesReset unless it's something like while(i<GamesReset.length){} or FilterList=GamesReset;. And the only tool I use when I filter games is FilterList.splice(i,1);. Now with that, GamesReset definitely, should never change as far as I know. I have it to reset FilterList, then depending on what needs to be filtered out, it will start removing those games from the FilterList. The problem I have, is that, GamesReset also becomes filtered. Which, does not make any sense at all. So like my title, it's just like saying b=0;, a=b;, a++;, and now b equals 1.
Now, I think that's the best/shortest way I can reveal this problem, without overdoing it with my bad habit of explaining things to people. I have a webpage currently available if anyone would like to see whats going on in action, because I wouldn't get what's going on with GamesReset either if I were you, here (url removed, read edit). To get the error working, just change the age to 10 without checking any boxes. The bottom paragraph is the GamesReset array (using <br> to separate each array), and it's the one that changes when I'm only changing FilterList in the JavaScript. The actual codes if you view the page source may be a little off compared to when I mentioned above, but it's pretty much 100% the same thing. I also wanted to have the codes available without a url and on this page, but I can't figure out how to do that with the html tags included.
Actually, here's the JavaScript function. I just figured out the 4 spaces thing when my question was rejected.
function SearchFilter() {
Games = GamesReset;
plat = document.getElementById('platformcheck').checked;
rpg = document.getElementById('rpgcheck').checked;
puzz = document.getElementById('puzzlecheck').checked;
hybo = document.getElementById('hybocollectcheck').checked;
ages = document.getElementById('agescheck').value;
if ((!plat) && (!rpg) && (!puzz) && (!hybo)) {
FilterList = Games;
} else {
FilterList = [];
i = 0;
while (i < Games.length) {
Set = '';
Set = Games[i];
Set = Set.split('</>');
StrFind = Set[0];
if (
(plat && (StrFind.search(',platform,') > -1)) || (rpg && (StrFind.search(',rpg,') > -1)) || (puzz && (StrFind.search(',puzzle,') > -1)) || (hybo && (StrFind.search(',hybocollect,') > -1))) {
FilterList.push(Games[i]);
}
i++;
}
// so by now, we should have the filtered array
}
//seperate filter for ages
i = 0;
while (i < FilterList.length) { //The problem should definitely start here
Set = '';
Set = FilterList[i];
Set = Set.split('</>');
StrFind = Set[1];
if ((Math.abs(StrFind)) > ages) {
FilterList.splice(i, 1);
} else {
i++;
}
}
GL.innerHTML = GamesReset.join('<br>');
}
As a reminder, the problem starts when the age filter is working. And the only thing it does is FilterList.splice(i,1);. But it ends up changing GamesReset. I changed this function a bit when I added Games=GamesReset;, but that was another test to try and make sure GamesReset doesn't get filtered like FilterList, but it still does.
EDIT: I removed my url since the answers definitely explained everything, so there's no need for it now.
Arrays are not copied when assigned, both variables will refer to the same data. Here is a post that goes into detail on this: Copying array by value in JavaScript
It makes perfect sense since variables are just references to objects in memory. One object can have several references. Consider this:
var a = { foo: 'bar' };
var b = a;
// b is now a reference to a and they both point to the same object
b.foo = 'doe';
alert( a.foo ); // alerts doe
The same goes for arrays. So when you do FilterList = GamesReset you are not copying the array - you are just assigning the same array to another variable. Any mutations or changes made to either reference will be reflected in all references.
To create a copy of an array you can use slice:
FilterList = GamesReset.slice();