css - كيفية تعطيل تحديد اختيار النص؟




cross-browser highlighting textselection (25)

ملحوظة:

الإجابة الصحيحة صحيحة لأنها تمنعك من تحديد النص. ومع ذلك ، فإنه لا يمنعك من القدرة على نسخ النص ، كما سأعرض مع الصورتين التاليتين (اعتبارًا من 7 نوفمبر 2014).

كما ترى ، لم نتمكن من تحديد الأرقام ، ولكن تمكنا من نسخها.

تم الاختبار على: Ubuntu ، Google Chrome 38.0.2125.111.

بالنسبة للمراسي التي تعمل مثل الأزرار (على سبيل المثال ، الأسئلة والعلامات والمستخدمون وما إلى ذلك في أعلى صفحة ) أو علامات التبويب ، هل توجد طريقة قياسية في CSS لتعطيل تأثير التمييز إذا اختار المستخدم النص عن طريق الخطأ؟

أدرك أنه يمكن إجراء ذلك باستخدام جافا سكريبت ، وأفضى القليل من googling إلى خيار Mozilla-only -moz-user-select .

هل هناك طريقة متوافقة معيارية لتحقيق ذلك باستخدام CSS ، وإذا لم يكن الأمر كذلك ، فما هو منهج "أفضل الممارسات"؟


يمكنك فعل ذلك في Firefox و Safari (Chrome أيضًا؟)

::selection { background: transparent; }
::-moz-selection { background: transparent; }

في اختيار الحلول أعلاه ، يتم إيقاف التحديد ، ولكن المستخدم لا يزال يعتقد أنه يمكنك تحديد النص لأن المؤشر لا يزال يتغير. للاحتفاظ بها ثابتة ، سيتعين عليك تعيين مؤشر CSS:

.noselect {
    cursor: default;
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
}
<p>
  Selectable text.
</p>
<p class="noselect">
  Unselectable text.
</p>

سيؤدي هذا إلى جعل النص الخاص بك مستويًا تمامًا ، كما لو كان في تطبيق سطح المكتب.


لقد تعلمت من موقع CSS-Tricks .

user-select: none;

وهذا أيضا:

::selection{ background-color: transparent;}
::moz-selection{ background-color: transparent;}
::webkit-selection{ background-color: transparent;}

بصرف النظر عن خاصية Mozilla-only ، لا ، لا توجد طريقة لتعطيل تحديد النص باستخدام CSS القياسي فقط (حتى الآن).

إذا لاحظت ، لا يقوم بتعطيل اختيار النص لأزرار التنقل الخاصة بهم ، وأوصي بعدم القيام بذلك في معظم الحالات ، نظرًا لأنه يعدل سلوك التحديد العادي ويجعله يتعارض مع توقعات المستخدم.


تحقق من الحل دون JavaScript:

jsFiddle

li:hover {
    background-color: silver;
}
#id1:before {
    content: "File";
}
#id2:before {
    content: "Edit";
}
#id3:before {
    content: "View";
}
<ul>
    <li><a id="id1" href="www.w1.com"></a>
    <li><a id="id2" href="www.w2.com"></a>
    <li><a id="id3" href="www.w3.com"></a>
</ul>

قائمة منبثقة مع تطبيق http://jsfiddle.net/y4Lac/2/ : http://jsfiddle.net/y4Lac/2/


في معظم المتصفحات ، يمكن تحقيق ذلك باستخدام أشكال الملكية في خاصية user-select CSS ، التي تم اقتراحها في الأصل ثم تم التخلي عنها في CSS3 والمقترح الآن في CSS UI Level 4 :

*.unselectable {
   -moz-user-select: none;
   -khtml-user-select: none;
   -webkit-user-select: none;

   /*
     Introduced in IE 10.
     See http://ie.microsoft.com/testdrive/HTML5/msUserSelect/
   */
   -ms-user-select: none;
   user-select: none;
}

بالنسبة لـ IE <10 و Opera <15 ، ستحتاج إلى استخدام السمة unselectable للعنصر الذي ترغب في إلغاء تحديده. يمكنك تعيين ذلك باستخدام سمة في HTML:

<div id="foo" unselectable="on" class="unselectable">...</div>

