2009-04-20 3 views
8

अजाक्स घटना के साथ एक पृष्ठ पर, मैं (आदि के लिये भेज डबल के साथ मुद्दों को रोकने के लिए)जावास्क्रिप्ट: पृष्ठ पर सभी कार्रवाइयों को अस्थायी रूप से अक्षम कैसे करें?

मैं वर्तमान onclick घटनाओं के लिए return false; prepending द्वारा इस की कोशिश की जब तक अजाक्स कॉल रिटर्न सभी कार्यों को निष्क्रिय करना चाहते जब "ताला" पृष्ठ, और बाद में पृष्ठ को "अनलॉक" करते समय इसे हटा रहा है। हालांकि, "अनलॉक" होने के बाद क्रियाएं सक्रिय नहीं होती हैं - आप बस उन्हें ट्रिगर नहीं कर सकते हैं।

यह क्यों काम नहीं कर रहा है? नीचे उदाहरण पृष्ठ देखें। मेरा लक्ष्य प्राप्त करने के लिए कोई अन्य विचार?

उदाहरण कोड:
दोनों लिंक और बटन एक जे एस चेतावनी दिखा रहे हैं; लॉक दबाते समय, इवेंट हैंडलर अनलॉक करें जैसा कि पहले था, लेकिन काम नहीं करता ...?!
कोड अंत में त्रिनिदाद के साथ काम करने के लिए है, लेकिन बाहर भी काम करना चाहिए।

<html><head><title>Test</title> 

<script type="text/javascript"> 
function lockPage() 
{ 
    document.body.style.cursor = 'wait'; 
    lockElements(document.getElementsByTagName("a")); 
    lockElements(document.getElementsByTagName("input")); 

    if (typeof TrPage != "undefined") 
    { 
    TrPage.getInstance().getRequestQueue().addStateChangeListener(unlockPage); 
    } 
} 

function lockElements(el) 
{ 
    for (var i=0; i<el.length; i++) 
    { 
    el[i].style.cursor = 'wait'; 
    if (el[i].onclick) 
    { 
     var newEvent = 'return false;' + el[i].onclick; 
     alert(el[i].onclick + "\n\nlock -->\n\n" + newEvent); 
     el[i].onclick = newEvent; 
    } 
    } 
} 

function unlockPage(state) 
{ 
    if (typeof TrRequestQueue == "undefined" || state == TrRequestQueue.STATE_READY) 
    { 
    //alert("unlocking for state: " + state); 
    document.body.style.cursor = 'auto'; 
    unlockElements(document.getElementsByTagName("a")); 
    unlockElements(document.getElementsByTagName("input")); 
    } 
} 

function unlockElements(el) 
{ 
    for (var i=0; i<el.length; i++) 
    { 
    el[i].style.cursor = 'auto'; 
    if (el[i].onclick && el[i].onclick.search(/^return false;/)==0) 
    { 
     var newEvent = el[i].onclick.substring(13); 
     alert(el[i].onclick + "\n\nunlock -->\n\n" + newEvent); 
     el[i].onclick = newEvent; 
    } 
    } 
} 
</script> 

<style type="text/css"> 
</style> 
</head> 

<body> 

<h1>Page lock/unlock test</h1> 

<p>Use these actions to lock or unlock active elements on the page: 
<a href="javascript:lockPage()">lock</a>, 
<a href="javascript:unlockPage()">unlock</a>.</p> 

<p>And now some elements:</p> 

<a onclick="alert('This is the action!');return false;" href="#">link action</a> &nbsp; 
<input type="button" value="button action" onclick="alert('This is another action!')"/> 
</body> 
</html> 

धन्यवाद लोग आपके विचारों और जवाब के लिए।

