hello im trying to make something like github treeslider
im new to javascript..
but heres what im working on
jQuery(document).ready(function(){
$('#red-side-menu a').pjax({
container: '#ajax-users-v1',
});
var toggle;
if (typeof toggle != 'undefined') {
toggle = true;
}
if (toggle) {
$('body')
.bind('start.pjax', function() { $('#ajax-users-v1').show("slide", { direction: "right" }); })
.bind('end.pjax', function() { })
toggle = false;
};
if (!toggle) {
$('body')
.bind('start.pjax', function() { $('#ajax-users-v1').show("slide", { direction: "left" }); })
.bind('end.pjax', function() { })
toggle = true;
}
$('#red-edit-full a').pjax({
container: '#ajax-users-v1',
});
});
well before above im useing php to get $_GET['infolder'] but it seems its not that good.
the problem now that it keeps slide to left
is there a way to do this?
I think this can be simplified.
# this variable maintains state for the lifetime of the page
var direction = "right";
jQuery(document).ready(function(){
# this whole statement only executes once
$('#red-side-menu a').pjax({
container: '#ajax-users-v1'
});
# this line executes once
$('body')
# this line executes once
.bind('start.pjax', function() {
# this line executes every time the start.pjax event reaches the body element
$('#ajax-users-v1').show("slide", { direction: direction });
})
# this line executes once
.bind('end.pjax', function() {
# this line executes every time the end.pjax event reaches the body element (hint: this event is raised after start.pjax is finished)
direction = (direction == "right" ? "left" : "right");
});
# this whole statement only executes once
$('#red-edit-full a').pjax({
container: '#ajax-users-v1'
});
});
The document ready event automatically runs only once. I have commented the code to show when each line or statement block is executed. It's really important to understand that the code inside the event handlers is the only code that is going to run after the page is finished loading.
Simply give a value to x outside the function
var x = true;
jQuery(document).ready(function(){ ...
What is happening here is that you declare var x without giving it a value. It is thus undefined, so typeof x != 'undefined' is false, so you don't end up setting x to true.
(What does x denote, by the way? Please name your variables something a human can understand...)
Then, since undefined is "falsy", the code inside if (!x) gets executed. $('body') gets bound those events, and x gets set to true.
Then the function you passed to jQuery(document).ready ends, and x goes out of scope, never to be seen again or used by anyone. So its existence was pretty pointless; you could have commented out all code except for that before var x, inside if (!x), and $('#red-edit-full a').pjax...
Related
I want to automate clicking the agree button to Google's cookie policies.
(I clean cookies after closing a tab, and I don't want to create a google account, so I get asked every time I use google)
There is a div element with the ID "introAgreeButton" that I'm trying to access with my script:
<div role="button" id="introAgreeButton" [...]></div>
However, document.getElementById('introAgreeButton') always returns null.
My first thought was that the element wasn't loaded by the time my function was executed. But it doesn't work if I execute it on window.onload, or even if I run it in a loop until the element is definitely there:
window.onload = function() {
var x = document.getElementById('introAgreeButton')
console.log(x)
}
Output:
null
function loop() {
var x = document.getElementById('introAgreeButton')
if (x) {
console.log('success')
} else {
loop()
}
}
Output:
null
null
null
...
Can be tested on https://www.google.com/search?hl=en&q=test
Anyone have an idea why this is and how to solve it?
Edit: I execute the script via the browser extension TamperMonkey
You can use setInterval to check if element is rendered in DOM like this :
document.addEventListener('DOMContentLoaded', function () {
var intervalID = null;
function checkElementInDOM () {
var element = document.getElementById('introAgreeButton');
if (element) {
clearInterval(intervalID);
// DO YOUR STUFF HERE ...
}
}
intervalID = setInterval(checkElementInDOM, 100);
});
To be used intelligently, however, so as not to have a setInterval which works continuously. Maybe think about adding a maximum number of attempts.
Here's the problem. I'm making a callback to the server that receives an MVC partial page. It's been working great, it calls the success function and all that. However, I'm calling a function after which iterates through specific elements:
$(".tool-fields.in div.collapse, .common-fields div.collapse").each(...)
Inside this, I'm checking for a specific attribute (custom one using data-) which is also working great; however; the iterator never finishes. No error messages are given, the program doesn't hold up. It just quits.
Here's the function with the iterator
function HideShow() {
$(".tool-fields.in div.collapse, .common-fields div.collapse").each(function () {
if (IsDataYesNoHide(this)) {
$(this).collapse("show");
}
else
$(this).collapse("hide");
});
alert("test");
}
Here's the function called in that, "IsDataYesNoHide":
function IsDataYesNoHide(element) {
var $element = $(element);
var datayesnohide = $element.attr("data-yes-no-hide");
if (datayesnohide !== undefined) {
var array = datayesnohide.split(";");
var returnAnswer = true;
for (var i in array) {
var answer = array[i].split("=")[1];
returnAnswer = returnAnswer && (answer.toLowerCase() === "true");
}
return returnAnswer;
}
else {
return false;
}
}
This is the way the attribute appears
data-yes-no-hide="pKanban_Val=true;pTwoBoxSystem_Val=true;"
EDIT: Per request, here is the jquery $.post
$.post(path + conPath + '/GrabDetails', $.param({ data: dataArr }, true), function (data) {
ToggleLoader(false); //Page load finished so the spinner should stop
if (data !== "") { //if we got anything back of if there wasn't a ghost record
$container.find(".container").first().append(data); //add the content
var $changes = $("#Changes"); //grab the changes
var $details = $("#details"); //grab the current
SplitPage($container, $details, $changes); //Just CSS changes
MoveApproveReject($changes); //Moves buttons to the left of the screen
MarkAsDifferent($changes, $details) //Adds the data- attribute and colors differences
}
else {
$(".Details .modal-content").removeClass("extra-wide"); //Normal page
$(".Details input[type=radio]").each(function () {
CheckOptionalFields(this);
});
}
HideShow(); //Hide or show fields by business logic
});
For a while, I thought the jquery collapse was breaking, but putting the simple alert('test') showed me what was happening. It just was never finishing.
Are there specific lengths of time a callback function can be called from a jquery postback? I'm loading everything in modal views which would indicate "oh maybe jquery is included twice", but I've already had that problem for other things and have made sure that it only ever includes once. As in the include is only once in the entire app and the layout is only applied to the main page.
I'm open to any possibilities.
Thanks!
~Brandon
Found the problem. I had a variable that was sometimes being set as undefined cause it to silently crash. I have no idea why there was no error message.
I have a setinterval that runes every 5 seconds. this works fine on page load.
I have the following scenarios:
Load page with interval (WORKS)
press button and load new content and stopp interval(WORKS)
Once the new content is no longer desiered, dissmiss it, return to first content and start interval again(DOES NOT WORK)
I have saftys suchs as events for window.blur that also stops the interval so that the browser does not commponsate for all the missing intervals if i would change tabs or something. Keep in mind that step 3 did not work BUT if i would after step 3 change a tab and then return to my original page(execute blur) the interval would start working again.
NOTE all content loading here exept page load is done with ajax calls.
My code:
initializing:
$.automation.worker.bindIntervalEvent("#TanksContent", "/Tank/GetTanks", function() {
$.automation.tanks.tableInit();
});
binding function:
bindIntervalEvent: function (target, url, callback) {
$(window)
.on("focus.mine",
function() {
$.automation.worker.setUpdateInterval(target, url, callback);
})
.on("blur",
function() {
$.automation.worker.stopUpdateInterval();
}).trigger("focus.mine");
}
interval function:
setUpdateInterval: function (target, url, callback) {
if ($.automation.globals.globalInterval.value.length === 0) {
$.automation.globals.globalInterval.value.push(window.setInterval(
function () {
var options = {
loadTarget: target
}
$.automation.worker.getView(url,
function() {
if (callback)
callback();
},
options);
},
5000));
}
}
the function that stops the interval:
stopUpdateInterval: function () {
if ($.automation.globals.globalInterval.value.length === 0)
return;
console.log("deleting");
for (var i = 0; i <= $.automation.globals.globalInterval.value.length; i++) {
window.clearInterval($.automation.globals.globalInterval.value[i])
$.automation.globals.globalInterval.value.splice(i, 1);
console.log($.automation.globals.globalInterval.value.length);
}
}
when stopping the interval i also remove the window bindings:
unBindIntervalEvent: function() {
$(window).off("focus.mine");
$(window).unbind("blur");
}
Back to step 3:
My sucess method in the callback to my getviewfunction is identical to what i execute in the beginning
code:
$(".updatelatest")
.on("click",
function () {
var _this = $(this);
var options = {
loadTarget:"#TanksContent"
}
$.automation.worker.getView("/Tank/GetTanks",
function (data) {
$(_this).switchClass("col-md-5", "col-md-1", 1000, function() {
$(_this).addClass("hidden");
$(".search").switchClass("col-md-5", "col-md-12", 1000, "easeInOutQuad");
})
$.automation.tanks.tableInit();
$.automation.worker.bindIntervalEvent("#TanksContent", "/Tank/GetTanks", function () {
$.automation.tanks.tableInit();
});
$(window).trigger("blur");
}, options);
});
but this does not start the interval. it is clearly initialized since it works when window.blur is executed for example when I change tab but for some reason this is not working beyond that.
i tried triggering the windows blur event and nothing happened, i tried triggering my custom window event "focuse.mine" but nothing happens.
I did not notice this while developing since I had firebug open and every time i checked scripts or css or the console the blur function was executed so I assumed that my code worked as intended but now that it is deployed I notice this.
My head is pounding beyond reason and I can't for figure out where I have gone wrong.
Well this was a fun one. I simply found that when calling the setUpdateInterval(); function directly it gave me the desiered result.
I realized that the reason I had them split like I did was becaouse of the blur event. "Focus.mine" is triggered to start the inteval again ocne a user comes back to the page.
I have a plugin that tells me if an element is visible in the viewport with $('#element').visible() (set to true when visible).
Now I want to create a function that I scroll down a page and load new content with ajax. I have this so far:
window.onscroll = function() {
console.log($('#ele').visible());
if ($('#ele').visible()) {
//ajax call comes here
}
};
As soon as I see the element my log shows true:
I don't have problems implementing the ajax-request now, but shouldn't I block this function to occur only once? How could I prevent that a new element that already has been loaded to load again (prevent using ajax again)?
I thought of using a boolean-variable, but my problem is that I don't know how to implement that because if I set a variable, how would the browser know it's value? Because on every move of my mousewheel it cant remember what that variable's value was?
EDIT:
I tried the code of Ismail and it never reaches the ajax call (alert won't show).
window.onscroll = function() {
var ajaxExecuted = false;
var ele = $('#load_more').visible();
console.log(ele);
return function() {
if (ajaxExecuted) return;
if (ele) {
alert("OK");
var ajaxArray;
ajaxArray = { page: 2 }
ajaxLoadContent(ajaxArray, "load_more", "ajax_load");
ajaxExecuted = true;
}
}
};
You can use this:
window.onscroll = (function() {
var ajaxExecuted = false;
return function() {
if(ajaxExecuted) return;
if ($('#ele').visible()) {
$.ajax({...}).success(function() {
//Your code here;
ajaxExecuted = true;
});
}
}
})();
One easy solution: set a boolean to true when the element first becomes visible and set it to false when it stops being visible. Only fire the request if those states mismatch (i.e. if it's visible but the boolean is false - that means it's the first time you've seen the window. You'd then set the bool afterwards so it won't fire off anymore until it disappears and reappears again).
So, this might be a bit confusing. A while back when Chromium decided to kill their modal support, our place found a library that seemed to work great (and yes, they want it parsed out between webkit/non-webkit [basically we have two versions of this thing running in either Firefox or Chrome])
function AddToConfig(){
....
....
....
if(/ipad|android|webkit/i.test(navigator.userAgent)){
$.showModalDialog({
url: "get_required.php?maxSelect="+max+"&forceReload="+Math.random(),
dialogArguments: window,
height: 270,
width: 510,
position: 'top',
onClose: function(){ numReq = this.returnValue; return retAction(numReq); }
});
}else{
numReq = window.showModalDialog ("get_required.php?maxSelect="+max+"&forceReload="+Math.random(), window, "dialogHeight:250px; dialogWidth:500px; center:yes; help:no; resizable:no; scroll:no; status:no; edge:raised");
return numReq;
}
(Lifted/more info here)
http://extremedev.blogspot.com/2011/03/windowshowmodaldialog-cross-browser-new.html
For a while, it worked fine. All the code replacement thus far has been situations where user clicks button, popup (now modal) happens, it does its thing and returns a value that 99% of the time requires a iFrame or something to be refreshed, so timing wasn't a issue. Great, awesome.
The situation I'm in right now, this modal call is in the middle of a bunch of other calculations. It fires if it reaches down this chain of ifthens. However, the code above seems to be making it a issue. I've tried doing callbacks like below (and maybe I'm just writing them wrong) and that hasn't worked. Hell, the comments in that URL above say doing this is a little tricky. Here's kinda (what I hope) is enough.
So, I want to hit AddToConfig(), ClearSelections(), printText() which seems simple in and of itself, but the GetRequired asynch-y call is throwing everything off.
Main code in question (Original):
//What kicks it off
<input type=button class="button3" id=btnAdd onClick='AddToConfig()' value='Add' onMouseDown="this.className='button3down'" onMouseUp="this.className='button3over'" onMouseOver="this.className='button3over'" onMouseOut="this.className='button3'">
function AddToConfig(){
....
...
if (meowmeowmeowmeow)
{
....
}
else
{
//Modal - NEEDS TO PAUSE
var requiredCount = GetRequired(arrConfigSet[--lenS][2]);
//Modal - NEEDS TO PAUSE
arrConfigSet[lenS][1] = requiredCount;
arrConfigSet[lenS][2]++;
}
arrConfigItem[lenI] = new Array ();
...
...
ClearSelections();
}
function GetRequired(max)
{
//This is modal and dumb and makes me cry
var numReq = '';
if(/ipad|android|webkit/i.test(navigator.userAgent)){
$.showModalDialog({
url: "get_required.php?maxSelect="+max+"&forceReload="+Math.random(),
dialogArguments: window,
height: 270,
width: 510,
position: 'top',
onClose: function(){ numReq = this.returnValue; return numReq; }
});
}else{
//This is fine, because it pops up a new window.
numReq = window.showModalDialog ("get_required.php?maxSelect="+max+"&forceReload="+Math.random(), window, "dialogHeight:250px; dialogWidth:500px; center:yes; help:no; resizable:no; scroll:no; status:no; edge:raised");
return numReq;
}
}
function ClearSelections(){
//various UI resetting of values
printText();
}
Main code in question (My callback version):
<input type=button class="button3" id=btnAdd onClick='AddToConfig(function(){ClearSelections();})' value='Add' onMouseDown="this.className='button3down'" onMouseUp="this.className='button3over'" onMouseOver="this.className='button3over'" onMouseOut="this.className='button3'">
if (meowmeowmeowmeow)
{
....
}
else
{
var requiredCount = GetRequired(arrConfigSet[--lenS][2]);
//So, here's my problem, that line above works fine with Firefox/non webkit because
//Popup windows make things work fine and great. With this modal thing we found
//on the internet (in getRequired()) this line of code keeps going and runs stuff below
// the line and keeps going. I need this to
//stop here. I've tried to do something like put that requiredCount in a while loop, but
//then it says Uncaught TypeError: Cannot read property '2' of undefined on that var requiredCount.
//For the record, this is all done from a onClick event on a button if it makes a difference.
//
//
//alert('test:' + arrConfigSet[--lenS][2]); //Returns a value!
// var requiredCount;
// while(typeof variable_here === 'undefined'){
// requiredCount = GetRequired(arrConfigSet[--lenS][2]);
// }
//This keeps running when in Webkit, I need that requiredCount to be set and finalized with
//the modal window gone before this continues.
arrConfigSet[lenS][1] = requiredCount;
arrConfigSet[lenS][2]++;
}
arrConfigItem[lenI] = new Array ();
...
...
callback();
}
function GetRequired(max)
{
//This is modal and dumb and makes me cry
var numReq = '';
if(/ipad|android|webkit/i.test(navigator.userAgent)){
$.showModalDialog({
url: "get_required.php?maxSelect="+max+"&forceReload="+Math.random(),
dialogArguments: window,
height: 270,
width: 510,
position: 'top',
onClose: function(){ numReq = this.returnValue; return numReq; }
});
}else{
//This is fine, because it pops up a new window.
numReq = window.showModalDialog ("get_required.php?maxSelect="+max+"&forceReload="+Math.random(), window, "dialogHeight:250px; dialogWidth:500px; center:yes; help:no; resizable:no; scroll:no; status:no; edge:raised");
return numReq;
}
}
function ClearSelections(){
//various UI resetting of values
printText();
}
Does anyone have any ideas on how I can get the JS to stop in its tracks until the script gets that return value? It gets it fine, but by the time it does, the rest of the code after it ran.
Note, we're running jQuery 1.4, so promise() is out of the question and I'm not in any position to push for anything newer. The code is kinda a rat's nest as it.
You can implement your own simple deferred library, or simply pass in a function that get's called when everything is complete. Simple example:
var whenDone = function(res) { alert('I\'m Done: ' + res); };
doComplexTask(whenDone);
And the doComplexTask:
function doComplexTask(completeFn) {
//Do some crazy work here that takes a long time (Or is asynchronous)
var res = crazyWork();
completeFn(res);
}
A simple jfiddle can be found here.