للأسف ، لا يتم توريث هذه الخاصية ، مما يعني أنه يجب عليك وضع سمة في علامة البدء لكل عنصر داخل <div> . إذا كانت هذه مشكلة ، فيمكنك بدلاً من ذلك استخدام جافا سكريبت للقيام بذلك بشكل متكرر لأحفاد عنصر ما:

function makeUnselectable(node) {
    if (node.nodeType == 1) {
        node.setAttribute("unselectable", "on");
    }
    var child = node.firstChild;
    while (child) {
        makeUnselectable(child);
        child = child.nextSibling;
    }
}

makeUnselectable(document.getElementById("foo"));

التحديث بتاريخ 30 نيسان (أبريل) 2014 : يحتاج هذا العبور إلى إعادة التشغيل كلما تمت إضافة عنصر جديد إلى الشجرة ، ولكن يبدو من تعليق بواسطةHan أنه من الممكن تجنب ذلك عن طريق إضافة معالج أحداث mousedown الذي يعين unselectable mousedown الهدف من الحدث. انظر http://jsbin.com/yagekiji/1 للحصول على التفاصيل.

هذا لا يزال لا يغطي جميع الاحتمالات. في حين أنه من المستحيل بدء التحديدات في العناصر غير القابلة للإختيار ، في بعض المتصفحات (IE و Firefox ، على سبيل المثال) لا يزال من المستحيل منع التحديدات التي تبدأ قبل وتنتهي بعد العنصر غير القابل للإلغاء دون جعل المستند بأكمله غير قابل للإلغاء.


حل جافا سكريبت ل IE هو

onselectstart="return false;"

حاول استخدام هذا واحد:

::selection {
    background: transparent;
}

وإذا كنت ترغب في تحديد عدم التحديد داخل عنصر معين ، فقط ضع فئة العنصر أو معرف قبل قاعدة التحديد ، مثل:

.ClassNAME::selection {
    background: transparent;
}
#IdNAME::selection {
    background: transparent;
}

يمكنك استخدام CSS أو جافا سكريبت لذلك ، كما يتم دعم طريقة جافا سكريبت في المتصفحات القديمة مثل IE القديمة أيضًا ، ولكن إذا لم تكن هذه هي حالتك ، فاستخدم طريقة CSS بعد ذلك:

HTML / جافا سكريبت:

<html onselectstart='return false;'>
  <body>
    <h1>This is the Heading!</h1>
    <p>And I'm the text, I won't be selected if you select me.</p>
  </body>
</html>

HTML / CSS:

.not-selectable {
  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}
<body class="not-selectable">
  <h1>This is the Heading!</h1>
  <p>And I'm the text, I won't be selected if you select me.</p>
</body>


التحديث في كانون الثاني 2017:

طبقًا لـ يمكنني استخدامها ، user-select خيار user-select حاليًا في جميع المتصفحات باستثناء Internet Explorer 9 والإصدارات السابقة (ولكن للأسف لا يزال بحاجة إلى بادئة بائع).

جميع أشكال CSS الصحيحة هي:

.noselect {
  -webkit-touch-callout: none; /* iOS Safari */
    -webkit-user-select: none; /* Safari */
     -khtml-user-select: none; /* Konqueror HTML */
       -moz-user-select: none; /* Firefox */
        -ms-user-select: none; /* Internet Explorer/Edge */
            user-select: none; /* Non-prefixed version, currently
                                  supported by Chrome and Opera */
}
<p>
  Selectable text.
</p>
<p class="noselect">
  Unselectable text.
</p>

لاحظ أنها ميزة غير قياسية (أي ليست جزءًا من أي مواصفات). ليس من المضمون العمل في كل مكان ، وقد تكون هناك اختلافات في التنفيذ بين المتصفحات وفي المستقبل يمكن للمتصفحات إسقاط الدعم لها.

يمكن العثور على مزيد من المعلومات في وثائق شبكة مطوري برامج Mozilla .


هذا يعمل في بعض المتصفحات:

::selection{ background-color: transparent;}
::moz-selection{ background-color: transparent;}
::webkit-selection{ background-color: transparent;}