अब मुझे लगता है कि मैं तार और काम करता है, जो स्पष्ट रूप से काम नहीं कर सकता को मिलाया है देखते हैं; (

मैं स्पष्ट कर दिया जाना चाहिए था कि हम जो घटना से निपटने बनाने के कुछ वेब परिवार कल्याण और टैग पुस्तकालयों (त्रिनिडाड) का उपयोग (और अजाक्स) कोड, इसलिए मैं इसे सीधे संपादित नहीं कर सकता या सिंक्रोनस अजाक्स इत्यादि का उपयोग नहीं कर सकता।

इसके अलावा, अजाक्स केवल एक परिदृश्य है जहां यह कोड निष्पादित किया जाना चाहिए। इसका उद्देश्य उपयोगकर्ता को दोबारा सबमिट करने से रोकना है पेज/एक्शन, जो गैर-अजाक्स पृष्ठों के लिए भी प्रासंगिक है, जहां आप एक बटन पर डोलबे-क्लिक कर सकते हैं। मुझे पता है कि यह वास्तव में सुरक्षित नहीं है, और यह केवल नेविगेशन प्राप्त करने से बचने के लिए "सुविधा" चीज़ बनना है त्रुटि पृष्ठ अक्सर (हमारे पास सर्वर-साइड सुरक्षा है, ज़ाहिर है)।

तो, शायद div ओवरले को आजमाएगा।

धन्यवाद,
क्रिस्टोफ।

उत्तर

9

कैसे

actions_disabled = 0 

वेतन वृद्धि एक वैश्विक वर की स्थापना जब AJAX कॉल तो घटती शुरू होता है जब इसके समाप्त होने के बारे में। आपके सभी "एक्शन" हैंडलर

if (actions_disabled) return false; 

स्वयं-संशोधित कोड डीबग करने से बहुत आसान हो सकते हैं!

वैकल्पिक रूप से, अपने नियंत्रण लॉक करने के लिए आप सेट कर सकते हैं:

control.disabled="disabled" 

जो उन्हें बाहर पक्का हो जानेवाला, यह उपयोगकर्ता है कि वे जमा नहीं कर सकते करने के लिए स्पष्ट बनाने का बोनस होगा। अनलॉक करने के लिए बस सेट:

control.disabled="" 

नया विचार टिप्पणी के आधार पर (, ऐसा लगता है ... टिप्पणी में कोड उद्धृत नहीं कर सकते हैं):

तुम हमेशा सिर्फ लटका कर सकते हैं अतिरिक्त जावास्क्रिप्ट वस्तुओं बंद जिम्मेदार बताते हैं:

लॉक करने के लिए आप:

control.onclick_old = control.onclick 
control.onclick = "return false;" 

को अनलॉक करने के आप:

control.onclick = control.onclick_old 
+0

धन्यवाद, लेकिन दुर्भाग्य से त्रिनिदाद ढांचे द्वारा एक्शन कोड उत्पन्न होता है और मैं इसे सीधे बदल नहीं सकता हूं। यही कारण है कि मुझे इवेंट हैंडलर कोड बदलने के लिए जेएस का उपयोग करना होगा। – ami

+0

क्या आप क्रियाओं को "लपेट" सकते हैं: फ़ंक्शन thingo_wrap (ई) { यदि (actions_disabled) झूठी वापसी करता है; मूल_टर्न (ई) } ऊपर वैकल्पिक विकल्प भी देखें। – NickZoic

+0

अच्छा विचार ... मैं इसे सीधे नहीं कर सकता, लेकिन कार्रवाई को संशोधित करने के लिए शायद कुछ जेएस का उपयोग कर सकता हूं। मेरा मूल समाधान काम नहीं करता है, ऐसा लगता है कि मैं फ़ंक्शंस और स्ट्रिंग्स को मिश्रित कर रहा हूं, है ना? मैं इसे आज़माउंगा। वैकल्पिक रूप से, मैं शायद मूल कार्रवाई को संग्रहीत करने के लिए मानचित्र का उपयोग कर सकता हूं और बाद में इसे पुनर्स्थापित कर सकता हूं ... – ami

2

मैं एक बार एक DIV उस क्षेत्र मैं विकलांग चाहता था, पृष्ठ पर अन्य तत्वों में से किसी की तुलना में अपने z-index उच्च की स्थापना कवर बनाने, और उसके बाद अपने opacity0 को निर्धारित करके इस लक्ष्य को हासिल कर लिया। डिफ़ॉल्ट रूप से, यह DIV display: none से छिपा हुआ था, ताकि यह किसी भी चीज़ में हस्तक्षेप न करे। हालांकि, जब मैं क्षेत्र को अक्षम करना चाहता था, तो मैंने बस अपना displayblock पर सेट किया।

स्टीव

+0

उत्तर के लिए धन्यवाद, लेकिन वास्तव में यह नहीं है कि ग्राहक क्या चाहता है ... ;-( पृष्ठ को अपरिवर्तित दिखाया जाना चाहिए (सभी बटन, फ़ील्ड इत्यादि के साथ) लेकिन केवल यह रोकें कि उपयोगकर्ता एक और कार्रवाई को ट्रिगर करता है या एक ही कार्रवाई दूसरी बार। – ami

+0

यही सुझाव दिया जा रहा है। पृष्ठ में कोई दृश्यमान परिवर्तन नहीं होगा। आपको अस्पष्टता को बदलने की भी आवश्यकता नहीं है - बस div को खाली रखें और 'none' और 'block' – ozan

+0

के बीच प्रदर्शन विशेषता को टॉगल करें ओह, हाँ, मैं देखता हूं। इसे और अधिक ध्यान से पढ़ना चाहिए;) उस दृष्टिकोण को आजमाएगा ... – ami

1

AJAX। अतुल्यकालिक। बस HTTP अनुरोध तुल्यकालिक बनाओ। समस्या सुलझ गयी।

+0

ठीक है, आप सही हैं, लेकिन ... एक तरफ, कोड का यह हिस्सा हमारे वेब एफडब्ल्यू द्वारा उत्पन्न होता है और मेरे पास उस पर प्रत्यक्ष नियंत्रण नहीं है। दूसरी तरफ, मुख्य उद्देश्य डबल-सबमिट को रोकने के लिए है (जैसे मौजूदा सर्वर साइड डिटेक्शन के लिए एक अतिरिक्त परत) ताकि सभी तंत्रों पर न केवल तंत्र का उपयोग किया जा सके, न केवल अजाक्स कॉल के लिए। उदाहरण के रूप में अजाक्स का जिक्र किया :( – ami

1

आपके कोड के साथ समस्या जावास्क्रिप्ट में प्रकारों के साथ पकड़ने का नतीजा नहीं है।

आप जब कहते हैं:

var newEvent = 'return false;' + el[i].onclick 

क्या करता मजबूर एल [i] .onclick (एक समारोह है जो) एक स्ट्रिंग के लिए, तो यह स्ट्रिंग के लिए संयोजित करता है 'return false;'। फिर जब आप इसे पुन: असाइन करते हैं:

el[i].onclick = newEvent; 

ऑनक्लिक जो पहले एक फ़ंक्शन था अब एक स्ट्रिंग है।

तो फिर तुम सबस्ट्रिंग लेने के द्वारा स्ट्रिंग से अपने पुराने समारोह को फिर से शुरू करने का प्रयास:

var newEvent = el[i].onclick.substring(13); 

जो ठीक है, newEvent को छोड़कर अभी भी एक स्ट्रिंग है! तो जब आप इसे फिर से क्लिक करने के लिए वापस असाइन करते हैं, तो आप मूल फ़ंक्शन के स्ट्रिंग प्रस्तुति को असाइन कर रहे हैं, न कि फ़ंक्शन स्वयं।

आप स्ट्रिंग का मूल्यांकन करने और फ़ंक्शन को वापस करने के लिए eval का उपयोग कर सकते हैं, लेकिन कृपया ऐसा न करें। ऐसा करने के कई तरीके हैं, जैसा कि अन्य टिप्पणीकारों द्वारा सुझाया गया है।

मैं यह भी पूछूंगा कि आप AJAX का उपयोग क्यों करना चाहते हैं यदि आप एसिंक्रोनस अनुरोधों को अनुमति नहीं देना चाहते हैं।

0

एक div ओवरले का उपयोग करने से उपयोगकर्ता को आपके पृष्ठ में टैब-इन करने से रोका नहीं जाता है। आमतौर पर यह ठीक है, क्योंकि अधिकांश उपयोगकर्ता किसी भी तरह से किसी पृष्ठ के माध्यम से टैब नहीं करते हैं।

यदि आप अपने पृष्ठ पर कोई भी कीबोर्ड शॉर्टकट का उपयोग करते हैं, तो वे अभी भी उपलब्ध होंगे, इसलिए उन लोगों के लिए अलग-अलग हैंडलिंग की आवश्यकता होगी।

अन्यथा, मुझे लगता है कि एक तत्व पर क्लिक करना जो फोकस कर सकता है (उदाहरण के लिए <a> टैग), फिर एंटर दबाकर, फिर भी एक डबल सबमिट कर देगा।