ما عليك سوى إضافة العناصر / معرفات أمام العناصر المحددة بفواصل بدون فراغات ، مثل:

h1::selection,h2::selection,h3::selection,p::selection{ background-color: transparent;}
h1::moz-selection,h2::moz-selection,h3::moz-selection,p::moz-selection{ background-color: transparent;}
h1::webkit-selection,h2::webkit-selection,h3::webkit-selection,p::webkit-selection{ background-color: transparent;}

الاجابات الاخرى افضل. ربما ينبغي النظر إلى هذا كملاذ أخير / catchall.


تحديث سريع للاختراق: آذار 2017 - من CSS-Tricks

إذا وضعت القيمة "لا شيء" لكل سمات تحديد مستخدم CSS كما هو موضح أدناه ، فهناك مشكلة يمكن أن يحدث بها هذا.

.div{
  -webkit-user-select: none; /* Chrome all / Safari all */
  -moz-user-select: none;   /* Firefox all */
  -ms-user-select: none;  /* IE 10+ */
   user-select: none;  /* Likely future */ 
}

كما يقول CSS-Tricks أن المشاكل هي

  • ما زال WebKit يسمح بنسخ النص إذا قمت بتحديد عناصر حوله.

لذا يمكنك أيضًا استخدام الجزء أدناه بدلاً منه لفرض تحديد عنصر بالكامل وهو الحل للمشكلة. كل ما عليك فعله هو تغيير القيمة "لا شيء" إلى "الكل" التي ستبدو هكذا

.force-select {  
  -webkit-user-select: all;  /* Chrome 49+ */
  -moz-user-select: all;     /* Firefox 43+ */
  -ms-user-select: all;      /* No support yet */
  user-select: all;          /* Likely future */   
}

أضف هذا إلى div الأول الذي تريد تعطيل التحديد للنص:

onmousedown='return false;' 
onselectstart='return false;'

لأولئك الذين لديهم مشكلة في تحقيق نفس الشيء في متصفح Android مع حدث اللمس ، استخدم:

html,body{
    -webkit-touch-callout: none;
    -webkit-user-select: none;
    -webkit-tap-highlight-color: rgba(0,0,0,0);
    -webkit-tap-highlight-color: transparent;
}

للحصول على النتيجة التي أحتاجها ، وجدت أنني مضطر لاستخدام كلا ::selection user-select و user-select

input.no-select:focus { 
    -webkit-touch-callout: none; 
    -webkit-user-select: none; 
    -khtml-user-select: none; 
    -moz-user-select: none; 
    -ms-user-select: none; 
    user-select: none; 
}

input.no-select::selection { 
    background: transparent; 
}

input.no-select::-moz-selection { 
    background: transparent; 
}

أنا أحب الحل المختلط CSS + jQuery.

لجعل جميع العناصر الموجودة داخل <div class="draggable"></div> غير قابلة للإلغاء ، استخدم CSS هذا:

.draggable {
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -o-user-select: none;
    -ms-user-select: none;
    user-select: none;
}

.draggable input { 
    -webkit-user-select: text; 
    -khtml-user-select: text; 
    -moz-user-select: text; 
    -o-user-select: text; 
    user-select: text; 
 }

ومن ثم ، إذا كنت تستخدم jQuery ، فأضف هذا داخل كتلة $(document).ready() :

if (($.browser.msie && $.browser.version < 10) || $.browser.opera) $('.draggable').find(':not(input)').attr('unselectable', 'on');

أظن أنك لا تزال ترغب في أن تكون أي عناصر مدخلات قابلة للتفاعل ، ومن هنا يكون :not() pseudo-selector. يمكنك استخدام '*' بدلاً من ذلك إذا كنت لا تهتم.

التحذير: قد لا يحتاج IE9 إلى هذه القطعة الإضافية من jQuery ، لذا قد ترغب في إضافة إصدار للتحقق هناك.


افترض أن هناك قسمين مثل هذا

.second {
  cursor: default;
  user-select: none;
  -webkit-user-select: none;
  /* Chrome/Safari/Opera */
  -moz-user-select: none;
  /* Firefox */
  -ms-user-select: none;
  /* IE/Edge */
  -webkit-touch-callout: none;
  /* iOS Safari */
}
<div class="first">
  This is my first div
</div>

<div class="second">
  This is my second div
</div>

تعيين المؤشر على الإعداد الافتراضي بحيث يمنح المستخدم /

يجب استخدام البادئة لدعمها في جميع المتصفحات بدون بادئة ، وقد لا يعمل ذلك في جميع الإجابات.


العمل

CSS:

 -khtml-user-select: none;
 -moz-user-select: none;
 -ms-user-select: none;
  user-select: none;
 -webkit-touch-callout: none;
 -webkit-user-select: none;

يجب أن يعمل هذا ، ولكنه لن يعمل مع المتصفحات القديمة. هناك مشكلة في توافق المستعرض.


على الرغم من أن هذا العنصر الزائف كان في مسودات المستوى 3 من CSS Selectors ، فقد تمت إزالته خلال مرحلة توصية المرشح ، حيث بدا أن سلوكه كان غير محدد بشكل خاص ، خاصة مع العناصر المتداخلة ، ولم يتم تحقيق قابلية التشغيل البيني.

تتم مناقشته في كيفية عمل الخيار "اختيار ::" على العناصر المتداخلة .

على الرغم من أنه يتم تنفيذه في المستعرض ، يمكنك جعل وهم من النص لا يتم تحديده باستخدام نفس اللون ولون الخلفية على التحديد من تصميم علامة التبويب (في حالتك).

تصميم عادي CSS

p { color: white;  background: black; }

على الاختيار

p::-moz-selection { color: white;  background: black; }
p::selection      { color: white;  background: black; }

سيؤدي عدم السماح للمستخدمين بتحديد النص إلى زيادة مشكلات قابلية الاستخدام.


 -webkit-user-select: none;  
  -moz-user-select: none;    
  -ms-user-select: none;      
  user-select: none;

الحل البديل لـ WebKit :

/* Disable tap highlighting */
-webkit-tap-highlight-color: rgba(0,0,0,0);

لقد وجدتها في مثال CardFlip.


-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-o-user-select: none;
user-select: none;

*.unselectable {
   -moz-user-select: -moz-none;
   -khtml-user-select: none;
   -webkit-user-select: none;
   user-select: none;
}
<div id="foo" unselectable="on" class="unselectable">...</div>
function makeUnselectable(node) {
    if (node.nodeType == 1) {
        node.unselectable = true;
    }
    var child = node.firstChild;
    while (child) {
        makeUnselectable(child);
        child = child.nextSibling;
    }
}

makeUnselectable(document.getElementById("foo"));
-webkit-user-select:none;
-moz-user-select:none;
onselectstart="return false;"
::selection { background: transparent; }
::-moz-selection { background: transparent; }

* {
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: -moz-none;
-o-user-select: none;
user-select: none;
}

p {
-webkit-user-select: text;
-khtml-user-select: text;
-moz-user-select: text;
-o-user-select: text;
user-select: text;
}
<div class="draggable"></div>
.draggable {
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: none;
    -o-user-select: none;
    user-select: none;
}

.draggable input { 
    -webkit-user-select: text; 
    -khtml-user-select: text; 
    -moz-user-select: text; 
    -o-user-select: text; 
    user-select: text; 
 }
if ($.browser.msie) $('.draggable').find(':not(input)').attr('unselectable', 'on');

إذا كنت ترغب في تعطيل تحديد النص على كل شيء ما عدا عناصر <p> ، فيمكنك القيام بذلك في CSS (احترس من -moz-none الذي يسمح بتجاوز العناصر الفرعية ، وهو مسموح به في المتصفحات الأخرى التي none تحتوي على none ):

* {
    -webkit-user-select: none;
    -khtml-user-select: none;
    -moz-user-select: -moz-none;
    -o-user-select: none;
    user-select: none;
}

p {
    -webkit-user-select: text;
    -khtml-user-select: text;
    -moz-user-select: text;
    -o-user-select: text;
    user-select: text;
}

يمكنك ببساطة تعطيل خاصية textarea مثل هذا:

textarea{
    resize: none;
}

لتعطيل تغيير الحجم العمودي أو الأفقي ، استخدم

resize: vertical;

أو

resize: horizontal;




css cross-browser highlighting textselection